diff options
author | Robin Watts <Robin.Watts@artifex.com> | 2023-03-09 18:49:41 +0000 |
---|---|---|
committer | Chris Liddell <chris.liddell@artifex.com> | 2023-03-10 08:44:34 +0000 |
commit | 367fd7f3a5422757655d644a4d0d2677fc16e60c (patch) | |
tree | c97422e9c4e9217534d1c6617355b38a17800750 /devices | |
parent | 6ae53227b5e5087610183c8071f160a53a226839 (diff) | |
download | ghostpdl-367fd7f3a5422757655d644a4d0d2677fc16e60c.tar.gz |
Bug 706463: Fix buffer overflow seen in bjc600.
This code is poorly documented, and an unholy mix of "int", "word"
and "ulong" pointers, but I think I've understood the problem
enough to solve it.
The bug uses a single pixel wide device. It's therefore dealing
with lines that are expected to be 3 bytes wide. It allocates
buffers based on this number.
But it actually processes a larger number of pixels per line -
namely the number of pixels that will fit into the expected
amount of storage, rounded up to a 'word'. When words are 64bits
this makes much more difference than when they are 32.
Accordingly, we allow for this extra when allocating our buffers.
This should be a harmless change, as effectively all I've done is
allocated a buffer to be slightly larger than before.
Thanks to Youngseok Choi for the report.
Diffstat (limited to 'devices')
-rw-r--r-- | devices/gdevcdj.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/devices/gdevcdj.c b/devices/gdevcdj.c index cb2160eee..1ef237314 100644 --- a/devices/gdevcdj.c +++ b/devices/gdevcdj.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2022 Artifex Software, Inc. +/* Copyright (C) 2001-2023 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -2029,6 +2029,7 @@ hp_colour_print_page(gx_device_printer * pdev, gp_file * prn_stream, int ptype) /* int line_size = gdev_prn_rasterwidth(pdev, 0); */ int line_size = gdev_prn_raster(pdev); int line_size_words = (line_size + W - 1) / W; + int line_size_padded; int paper_size = gdev_pcl_paper_size((gx_device *)pdev); int num_comps = pdev->color_info.num_components; int bits_per_pixel = pdev->color_info.depth; @@ -2087,8 +2088,17 @@ hp_colour_print_page(gx_device_printer * pdev, gp_file * prn_stream, int ptype) bits_per_pixel = expanded_bpp = 3; /* Only 3 bits of each byte used */ } + /* line_size = width * storage_bpp/8 (e.g. 9180) */ + /* storage_bpp = number of bits to store a single pixel in the output (e.g. 24) */ + /* plane_size = number of pixels we are going to process for each line (basically + * line_size/storage_bpp rounded up a bit to allow for padding the output buffer + * to word size). */ plane_size = calc_buffsize(line_size, storage_bpp); eg.plane_size = plane_size; + /* line_size_padded = how many pixels we'd actually get in the padded storage. */ + line_size_padded = plane_size * storage_bpp; + /* BUT, if we're going to process plane_size pixels rather than line_size/storage_bpp + * pixels, we ought to calculate future things based upon line_size_padded. */ if (bits_per_pixel == 1) { /* Data printed direct from i/p */ databuff_size = 0; /* so no data buffer required, */ @@ -2100,7 +2110,7 @@ hp_colour_print_page(gx_device_printer * pdev, gp_file * prn_stream, int ptype) num_comps * 8; /* 8, 24 or 32 bits */ if (cprn_device->cmyk > 0) { /* Use CMYK dithering algorithm. */ - errbuff_size = 4 * (5 + 1 + 1 + line_size + 1 + 2) * I; + errbuff_size = 4 * (5 + 1 + 1 + line_size_padded + 1 + 2) * I; } else { /* Use original (RGB) dithering. */ errbuff_size = /* 4n extra values for line ends */ calc_buffsize((plane_size * expanded_bpp + num_comps * 4) * I, 1); |