Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 1 | From cfde94be1d4286bc47633c6e6eaf4e659bd78066 Mon Sep 17 00:00:00 2001 |
| 2 | From: Chris Liddell <chris.liddell@artifex.com> |
| 3 | Date: Wed, 7 Jun 2017 14:55:12 +0100 |
| 4 | Subject: [PATCH] Bug 697985: bounds check the array allocations methods |
| 5 | |
| 6 | The clump allocator has four allocation functions that use 'number of elements' |
| 7 | and 'size of elements' parameters (rather than a simple 'number of bytes'). |
| 8 | |
| 9 | Those need specific bounds checking. |
| 10 | --- |
| 11 | base/gsalloc.c | 42 ++++++++++++++++++++++++++++-------------- |
| 12 | 1 file changed, 28 insertions(+), 14 deletions(-) |
| 13 | |
| 14 | --- end of original header |
| 15 | |
| 16 | CVE: CVE-2017-9835 |
| 17 | |
| 18 | Upstream-Status: Backport [git://git.ghostscript.com/ghostpdl.git] |
| 19 | |
| 20 | Signed-off-by: Joe Slater <joe.slater@windriver.com> |
| 21 | |
| 22 | diff --git a/base/gsalloc.c b/base/gsalloc.c |
| 23 | index 741ba00..10c04dd 100644 |
| 24 | --- a/base/gsalloc.c |
| 25 | +++ b/base/gsalloc.c |
| 26 | @@ -1248,19 +1248,32 @@ i_alloc_struct_immovable(gs_memory_t * mem, gs_memory_type_ptr_t pstype, |
| 27 | alloc_trace("|+<.", imem, cname, pstype, size, obj); |
| 28 | return obj; |
| 29 | } |
| 30 | + |
| 31 | +static inline bool |
| 32 | +alloc_array_check_size(ulong num_elements, ulong elt_size, ulong *lsize) |
| 33 | +{ |
| 34 | + int64_t s = (int64_t)num_elements * elt_size; |
| 35 | + if (s > max_uint) { |
| 36 | + return false; |
| 37 | + } |
| 38 | + *lsize = (ulong)s; |
| 39 | + return true; |
| 40 | +} |
| 41 | + |
| 42 | static byte * |
| 43 | i_alloc_byte_array(gs_memory_t * mem, uint num_elements, uint elt_size, |
| 44 | client_name_t cname) |
| 45 | { |
| 46 | gs_ref_memory_t * const imem = (gs_ref_memory_t *)mem; |
| 47 | obj_header_t *obj; |
| 48 | - |
| 49 | + ulong lsize; |
| 50 | #ifdef MEMENTO |
| 51 | if (Memento_failThisEvent()) |
| 52 | return NULL; |
| 53 | #endif |
| 54 | - |
| 55 | - obj = alloc_obj(imem, (ulong) num_elements * elt_size, |
| 56 | + if (alloc_array_check_size(num_elements, elt_size, &lsize) == false) |
| 57 | + return NULL; |
| 58 | + obj = alloc_obj(imem, lsize, |
| 59 | &st_bytes, ALLOC_DIRECT, cname); |
| 60 | |
| 61 | if_debug6m('A', mem, "[a%d:+b.]%s -bytes-*(%lu=%u*%u) = 0x%lx\n", |
| 62 | @@ -1275,13 +1288,14 @@ i_alloc_byte_array_immovable(gs_memory_t * mem, uint num_elements, |
| 63 | { |
| 64 | gs_ref_memory_t * const imem = (gs_ref_memory_t *)mem; |
| 65 | obj_header_t *obj; |
| 66 | - |
| 67 | + ulong lsize; |
| 68 | #ifdef MEMENTO |
| 69 | if (Memento_failThisEvent()) |
| 70 | return NULL; |
| 71 | #endif |
| 72 | - |
| 73 | - obj = alloc_obj(imem, (ulong) num_elements * elt_size, |
| 74 | + if (alloc_array_check_size(num_elements, elt_size, &lsize) == false) |
| 75 | + return NULL; |
| 76 | + obj = alloc_obj(imem, lsize, |
| 77 | &st_bytes, ALLOC_IMMOVABLE | ALLOC_DIRECT, |
| 78 | cname); |
| 79 | |
| 80 | @@ -1297,7 +1311,7 @@ i_alloc_struct_array(gs_memory_t * mem, uint num_elements, |
| 81 | { |
| 82 | gs_ref_memory_t * const imem = (gs_ref_memory_t *)mem; |
| 83 | obj_header_t *obj; |
| 84 | - |
| 85 | + ulong lsize; |
| 86 | #ifdef MEMENTO |
| 87 | if (Memento_failThisEvent()) |
| 88 | return NULL; |
| 89 | @@ -1311,9 +1325,9 @@ i_alloc_struct_array(gs_memory_t * mem, uint num_elements, |
| 90 | return NULL; /* fail */ |
| 91 | } |
| 92 | #endif |
| 93 | - obj = alloc_obj(imem, |
| 94 | - (ulong) num_elements * pstype->ssize, |
| 95 | - pstype, ALLOC_DIRECT, cname); |
| 96 | + if (alloc_array_check_size(num_elements, pstype->ssize, &lsize) == false) |
| 97 | + return NULL; |
| 98 | + obj = alloc_obj(imem, lsize, pstype, ALLOC_DIRECT, cname); |
| 99 | if_debug7m('A', mem, "[a%d:+<.]%s %s*(%lu=%u*%u) = 0x%lx\n", |
| 100 | alloc_trace_space(imem), client_name_string(cname), |
| 101 | struct_type_name_string(pstype), |
| 102 | @@ -1327,16 +1341,16 @@ i_alloc_struct_array_immovable(gs_memory_t * mem, uint num_elements, |
| 103 | { |
| 104 | gs_ref_memory_t * const imem = (gs_ref_memory_t *)mem; |
| 105 | obj_header_t *obj; |
| 106 | - |
| 107 | + ulong lsize; |
| 108 | #ifdef MEMENTO |
| 109 | if (Memento_failThisEvent()) |
| 110 | return NULL; |
| 111 | #endif |
| 112 | |
| 113 | ALLOC_CHECK_SIZE(mem,pstype); |
| 114 | - obj = alloc_obj(imem, |
| 115 | - (ulong) num_elements * pstype->ssize, |
| 116 | - pstype, ALLOC_IMMOVABLE | ALLOC_DIRECT, cname); |
| 117 | + if (alloc_array_check_size(num_elements, pstype->ssize, &lsize) == false) |
| 118 | + return NULL; |
| 119 | + obj = alloc_obj(imem, lsize, pstype, ALLOC_IMMOVABLE | ALLOC_DIRECT, cname); |
| 120 | if_debug7m('A', mem, "[a%d|+<.]%s %s*(%lu=%u*%u) = 0x%lx\n", |
| 121 | alloc_trace_space(imem), client_name_string(cname), |
| 122 | struct_type_name_string(pstype), |
| 123 | -- |
| 124 | 1.7.9.5 |
| 125 | |