1*4882a593SmuzhiyunFrom 0718b375425aad8e54e1150313b862e4c6fd324a Mon Sep 17 00:00:00 2001 2*4882a593SmuzhiyunFrom: Kevin Atkinson <kevina@gnu.org> 3*4882a593SmuzhiyunDate: Sat, 21 Dec 2019 20:32:47 +0000 4*4882a593SmuzhiyunSubject: [PATCH] objstack: assert that the alloc size will fit within a chunk 5*4882a593Smuzhiyun to prevent a buffer overflow 6*4882a593Smuzhiyun 7*4882a593SmuzhiyunBug found using OSS-Fuze. 8*4882a593Smuzhiyun 9*4882a593SmuzhiyunUpstream-Status: Backport 10*4882a593Smuzhiyun[https://github.com/gnuaspell/aspell/commit/0718b375425aad8e54e1150313b862e4c6fd324a] 11*4882a593SmuzhiyunCVE: CVE-2019-25051 12*4882a593SmuzhiyunSigned-off-by: Chee Yang Lee <chee.yang.lee@intel.com> 13*4882a593Smuzhiyun--- 14*4882a593Smuzhiyun common/objstack.hpp | 18 ++++++++++++++---- 15*4882a593Smuzhiyun 1 file changed, 14 insertions(+), 4 deletions(-) 16*4882a593Smuzhiyun 17*4882a593Smuzhiyundiff --git a/common/objstack.hpp b/common/objstack.hpp 18*4882a593Smuzhiyunindex 3997bf7..bd97ccd 100644 19*4882a593Smuzhiyun--- a/common/objstack.hpp 20*4882a593Smuzhiyun+++ b/common/objstack.hpp 21*4882a593Smuzhiyun@@ -5,6 +5,7 @@ 22*4882a593Smuzhiyun #include "parm_string.hpp" 23*4882a593Smuzhiyun #include <stdlib.h> 24*4882a593Smuzhiyun #include <assert.h> 25*4882a593Smuzhiyun+#include <stddef.h> 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun namespace acommon { 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun@@ -26,6 +27,12 @@ class ObjStack 30*4882a593Smuzhiyun byte * temp_end; 31*4882a593Smuzhiyun void setup_chunk(); 32*4882a593Smuzhiyun void new_chunk(); 33*4882a593Smuzhiyun+ bool will_overflow(size_t sz) const { 34*4882a593Smuzhiyun+ return offsetof(Node,data) + sz > chunk_size; 35*4882a593Smuzhiyun+ } 36*4882a593Smuzhiyun+ void check_size(size_t sz) { 37*4882a593Smuzhiyun+ assert(!will_overflow(sz)); 38*4882a593Smuzhiyun+ } 39*4882a593Smuzhiyun 40*4882a593Smuzhiyun ObjStack(const ObjStack &); 41*4882a593Smuzhiyun void operator=(const ObjStack &); 42*4882a593Smuzhiyun@@ -56,7 +63,7 @@ class ObjStack 43*4882a593Smuzhiyun void * alloc_bottom(size_t size) { 44*4882a593Smuzhiyun byte * tmp = bottom; 45*4882a593Smuzhiyun bottom += size; 46*4882a593Smuzhiyun- if (bottom > top) {new_chunk(); tmp = bottom; bottom += size;} 47*4882a593Smuzhiyun+ if (bottom > top) {check_size(size); new_chunk(); tmp = bottom; bottom += size;} 48*4882a593Smuzhiyun return tmp; 49*4882a593Smuzhiyun } 50*4882a593Smuzhiyun // This alloc_bottom will insure that the object is aligned based on the 51*4882a593Smuzhiyun@@ -66,7 +73,7 @@ class ObjStack 52*4882a593Smuzhiyun align_bottom(align); 53*4882a593Smuzhiyun byte * tmp = bottom; 54*4882a593Smuzhiyun bottom += size; 55*4882a593Smuzhiyun- if (bottom > top) {new_chunk(); goto loop;} 56*4882a593Smuzhiyun+ if (bottom > top) {check_size(size); new_chunk(); goto loop;} 57*4882a593Smuzhiyun return tmp; 58*4882a593Smuzhiyun } 59*4882a593Smuzhiyun char * dup_bottom(ParmString str) { 60*4882a593Smuzhiyun@@ -79,7 +86,7 @@ class ObjStack 61*4882a593Smuzhiyun // always be aligned as such. 62*4882a593Smuzhiyun void * alloc_top(size_t size) { 63*4882a593Smuzhiyun top -= size; 64*4882a593Smuzhiyun- if (top < bottom) {new_chunk(); top -= size;} 65*4882a593Smuzhiyun+ if (top < bottom) {check_size(size); new_chunk(); top -= size;} 66*4882a593Smuzhiyun return top; 67*4882a593Smuzhiyun } 68*4882a593Smuzhiyun // This alloc_top will insure that the object is aligned based on 69*4882a593Smuzhiyun@@ -88,7 +95,7 @@ class ObjStack 70*4882a593Smuzhiyun {loop: 71*4882a593Smuzhiyun top -= size; 72*4882a593Smuzhiyun align_top(align); 73*4882a593Smuzhiyun- if (top < bottom) {new_chunk(); goto loop;} 74*4882a593Smuzhiyun+ if (top < bottom) {check_size(size); new_chunk(); goto loop;} 75*4882a593Smuzhiyun return top; 76*4882a593Smuzhiyun } 77*4882a593Smuzhiyun char * dup_top(ParmString str) { 78*4882a593Smuzhiyun@@ -117,6 +124,7 @@ class ObjStack 79*4882a593Smuzhiyun void * alloc_temp(size_t size) { 80*4882a593Smuzhiyun temp_end = bottom + size; 81*4882a593Smuzhiyun if (temp_end > top) { 82*4882a593Smuzhiyun+ check_size(size); 83*4882a593Smuzhiyun new_chunk(); 84*4882a593Smuzhiyun temp_end = bottom + size; 85*4882a593Smuzhiyun } 86*4882a593Smuzhiyun@@ -131,6 +139,7 @@ class ObjStack 87*4882a593Smuzhiyun } else { 88*4882a593Smuzhiyun size_t s = temp_end - bottom; 89*4882a593Smuzhiyun byte * p = bottom; 90*4882a593Smuzhiyun+ check_size(size); 91*4882a593Smuzhiyun new_chunk(); 92*4882a593Smuzhiyun memcpy(bottom, p, s); 93*4882a593Smuzhiyun temp_end = bottom + size; 94*4882a593Smuzhiyun@@ -150,6 +159,7 @@ class ObjStack 95*4882a593Smuzhiyun } else { 96*4882a593Smuzhiyun size_t s = temp_end - bottom; 97*4882a593Smuzhiyun byte * p = bottom; 98*4882a593Smuzhiyun+ check_size(size); 99*4882a593Smuzhiyun new_chunk(); 100*4882a593Smuzhiyun memcpy(bottom, p, s); 101*4882a593Smuzhiyun temp_end = bottom + size; 102