Package: gs-esp Version: 8.15.1.dfsg.1-1 Severity: important Tags: patch HP upstream just released a new version of the KRGB patches. Since they fix a buffer overflow in borderless printing, I am setting the severity of the bug report to important instead of wishlist.
It is unknown at this time if the buffer overflow is exploitable or not. The patch also closes a memory leak (fix from gs upstream). The attached patch against gs-esp 8.15.1.dfsg.1-1 updates the KRGB support to version 1.2 -- System Information: Debian Release: testing/unstable APT prefers unstable APT policy: (990, 'unstable') Architecture: i386 (i686) Shell: /bin/sh linked to /bin/bash Kernel: Linux 2.6.15.4-debian5+bluesmoke+lm85 Locale: LANG=pt_BR.ISO-8859-1, LC_CTYPE=pt_BR.ISO-8859-1 (charmap=ISO-8859-1) Versions of packages gs-esp depends on: ii gs-common 0.3.9 Common files for different Ghostsc ii libc6 2.3.6-2 GNU C Library: Shared libraries an ii libcupsimage2 1.1.23-15 Common UNIX Printing System(tm) - ii libcupsys2 1.1.23-15 Common UNIX Printing System(tm) - ii libice6 6.9.0.dfsg.1-4 Inter-Client Exchange library ii libjpeg62 6b-11 The Independent JPEG Group's JPEG ii libpaper1 1.1.14-5 Library for handling paper charact ii libpng12-0 1.2.8rel-5 PNG library - runtime ii libsm6 6.9.0.dfsg.1-4 X Window System Session Management ii libstdc++6 4.0.2-9 The GNU Standard C++ Library v3 ii libtiff4 3.8.0-2 Tag Image File Format (TIFF) libra ii libx11-6 6.9.0.dfsg.1-4 X Window System protocol client li ii libxext6 6.9.0.dfsg.1-4 X Window System miscellaneous exte ii libxt6 6.9.0.dfsg.1-4 X Toolkit Intrinsics ii xlibs 6.9.0.dfsg.1-4 X Window System client libraries m ii zlib1g 1:1.2.3-9 compression library - runtime Versions of packages gs-esp recommends: ii gsfonts 8.14+v8.11+urw-0.2 Fonts for the Ghostscript interpre ii psfontmgr 0.11.8-0.1 PostScript font manager -- part of -- no debconf information -- "One disk to rule them all, One disk to find them. One disk to bring them all and in the darkness grind them. In the Land of Redmond where the shadows lie." -- The Silicon Valley Tarot Henrique Holschuh
diff -ruN gs-esp-8.15.1.dfsg.1/src/gdevijs.c gs-esp-8.15.1.dfsg.1.krgb1.2/src/gdevijs.c --- gs-esp-8.15.1.dfsg.1/src/gdevijs.c 2005-03-04 16:41:53.000000000 -0300 +++ gs-esp-8.15.1.dfsg.1.krgb1.2/src/gdevijs.c 2006-02-25 19:06:17.334373921 -0300 @@ -28,27 +28,35 @@ * You should use -dSAFER which sets .LockSafetyParams to true * before opening this device. * - * 11/26/03 David Suffield + * 11/26/03 David Suffield (gdevijs-krgb-1.0.patch) * (c) 2003-2004 Copyright Hewlett-Packard Development Company, LP * * 1. Removed hpijs 1.0-1.0.2 workarounds, use hpijs 1.0.3 or higher. * 2. Added krgb support. * - * 02/21/05 David Suffield + * 02/21/05 David Suffield (gdevijs-krgb-1.1.patch) * 1. Fixed segfault issue with 1-bit color space. * 2. Fixed z-order issue with colored text on black rectangle. * + * 02/22/06 David Suffield (gdevijs-krgb-1.2.patch) + * 1. Fixed krgb buffer overflow issue with out-of-band data in + * fill_rectangle and copy_mono. This buffer overflow condition + * occurred with fullbleed print jobs that had k-band images. + * 2. Added Dan Coby (artifex) fix for gsijs_read_string_malloc + * gs_free *str memory leak. */ #include "unistd_.h" /* for dup() */ #include <stdlib.h> -#include <fcntl.h> #include "gdevprn.h" #include "gp.h" #include "ijs.h" #include "ijs_client.h" /*#define KRGB_DEBUG*/ +#ifdef KRGB_DEBUG +#include <fcntl.h> +#endif /* This should go into gdevprn.h, or, better yet, gdevprn should acquire an API for changing resolution. */ @@ -183,24 +191,62 @@ if (ijsdev->krgb_mode && ijsdev->k_path && y >= 0 && x >= 0) { int raster = (ijsdev->k_width+7) >> 3; - register unsigned char *dest=ijsdev->k_band+(raster*y)+(x >> 3); - int dest_start_bit = x & 7; - int i,j,w1; + register unsigned char *dest; + int dest_start_bit; + int band_height = ijsdev->k_band_size/raster; + int i,j,x1,y1,w1,h1; if (h <= 0 || w <= 0) return 0; - if ((x+w) > ijsdev->k_width) - w1 = ijsdev->k_width - x; + /* Check for out-of-band graphic. */ + if (x >= ijsdev->k_width || y >= band_height) + return 0; /* out-of-band */ + + /* Check for x clipping. */ + if (x < 0) + { + x1 = 0; + w1 = w + x; + } + else if ((x+w) > ijsdev->k_width) + { + x1 = x; + w1 = ijsdev->k_width - x; + } else + { + x1 = x; w1 = w; + } + + dest_start_bit = x1 & 7; + + /* Check for y clipping. */ + if (y < 0) + { + y1 = 0; + h1 = h + y; + } + else if ((y+h) > band_height) + { + y1 = y; + h1 = band_height - y; + } + else + { + y1 = y; + h1 = h; + } + + dest=ijsdev->k_band+(raster*y1)+(x1 >> 3); /* Note x,y orgin 0,0 is stored first byte 0 left to right. */ if (color==0x0) { /* Color is black, store in k plane band instead of regular band. */ - for (j=0; j<h; j++) + for (j=0; j<h1; j++) { for (i=0; i<w1; i++) dest[(dest_start_bit+i)>>3] |= xmask[(dest_start_bit+i)&7]; @@ -210,8 +256,9 @@ } else { - /* Color is not black, remove any k plane bits for z-order dependencies, store in regular band. */ - for (j=0; j<h; j++) + /* Color is not black, remove any k plane bits for + * z-order dependencies, store in regular band. */ + for (j=0; j<h1; j++) { for (i=0; i<w1; i++) dest[(dest_start_bit+i)>>3] &= ~xmask[(dest_start_bit+i)&7]; @@ -233,22 +280,70 @@ if (ijsdev->krgb_mode && ijsdev->k_path) { /* Store in k plane band instead of regular band. */ - int raster = (ijsdev->k_width+7) >> 3; /* raster width in bytes, byte aligned */ - register unsigned char *dest=ijsdev->k_band+(raster*y)+(x >> 3); - register const unsigned char *scan=data+(dx >> 3); - int dest_start_bit = x & 7; - int scan_start_bit = dx & 7; - int i, h=height; + int raster = (ijsdev->k_width+7) >> 3; /* raster width in bytes, + byte aligned */ + register unsigned char *dest; + register const unsigned char *scan; + int dest_start_bit; + int scan_start_bit; + int band_height = ijsdev->k_band_size/raster; + int i,x1,y1,w1,h1,h=height; if (h <= 0 || w <= 0) return 0; + /* Check for out-of-band graphic. */ + if (x >= ijsdev->k_width || y >= band_height) + return 0; /* out-of-band */ + + /* Check for x clipping. */ + if (x < 0) + { + x1 = 0; + w1 = w + x; + /* adj dx here?? */ + } + else if ((x+w) > ijsdev->k_width) + { + x1 = x; + w1 = ijsdev->k_width - x; + } + else + { + x1 = x; + w1 = w; + } + + scan=data+(dx >> 3); + dest_start_bit = x1 & 7; + scan_start_bit = dx & 7; + + /* Check for y clipping. */ + if (y < 0) + { + y1 = 0; + h1 = h + y; + scan+=draster*(h-h1); + } + else if ((y+h) > band_height) + { + y1 = y; + h1 = band_height - y; + } + else + { + y1 = y; + h1 = h; + } + + dest=ijsdev->k_band+(raster*y1)+(x1 >> 3); + if (one==0x0) { /* Color is black, store in k plane band instead of regular band. */ - while (h-- > 0) + while (h1-- > 0) { - for (i=0; i<w; i++) + for (i=0; i<w1; i++) { if (scan[(scan_start_bit+i)>>3] & xmask[(scan_start_bit+i)&7]) dest[(dest_start_bit+i)>>3] |= xmask[(dest_start_bit+i)&7]; @@ -260,10 +355,11 @@ } else { - /* Color is not black, remove any k plane bits for z-order dependencies, store in regular band. */ - while (h-- > 0) + /* Color is not black, remove any k plane bits + * for z-order dependencies, store in regular band. */ + while (h1-- > 0) { - for (i=0; i<w; i++) + for (i=0; i<w1; i++) { if (scan[(scan_start_bit+i)>>3] & xmask[(scan_start_bit+i)&7]) dest[(dest_start_bit+i)>>3] &= ~xmask[(dest_start_bit+i)&7]; @@ -274,7 +370,8 @@ } } - return (*ijsdev->prn_procs.copy_mono)(dev, data, dx, draster, id, x, y, w, height, zero, one); + return (*ijsdev->prn_procs.copy_mono)(dev, data, dx, draster, id, + x, y, w, height, zero, one); } /* ---------------- High-level graphic procedures ---------------- */ @@ -290,7 +387,8 @@ ijsdev->k_path = 1; - code = (*ijsdev->prn_procs.fill_mask)(dev, data, dx, raster, id, x, y, w, h, pdcolor, depth, lop, pcpath); + code = (*ijsdev->prn_procs.fill_mask)(dev, data, dx, raster, id, + x, y, w, h, pdcolor, depth, lop, pcpath); ijsdev->k_path = 0; @@ -307,7 +405,8 @@ ijsdev->k_path = 1; - code = (*ijsdev->prn_procs.fill_path)(dev, pis, ppath, params, pdcolor, pcpath); + code = (*ijsdev->prn_procs.fill_path)(dev, pis, ppath, params, + pdcolor, pcpath); ijsdev->k_path = 0; @@ -324,7 +423,8 @@ ijsdev->k_path = 1; - code = (*ijsdev->prn_procs.stroke_path)(dev, pis, ppath, params, pdcolor, pcpath); + code = (*ijsdev->prn_procs.stroke_path)(dev, pis, ppath, params, + pdcolor, pcpath); ijsdev->k_path = 0; @@ -339,16 +439,19 @@ gx_device_clist_common *cdev = (gx_device_clist_common *)pdev; int band_height = cdev->page_info.band_params.BandHeight; int band_number = y/band_height; - int raster = (ijsdev->k_width+7) >> 3; /* raster width in bytes, byte aligned */ + int raster = (ijsdev->k_width+7) >> 3; /* raster width in bytes, + byte aligned */ int y1=raster*(y-(band_height*band_number)); if (y1 == 0) { - /* First raster for band, clear k_band. Banding playback occurs on first raster. */ + /* First raster for band, clear k_band. + * Banding playback occurs on first raster. */ memset(ijsdev->k_band, 0, ijsdev->k_band_size); } - return gdev_prn_get_bits(pdev, y, str, actual_data); /* get raster from regular band */ + return gdev_prn_get_bits(pdev, y, str, actual_data); /* get raster from + regular band */ } private int gsijs_k_get_bits(gx_device_printer * pdev, int y, byte ** actual_data) @@ -357,7 +460,8 @@ gx_device_clist_common *cdev = (gx_device_clist_common *)pdev; int band_height = cdev->page_info.band_params.BandHeight; int band_number = y/band_height; - int raster = (ijsdev->k_width+7) >> 3; /* raster width in bytes, byte aligned */ + int raster = (ijsdev->k_width+7) >> 3; /* raster width in bytes, + byte aligned */ int y1=raster*(y-(band_height*band_number)); *actual_data = ijsdev->k_band+y1; @@ -366,15 +470,18 @@ } private int gsijs_create_buf_device(gx_device **pbdev, gx_device *target, - const gx_render_plane_t *render_plane, gs_memory_t *mem, bool for_band) + const gx_render_plane_t *render_plane, gs_memory_t *mem, + bool for_band) { gx_device_ijs *ijsdev = (gx_device_ijs *)target; int n_chan = ijsdev->color_info.num_components; - int code = gx_default_create_buf_device(pbdev, target, render_plane, mem, for_band); + int code = gx_default_create_buf_device(pbdev, target, render_plane, + mem, for_band); if (code < 0 || n_chan != 3) return code; - /* Save buffer (vector) procedures so that we can hook them during banding playback. */ + /* Save buffer (vector) procedures so that + * we can hook them during banding playback. */ ijsdev->prn_procs = (*pbdev)->procs; /* Replace buffer procedures with krgb procedures. */ @@ -399,7 +506,8 @@ return 0; /* no krgb support, not RGB colorspace */ buf[0] = 0; - code = ijs_client_enum_param(ijsdev->ctx, 0, "ColorSpace", buf, sizeof(buf)-1); + code = ijs_client_enum_param(ijsdev->ctx, 0, "ColorSpace", + buf, sizeof(buf)-1); if (code >= 0) buf[code] = 0; if (strstr(buf, "KRGB") == NULL) @@ -681,7 +789,8 @@ ijsdev->space_params.MaxBitmap = 0; /* force banding */ - /* Set create_buf_device in printer device, so that we can hook the banding playback procedures. */ + /* Set create_buf_device in printer device, so that + * we can hook the banding playback procedures. */ ijsdev->printer_procs.buf_procs.create_buf_device = gsijs_create_buf_device; /* Decide whether to use OutputFile or OutputFD. Note: how to @@ -760,7 +869,7 @@ code = gsijs_set_margin_params(ijsdev); if (code >= 0) - ijsdev->krgb_mode = gsijs_set_krgb_mode(ijsdev); + ijsdev->krgb_mode = gsijs_set_krgb_mode(ijsdev); return code; } @@ -849,7 +958,7 @@ /* Determine bitmap width and height */ ijs_height = gdev_prn_print_scan_lines(dev); - ijs_width = gsijs_raster_width(dev); + ijs_width = gsijs_raster_width(dev); row_bytes = (ijs_width * pdev->color_info.depth + 7) >> 3; @@ -862,7 +971,8 @@ /* Create banding buffer for k plane. */ ijsdev->k_width = ijs_width; ijsdev->k_band_size = band_height * k_row_bytes; - if ((ijsdev->k_band = gs_malloc(ijsdev->k_band_size, 1, "gsijs_output_page")) == (unsigned char *)NULL) + if ((ijsdev->k_band = gs_malloc(ijsdev->k_band_size, 1, + "gsijs_output_page")) == (unsigned char *)NULL) return gs_note_error(gs_error_VMerror); } @@ -890,9 +1000,11 @@ char sz[128]; kfd = open("/tmp/k.pbm", O_CREAT | O_TRUNC | O_RDWR, 0644); rgbfd = open("/tmp/rgb.ppm", O_CREAT | O_TRUNC | O_RDWR, 0644); - snprintf(sz, sizeof(sz), "P4\n#gdevijs test\n%d\n%d\n", ijs_width, ijs_height); + snprintf(sz, sizeof(sz), "P4\n#gdevijs test\n%d\n%d\n", + ijs_width, ijs_height); write(kfd, sz, strlen(sz)); - snprintf(sz, sizeof(sz), "P6\n#gdevijs test\n%d\n%d\n255\n", ijs_width, ijs_height); + snprintf(sz, sizeof(sz), "P6\n#gdevijs test\n%d\n%d\n255\n", + ijs_width, ijs_height); write(rgbfd, sz, strlen(sz)); #endif @@ -911,7 +1023,8 @@ #ifdef KRGB_DEBUG write(rgbfd, actual_data, row_bytes); #endif - status = ijs_client_send_data_wait(ijsdev->ctx, 0, (char *)actual_data, row_bytes); + status = ijs_client_send_data_wait(ijsdev->ctx, 0, + (char *)actual_data, row_bytes); if (status) break; @@ -922,7 +1035,8 @@ #ifdef KRGB_DEBUG write(kfd, actual_data, k_row_bytes); #endif - status = ijs_client_send_data_wait(ijsdev->ctx, 0, (char *)actual_data, k_row_bytes); + status = ijs_client_send_data_wait(ijsdev->ctx, 0, + (char *)actual_data, k_row_bytes); if (status) break; } @@ -1131,7 +1245,7 @@ } if (new_value.size >= *size) { if (*str) - gs_free(str, *size, 1, "gsijs_read_string_malloc"); + gs_free(*str, *size, 1, "gsijs_read_string_malloc"); *str = NULL; *size = 0; }