From 0718b375425aad8e54e1150313b862e4c6fd324a Mon Sep 17 00:00:00 2001 From: Kevin Atkinson Date: Sat, 21 Dec 2019 20:32:47 +0000 Subject: [PATCH] objstack: assert that the alloc size will fit within a chunk to prevent a buffer overflow Bug found using OSS-Fuze. Upstream-Status: Backport [https://github.com/gnuaspell/aspell/commit/0718b375425aad8e54e1150313b862e4c6fd324a] CVE: CVE-2019-25051 Signed-off-by: Chee Yang Lee --- common/objstack.hpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/common/objstack.hpp b/common/objstack.hpp index 3997bf7..bd97ccd 100644 --- a/common/objstack.hpp +++ b/common/objstack.hpp @@ -5,6 +5,7 @@ #include "parm_string.hpp" #include #include +#include namespace acommon { @@ -26,6 +27,12 @@ class ObjStack byte * temp_end; void setup_chunk(); void new_chunk(); + bool will_overflow(size_t sz) const { + return offsetof(Node,data) + sz > chunk_size; + } + void check_size(size_t sz) { + assert(!will_overflow(sz)); + } ObjStack(const ObjStack &); void operator=(const ObjStack &); @@ -56,7 +63,7 @@ class ObjStack void * alloc_bottom(size_t size) { byte * tmp = bottom; bottom += size; - if (bottom > top) {new_chunk(); tmp = bottom; bottom += size;} + if (bottom > top) {check_size(size); new_chunk(); tmp = bottom; bottom += size;} return tmp; } // This alloc_bottom will insure that the object is aligned based on the @@ -66,7 +73,7 @@ class ObjStack align_bottom(align); byte * tmp = bottom; bottom += size; - if (bottom > top) {new_chunk(); goto loop;} + if (bottom > top) {check_size(size); new_chunk(); goto loop;} return tmp; } char * dup_bottom(ParmString str) { @@ -79,7 +86,7 @@ class ObjStack // always be aligned as such. void * alloc_top(size_t size) { top -= size; - if (top < bottom) {new_chunk(); top -= size;} + if (top < bottom) {check_size(size); new_chunk(); top -= size;} return top; } // This alloc_top will insure that the object is aligned based on @@ -88,7 +95,7 @@ class ObjStack {loop: top -= size; align_top(align); - if (top < bottom) {new_chunk(); goto loop;} + if (top < bottom) {check_size(size); new_chunk(); goto loop;} return top; } char * dup_top(ParmString str) { @@ -117,6 +124,7 @@ class ObjStack void * alloc_temp(size_t size) { temp_end = bottom + size; if (temp_end > top) { + check_size(size); new_chunk(); temp_end = bottom + size; } @@ -131,6 +139,7 @@ class ObjStack } else { size_t s = temp_end - bottom; byte * p = bottom; + check_size(size); new_chunk(); memcpy(bottom, p, s); temp_end = bottom + size; @@ -150,6 +159,7 @@ class ObjStack } else { size_t s = temp_end - bottom; byte * p = bottom; + check_size(size); new_chunk(); memcpy(bottom, p, s); temp_end = bottom + size;