Skip to content

Commit 8af5d57

Browse files
committed
- Issues python#2588, python#2589: Fix potential integer underflow and overflow
conditions in the PyOS_vsnprintf C API function. CVE-2008-3144.
1 parent 01feb5a commit 8af5d57

2 files changed

Lines changed: 20 additions & 5 deletions

File tree

‎Misc/NEWS‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ Core and builtins
2727
- Issue #2586: Fix CVE-2008-1721, zlib crash from
2828
zlib.decompressobj().flush(val) when val is not positive.
2929

30+
- Issues #2588, #2589: Fix potential integer underflow and overflow
31+
conditions in the PyOS_vsnprintf C API function. CVE-2008-3144.
32+
3033
Extension Modules
3134
-----------------
3235

‎Python/mysnprintf.c‎

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,28 @@ int
5454
PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va)
5555
{
5656
int len; /* # bytes written, excluding \0 */
57-
#ifndef HAVE_SNPRINTF
57+
#ifdef HAVE_SNPRINTF
58+
#define _PyOS_vsnprintf_EXTRA_SPACE 1
59+
#else
60+
#define _PyOS_vsnprintf_EXTRA_SPACE 512
5861
char *buffer;
5962
#endif
6063
assert(str != NULL);
6164
assert(size > 0);
6265
assert(format != NULL);
66+
/* We take a size_t as input but return an int. Sanity check
67+
* our input so that it won't cause an overflow in the
68+
* vsnprintf return value or the buffer malloc size. */
69+
if (size > INT_MAX - _PyOS_vsnprintf_EXTRA_SPACE) {
70+
len = -666;
71+
goto Done;
72+
}
6373

6474
#ifdef HAVE_SNPRINTF
6575
len = vsnprintf(str, size, format, va);
6676
#else
6777
/* Emulate it. */
68-
buffer = PyMem_MALLOC(size + 512);
78+
buffer = PyMem_MALLOC(size + _PyOS_vsnprintf_EXTRA_SPACE);
6979
if (buffer == NULL) {
7080
len = -666;
7181
goto Done;
@@ -75,7 +85,7 @@ PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va)
7585
if (len < 0)
7686
/* ignore the error */;
7787

78-
else if ((size_t)len >= size + 512)
88+
else if ((size_t)len >= size + _PyOS_vsnprintf_EXTRA_SPACE)
7989
Py_FatalError("Buffer overflow in PyOS_snprintf/PyOS_vsnprintf");
8090

8191
else {
@@ -86,8 +96,10 @@ PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va)
8696
str[to_copy] = '\0';
8797
}
8898
PyMem_FREE(buffer);
89-
Done:
9099
#endif
91-
str[size-1] = '\0';
100+
Done:
101+
if (size > 0)
102+
str[size-1] = '\0';
92103
return len;
104+
#undef _PyOS_vsnprintf_EXTRA_SPACE
93105
}

0 commit comments

Comments
 (0)