From e6c48213c22ed50b2b987b479fcc1ac709394caa Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Mon, 18 Jul 2016 21:44:39 -0700 Subject: [PATCH] Fix bug #72606: heap-buffer-overflow (write) simplestring_addn simplestring.c --- ext/xmlrpc/libxmlrpc/simplestring.c | 61 ++++++++++++++++++++++--------------- ext/xmlrpc/libxmlrpc/simplestring.h | 2 +- 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/ext/xmlrpc/libxmlrpc/simplestring.c b/ext/xmlrpc/libxmlrpc/simplestring.c index a084d0e..6477734 100644 --- a/ext/xmlrpc/libxmlrpc/simplestring.c +++ b/ext/xmlrpc/libxmlrpc/simplestring.c @@ -5,28 +5,28 @@ Epinions.com may be contacted at feedback@epinions-inc.com */ -/* - Copyright 2000 Epinions, Inc. +/* + Copyright 2000 Epinions, Inc. - Subject to the following 3 conditions, Epinions, Inc. permits you, free - of charge, to (a) use, copy, distribute, modify, perform and display this - software and associated documentation files (the "Software"), and (b) - permit others to whom the Software is furnished to do so as well. + Subject to the following 3 conditions, Epinions, Inc. permits you, free + of charge, to (a) use, copy, distribute, modify, perform and display this + software and associated documentation files (the "Software"), and (b) + permit others to whom the Software is furnished to do so as well. - 1) The above copyright notice and this permission notice shall be included - without modification in all copies or substantial portions of the - Software. + 1) The above copyright notice and this permission notice shall be included + without modification in all copies or substantial portions of the + Software. - 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF - ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY - IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE OR NONINFRINGEMENT. + 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF + ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY + IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE OR NONINFRINGEMENT. - 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, - SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT - OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING - NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH - DAMAGES. + 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, + SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT + OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING + NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH + DAMAGES. */ @@ -71,7 +71,7 @@ static const char rcsid[] = "#(@) $Id$"; * * Oh, and it is also binary safe, ie it can handle strings with embedded NULLs, * so long as the real length is passed in. - * + * * And the masses rejoiced. * * BUGS @@ -136,7 +136,7 @@ static void simplestring_init_str(simplestring* string) { * NOTES * This function is very fast as it does not de-allocate any memory. * SEE ALSO - * + * * SOURCE */ void simplestring_clear(simplestring* string) { @@ -190,18 +190,31 @@ void simplestring_free(simplestring* string) { * simplestring_add () * SOURCE */ -void simplestring_addn(simplestring* target, const char* source, int add_len) { +void simplestring_addn(simplestring* target, const char* source, size_t add_len) { + size_t newsize = target->size, incr = 0; if(target && source) { if(!target->str) { simplestring_init_str(target); } + + if((SIZE_MAX - add_len) < target->len || (SIZE_MAX - add_len - 1) < target->len) { + /* check for overflows, if there's a potential overflow do nothing */ + return; + } + if(target->len + add_len + 1 > target->size) { /* newsize is current length + new length */ - int newsize = target->len + add_len + 1; - int incr = target->size * 2; + newsize = target->len + add_len + 1; + incr = target->size * 2; /* align to SIMPLESTRING_INCR increments */ - newsize = newsize - (newsize % incr) + incr; + if (incr) { + newsize = newsize - (newsize % incr) + incr; + } + if(newsize < (target->len + add_len + 1)) { + /* some kind of overflow happened */ + return; + } target->str = (char*)realloc(target->str, newsize); target->size = target->str ? newsize : 0; diff --git a/ext/xmlrpc/libxmlrpc/simplestring.h b/ext/xmlrpc/libxmlrpc/simplestring.h index c5d98cf..7e88cd0 100644 --- a/ext/xmlrpc/libxmlrpc/simplestring.h +++ b/ext/xmlrpc/libxmlrpc/simplestring.h @@ -63,7 +63,7 @@ void simplestring_init(simplestring* string); void simplestring_clear(simplestring* string); void simplestring_free(simplestring* string); void simplestring_add(simplestring* string, const char* add); -void simplestring_addn(simplestring* string, const char* add, int add_len); +void simplestring_addn(simplestring* string, const char* add, size_t add_len); #ifdef __cplusplus } From 33c1a55b40900c61ce7e162648eb71ce9b25837c Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Tue, 19 Jul 2016 00:13:25 -0700 Subject: [PATCH] Apparently some envs miss SIZE_MAX --- ext/xmlrpc/libxmlrpc/simplestring.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ext/xmlrpc/libxmlrpc/simplestring.c b/ext/xmlrpc/libxmlrpc/simplestring.c index 6477734..c88754f 100644 --- a/ext/xmlrpc/libxmlrpc/simplestring.c +++ b/ext/xmlrpc/libxmlrpc/simplestring.c @@ -172,6 +172,9 @@ void simplestring_free(simplestring* string) { } /******/ +#ifndef SIZE_MAX +#define SIZE_MAX ((size_t)-1) +#endif /****f* FUNC/simplestring_addn * NAME * simplestring_addn