[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#354394: gs-esp: [IJS/KRGB] please update KRGB support to version 1.2



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;
 	    }

Reply to: