Vulnerabilities > CVE-2016-8728 - Out-of-bounds Write vulnerability in Artifex Mupdf 1.10

047910
CVSS 7.8 - HIGH
Attack vector
LOCAL
Attack complexity
LOW
Privileges required
NONE
Confidentiality impact
HIGH
Integrity impact
HIGH
Availability impact
HIGH
local
low complexity
artifex
CWE-787
nessus

Summary

An exploitable heap out of bounds write vulnerability exists in the Fitz graphical library part of the MuPDF renderer. A specially crafted PDF file can cause a out of bounds write resulting in heap metadata and sensitive process memory corruption leading to potential code execution. Victim needs to open the specially crafted file in a vulnerable reader in order to trigger this vulnerability.

Vulnerable Configurations

Part Description Count
Application
Artifex
1

Common Weakness Enumeration (CWE)

Nessus

  • NASL familySuSE Local Security Checks
    NASL idOPENSUSE-2017-1300.NASL
    descriptionThis update for mupdf fixes the following issues : Security issues fixed : - CVE-2017-7976: integer overflow (jbig2_image_compose function in jbig2_image.c) during operations on a crafted .jb2 file (boo#1052029). - CVE-2016-10221: count_entries in pdf-layer.c allows for DoS (boo#1032140). - CVE-2016-8728: Fitz library font glyph scaling Code Execution Vulnerability (boo#1039850). Bug fixes : - Update to version 1.11 - This is primarily a bug fix release. - PDF portfolio support with command line tool
    last seen2020-06-05
    modified2017-11-27
    plugin id104766
    published2017-11-27
    reporterThis script is Copyright (C) 2017-2020 and is owned by Tenable, Inc. or an Affiliate thereof.
    sourcehttps://www.tenable.com/plugins/nessus/104766
    titleopenSUSE Security Update : mupdf (openSUSE-2017-1300)
    code
    #%NASL_MIN_LEVEL 80502
    #
    # (C) Tenable Network Security, Inc.
    #
    # The descriptive text and package checks in this plugin were
    # extracted from openSUSE Security Update openSUSE-2017-1300.
    #
    # The text description of this plugin is (C) SUSE LLC.
    #
    
    include("compat.inc");
    
    if (description)
    {
      script_id(104766);
      script_version("3.5");
      script_set_attribute(attribute:"plugin_modification_date", value:"2020/06/04");
    
      script_cve_id("CVE-2016-10221", "CVE-2016-8728", "CVE-2016-8729", "CVE-2017-7976");
    
      script_name(english:"openSUSE Security Update : mupdf (openSUSE-2017-1300)");
      script_summary(english:"Check for the openSUSE-2017-1300 patch");
    
      script_set_attribute(
        attribute:"synopsis", 
        value:"The remote openSUSE host is missing a security update."
      );
      script_set_attribute(
        attribute:"description", 
        value:
    "This update for mupdf fixes the following issues :
    
    Security issues fixed :
    
      - CVE-2017-7976: integer overflow (jbig2_image_compose
        function in jbig2_image.c) during operations on a
        crafted .jb2 file (boo#1052029).
    
      - CVE-2016-10221: count_entries in pdf-layer.c allows for
        DoS (boo#1032140).
    
      - CVE-2016-8728: Fitz library font glyph scaling Code
        Execution Vulnerability (boo#1039850).
    
    Bug fixes :
    
      - Update to version 1.11
    
      - This is primarily a bug fix release.
    
      - PDF portfolio support with command line tool 'mutool
        portfolio'.
    
      - Add callbacks to load fallback fonts from the system.
    
      - Use system fonts in Android to reduce install size.
    
      - Flag to disable publisher styles in EPUB layout.
    
      - Improved SVG output.
    
      - Add reproducible.patch to sort input files to make build
        reproducible (boo#1041090)
    
      - mupdf is not a terminal app (boo#1036637)"
      );
      script_set_attribute(
        attribute:"see_also",
        value:"https://bugzilla.opensuse.org/show_bug.cgi?id=1032140"
      );
      script_set_attribute(
        attribute:"see_also",
        value:"https://bugzilla.opensuse.org/show_bug.cgi?id=1036637"
      );
      script_set_attribute(
        attribute:"see_also",
        value:"https://bugzilla.opensuse.org/show_bug.cgi?id=1039850"
      );
      script_set_attribute(
        attribute:"see_also",
        value:"https://bugzilla.opensuse.org/show_bug.cgi?id=1041090"
      );
      script_set_attribute(
        attribute:"see_also",
        value:"https://bugzilla.opensuse.org/show_bug.cgi?id=1052029"
      );
      script_set_attribute(
        attribute:"solution", 
        value:"Update the affected mupdf packages."
      );
      script_set_cvss_base_vector("CVSS2#AV:N/AC:M/Au:N/C:P/I:P/A:P");
      script_set_cvss3_base_vector("CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H");
    
      script_set_attribute(attribute:"plugin_type", value:"local");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:mupdf");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:mupdf-devel-static");
      script_set_attribute(attribute:"cpe", value:"cpe:/o:novell:opensuse:42.2");
      script_set_attribute(attribute:"cpe", value:"cpe:/o:novell:opensuse:42.3");
    
      script_set_attribute(attribute:"patch_publication_date", value:"2017/11/23");
      script_set_attribute(attribute:"plugin_publication_date", value:"2017/11/27");
      script_end_attributes();
    
      script_category(ACT_GATHER_INFO);
      script_copyright(english:"This script is Copyright (C) 2017-2020 and is owned by Tenable, Inc. or an Affiliate thereof.");
      script_family(english:"SuSE Local Security Checks");
    
      script_dependencies("ssh_get_info.nasl");
      script_require_keys("Host/local_checks_enabled", "Host/SuSE/release", "Host/SuSE/rpm-list", "Host/cpu");
    
      exit(0);
    }
    
    
    include("audit.inc");
    include("global_settings.inc");
    include("rpm.inc");
    
    if (!get_kb_item("Host/local_checks_enabled")) audit(AUDIT_LOCAL_CHECKS_NOT_ENABLED);
    release = get_kb_item("Host/SuSE/release");
    if (isnull(release) || release =~ "^(SLED|SLES)") audit(AUDIT_OS_NOT, "openSUSE");
    if (release !~ "^(SUSE42\.2|SUSE42\.3)$") audit(AUDIT_OS_RELEASE_NOT, "openSUSE", "42.2 / 42.3", release);
    if (!get_kb_item("Host/SuSE/rpm-list")) audit(AUDIT_PACKAGE_LIST_MISSING);
    
    ourarch = get_kb_item("Host/cpu");
    if (!ourarch) audit(AUDIT_UNKNOWN_ARCH);
    if (ourarch !~ "^(i586|i686|x86_64)$") audit(AUDIT_ARCH_NOT, "i586 / i686 / x86_64", ourarch);
    
    flag = 0;
    
    if ( rpm_check(release:"SUSE42.2", reference:"mupdf-1.11-13.3.1") ) flag++;
    if ( rpm_check(release:"SUSE42.2", reference:"mupdf-devel-static-1.11-13.3.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"mupdf-1.11-16.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"mupdf-devel-static-1.11-16.1") ) flag++;
    
    if (flag)
    {
      if (report_verbosity > 0) security_warning(port:0, extra:rpm_report_get());
      else security_warning(0);
      exit(0);
    }
    else
    {
      tested = pkg_tests_get();
      if (tested) audit(AUDIT_PACKAGE_NOT_AFFECTED, tested);
      else audit(AUDIT_PACKAGE_NOT_INSTALLED, "mupdf / mupdf-devel-static");
    }
    
  • NASL familyFedora Local Security Checks
    NASL idFEDORA_2017-5135C91B36.NASL
    descriptionFix for CVE-2016-8728 CVE-2016-8729 ---- Rebuild with new jbig2dec Note that Tenable Network Security has extracted the preceding description block directly from the Fedora update system website. Tenable has attempted to automatically clean and format it as much as possible without introducing additional issues.
    last seen2020-06-05
    modified2017-05-30
    plugin id100488
    published2017-05-30
    reporterThis script is Copyright (C) 2017-2020 and is owned by Tenable, Inc. or an Affiliate thereof.
    sourcehttps://www.tenable.com/plugins/nessus/100488
    titleFedora 25 : mupdf (2017-5135c91b36)
    code
    #%NASL_MIN_LEVEL 80502
    #
    # (C) Tenable Network Security, Inc.
    #
    # The descriptive text and package checks in this plugin were  
    # extracted from Fedora Security Advisory FEDORA-2017-5135c91b36.
    #
    
    include("compat.inc");
    
    if (description)
    {
      script_id(100488);
      script_version("3.6");
      script_set_attribute(attribute:"plugin_modification_date", value:"2020/06/04");
    
      script_cve_id("CVE-2016-8728", "CVE-2016-8729", "CVE-2017-7885");
      script_xref(name:"FEDORA", value:"2017-5135c91b36");
    
      script_name(english:"Fedora 25 : mupdf (2017-5135c91b36)");
      script_summary(english:"Checks rpm output for the updated package.");
    
      script_set_attribute(
        attribute:"synopsis", 
        value:"The remote Fedora host is missing a security update."
      );
      script_set_attribute(
        attribute:"description", 
        value:
    "Fix for CVE-2016-8728 CVE-2016-8729
    
    ----
    
    Rebuild with new jbig2dec
    
    Note that Tenable Network Security has extracted the preceding
    description block directly from the Fedora update system website.
    Tenable has attempted to automatically clean and format it as much as
    possible without introducing additional issues."
      );
      script_set_attribute(
        attribute:"see_also",
        value:"https://bodhi.fedoraproject.org/updates/FEDORA-2017-5135c91b36"
      );
      script_set_attribute(attribute:"solution", value:"Update the affected mupdf package.");
      script_set_cvss_base_vector("CVSS2#AV:N/AC:M/Au:N/C:P/I:P/A:P");
      script_set_cvss3_base_vector("CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H");
    
      script_set_attribute(attribute:"plugin_type", value:"local");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:fedoraproject:fedora:mupdf");
      script_set_attribute(attribute:"cpe", value:"cpe:/o:fedoraproject:fedora:25");
    
      script_set_attribute(attribute:"vuln_publication_date", value:"2017/04/17");
      script_set_attribute(attribute:"patch_publication_date", value:"2017/05/27");
      script_set_attribute(attribute:"plugin_publication_date", value:"2017/05/30");
      script_set_attribute(attribute:"generated_plugin", value:"current");
      script_end_attributes();
    
      script_category(ACT_GATHER_INFO);
      script_copyright(english:"This script is Copyright (C) 2017-2020 and is owned by Tenable, Inc. or an Affiliate thereof.");
      script_family(english:"Fedora Local Security Checks");
    
      script_dependencies("ssh_get_info.nasl");
      script_require_keys("Host/local_checks_enabled", "Host/RedHat/release", "Host/RedHat/rpm-list");
    
      exit(0);
    }
    
    
    include("audit.inc");
    include("global_settings.inc");
    include("rpm.inc");
    
    
    if (!get_kb_item("Host/local_checks_enabled")) audit(AUDIT_LOCAL_CHECKS_NOT_ENABLED);
    release = get_kb_item("Host/RedHat/release");
    if (isnull(release) || "Fedora" >!< release) audit(AUDIT_OS_NOT, "Fedora");
    os_ver = pregmatch(pattern: "Fedora.*release ([0-9]+)", string:release);
    if (isnull(os_ver)) audit(AUDIT_UNKNOWN_APP_VER, "Fedora");
    os_ver = os_ver[1];
    if (! preg(pattern:"^25([^0-9]|$)", string:os_ver)) audit(AUDIT_OS_NOT, "Fedora 25", "Fedora " + os_ver);
    
    if (!get_kb_item("Host/RedHat/rpm-list")) audit(AUDIT_PACKAGE_LIST_MISSING);
    
    
    cpu = get_kb_item("Host/cpu");
    if (isnull(cpu)) audit(AUDIT_UNKNOWN_ARCH);
    if ("x86_64" >!< cpu && cpu !~ "^i[3-6]86$") audit(AUDIT_LOCAL_CHECKS_NOT_IMPLEMENTED, "Fedora", cpu);
    
    
    flag = 0;
    if (rpm_check(release:"FC25", reference:"mupdf-1.10a-7.fc25")) flag++;
    
    
    if (flag)
    {
      security_report_v4(
        port       : 0,
        severity   : SECURITY_WARNING,
        extra      : rpm_report_get()
      );
      exit(0);
    }
    else
    {
      tested = pkg_tests_get();
      if (tested) audit(AUDIT_PACKAGE_NOT_AFFECTED, tested);
      else audit(AUDIT_PACKAGE_NOT_INSTALLED, "mupdf");
    }
    

Seebug

bulletinFamilyexploit
description### Summary An exploitable heap out of bounds write vulnerability exists in the Fitz graphical library part of the MuPDF renderer. A specially crafted PDF file can cause a out of bounds write resulting in heap metadata and sensitive process memory corruption leading to potential code execution. Victim needs to open the specially crafted file in a vulnerable reader in order to trigger this vulnerability. ### Tested Versions MuPDF 1.10-rc1 ### Product URLs http://mupdf.com/ ### CVSSv3 Score 8.6 – CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H ### Details MuPDF is a lightweight PDF parsing and rendering library featuring high fidelity graphics, high speed and compact code size which makes it a fairly popular PDF library for embedding in different projects, especially mobile and web applications. Fitz is an underlying graphics library which MuPDF uses to render PDFs and images. There exists an exploitable vulnerability in the glyph scaling code of MuPDF. Specifically, when a font glyph is specified and used in a way where it must be scaled down an invalid pointer arithmetic can result in invalid memory access which can be abused to overwrite sensitive memory. The vulnerability is located in function `scale_single_row` in file `source/fitz/draw-scale-simple.c`: ``` static void scale_single_row(unsigned char * restrict dst, int dstride, const unsigned char * restrict src, const fz_weights * restrict weights, int src_w, int h, int forcealpha) { const int *contrib = &weights->index[weights->index[0]]; int min, len, i, j, n, nf; int tmp[FZ_MAX_COLORS]; n = weights->n; [1] nf = n + forcealpha; [2] ... if (weights->flip) { dst += (weights->count-1)*n; [3] for (i=weights->count; i > 0; i--) { ... for (j = 0; j < nf; j++) [4] { *dst++ = (unsigned char)(tmp[j]>>8); tmp[j] = 128; } dst -= 2*nf; [5] } dst += nf + dstride; } ``` In the above code, at [1] and [2] variables `n` and `nf` are initialized, at [3] the destination pointer `dst` is increased in relation to `count` and `n`. Inside a for loop at [4] `dst` pointer is written to and incremented and finally at [5] it is decremented. The vulnerability can be triggered due to the fact that `dst` in increased `nf` times inside for loop, but decreased by `2*nf` just outside the for loop. If the outer loop (at [3]) loops more than once, `dst` can start pointing behind it’s original value which leads to adjacent memory overwrite. With precise control over values of `n` and `count`, the pointer can be shifted as desired giving control over which memory gets overwritten. In the following debugging session, we can see the concrete values for `n` and `count` from a PoC testcase that results in triggering this vulnerability: ``` Breakpoint 2, scale_single_row (dst=0xa4292a0 "\210\030߷\220\252B\nP", dstride=0xc, src=0xa3ecad8 "AAAABBBBCCCC\031", weights=0xa40c560, src_w=0x4, h=0x2, forcealpha=0x1) at source/fitz/draw-scale-simple.c:1286 1286 const int *contrib = &weights->index[weights->index[0]]; gdb$ p *(struct fz_weights_s *)0xa40c560 $5 = { flip = 0x1, count = 0x3, max_len = 0x4, n = 0x3, new_line = 0x0, patch_l = 0x0, index = {0x3} } gdb$ x/x 0xa4292a0 0xa4292a0: 0xb7df1888 gdb$ x/x 0xa4292a0-4 0xa42929c: 0x00000021 gdb$ watch *0xa42929c Hardware watchpoint 7: *0xa42929c gdb$ c Continuing. Hardware watchpoint 7: *0xa42929c Old value = 0x21 New value = 0xb0021 scale_single_row (dst=0xa42929f "", dstride=0xc, src=0xa3ecad8 "AAAABBBBCCCC\031", weights=0xa40c560, src_w=0x4, h=0x2, forcealpha=0x1) at source/fitz/draw-scale-simple.c:1314 1314 tmp[j] = 128; gdb$ c Hardware watchpoint 7: *0xa42929c Old value = 0xb0021 New value = 0xb0b0021 scale_single_row (dst=0xa4292a0 "\210\030BBC\377\036\036\036v", dstride=0xc, src=0xa3ecad8 "AAAABBBBCCCC\031", weights=0xa40c560, src_w=0x4, h=0x2, forcealpha=0x1) at source/fitz/draw-scale-simple.c:1314 1314 tmp[j] = 128; gdb$ ``` Breakpoint 2 is hit, at the beginning of function `scale_single_row` and we can see that values of `weights` structure are: ``` flip = 0x1, count = 0x3, max_len = 0x4, n = 0x3, new_line = 0x0, patch_l = 0x0, ``` Also important is that `forcealpha` is set to 1. In this case, `nf` will be equal to 4, at first dst will be increased by `(count - 1 )*n`, that is 6, then the loop will loop 4 times, increasing dst by 4 for a total of 10. Outside the loop, `dst` will be decreased by `2*nf` or 8, totaling 2. Next time the inner for loop is hit, `dst` will be increased by 4 times (for 6 total) but will be decreased by 8, therefore accessing the data previous to the original pointer address. This can be observed in the above gdb input by setting a read/write access breakpoint on memory location just before the original pointer. This overwrite results in heap metadata corruption leading to process termination. The data that is being written to an out of bounds location is under indirect control of the attacker. ### Crash Information Valgrind output showing the vulnerability being triggered against a sample PDF viewer application `mupdf-x11`: ``` ==10727== Memcheck, a memory error detector ==10727== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==10727== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info ==10727== Command: ../mupdf/build/debug/mupdf-x11 triage.pdf ==10727== error: cannot recognize xref format warning: trying to repair broken xref ==10727== Invalid write of size 1 ==10727== at 0x808C898: scale_single_row (draw-scale-simple.c:1313) ==10727== by 0x808DA6A: fz_scale_pixmap_cached (draw-scale-simple.c:1736) ==10727== by 0x8063635: fz_transform_pixmap (draw-device.c:1302) ==10727== by 0x8063B3B: fz_draw_fill_image (draw-device.c:1416) ==10727== by 0x805687E: fz_fill_image (device.c:317) ==10727== by 0x8071D4F: fz_run_display_list (list-device.c:1646) ==10727== by 0x805AD23: fz_run_t3_glyph (font.c:1224) ==10727== by 0x805AEE1: fz_render_t3_glyph_pixmap (font.c:1272) ==10727== by 0x805B000: fz_render_t3_glyph (font.c:1307) ==10727== by 0x805C42B: fz_render_glyph (draw-glyph.c:327) ==10727== by 0x8061E02: fz_draw_fill_text (draw-device.c:798) ==10727== by 0x80564D7: fz_fill_text (device.c:198) ==10727== Address 0x4743ad6 is 2 bytes before a block of size 24 alloc'd ==10727== at 0x402B211: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==10727== by 0x8074989: fz_malloc_default (memory.c:213) ==10727== by 0x807445C: do_scavenging_malloc (memory.c:17) ==10727== by 0x80745EB: fz_malloc_array (memory.c:80) ==10727== by 0x8068A1B: fz_new_pixmap_with_data (pixmap.c:76) ==10727== by 0x8068AC3: fz_new_pixmap (pixmap.c:95) ==10727== by 0x808D8FE: fz_scale_pixmap_cached (draw-scale-simple.c:1709) ==10727== by 0x8063635: fz_transform_pixmap (draw-device.c:1302) ==10727== by 0x8063B3B: fz_draw_fill_image (draw-device.c:1416) ==10727== by 0x805687E: fz_fill_image (device.c:317) ==10727== by 0x8071D4F: fz_run_display_list (list-device.c:1646) ==10727== by 0x805AD23: fz_run_t3_glyph (font.c:1224) ==10727== ``` ### Timeline * 2016-11-29 - Vendor Disclosure * 2017-05-15 - Public Release ### CREDIT * Discovered by Aleksandar Nikolic of Cisco Talos
idSSV:96508
last seen2017-11-19
modified2017-09-18
published2017-09-18
reporterRoot
titleMuPDF Fitz library font glyph scaling Code Execution Vulnerability(CVE-2016-8728)

Talos

idTALOS-2016-0242
last seen2019-05-29
published2017-05-15
reporterTalos Intelligence
sourcehttp://www.talosintelligence.com/vulnerability_reports/TALOS-2016-0242
titleMuPDF Fitz library font glyph scaling Code Execution Vulnerability