diff options
author | Gregory P. Smith <greg@mad-scientist.com> | 2008-05-26 21:16:34 (GMT) |
---|---|---|
committer | Gregory P. Smith <greg@mad-scientist.com> | 2008-05-26 21:16:34 (GMT) |
commit | 23921f00e8a2d1a4ac3e3274b9523fddafb42fe1 (patch) | |
tree | d72668520d064270ffd5b081996dbfa24fb73b8f | |
parent | 06abba3558f0be86134a569f9885b0edcfdbbe16 (diff) | |
download | cpython-23921f00e8a2d1a4ac3e3274b9523fddafb42fe1.zip cpython-23921f00e8a2d1a4ac3e3274b9523fddafb42fe1.tar.gz cpython-23921f00e8a2d1a4ac3e3274b9523fddafb42fe1.tar.bz2 |
Fix issue2589: there was a potential integer overflow leading to
memory corruption on esoteric platforms and incorrect behavior on
normal platforms.
-rw-r--r-- | Python/mysnprintf.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/Python/mysnprintf.c b/Python/mysnprintf.c index 4d3770d..8c47794 100644 --- a/Python/mysnprintf.c +++ b/Python/mysnprintf.c @@ -54,18 +54,28 @@ int PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va) { int len; /* # bytes written, excluding \0 */ -#ifndef HAVE_SNPRINTF +#ifdef HAVE_SNPRINTF +#define _PyOS_vsnprintf_EXTRA_SPACE 1 +#else +#define _PyOS_vsnprintf_EXTRA_SPACE 512 char *buffer; #endif assert(str != NULL); assert(size > 0); assert(format != NULL); + /* We take a size_t as input but return an int. Sanity check + * our input so that it won't cause an overflow in the + * vsnprintf return value or the buffer malloc size. */ + if (size > INT_MAX - _PyOS_vsnprintf_EXTRA_SPACE) { + len = -666; + goto Done; + } #ifdef HAVE_SNPRINTF len = vsnprintf(str, size, format, va); #else /* Emulate it. */ - buffer = PyMem_MALLOC(size + 512); + buffer = PyMem_MALLOC(size + _PyOS_vsnprintf_EXTRA_SPACE); if (buffer == NULL) { len = -666; goto Done; @@ -75,7 +85,7 @@ PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va) if (len < 0) /* ignore the error */; - else if ((size_t)len >= size + 512) + else if ((size_t)len >= size + _PyOS_vsnprintf_EXTRA_SPACE) Py_FatalError("Buffer overflow in PyOS_snprintf/PyOS_vsnprintf"); else { @@ -86,8 +96,9 @@ PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va) str[to_copy] = '\0'; } PyMem_FREE(buffer); -Done: #endif +Done: str[size-1] = '\0'; return len; +#undef _PyOS_vsnprintf_EXTRA_SPACE } |