From d4c0a9c59b399bfa0d36030663f78aa18a68e051 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lemburg?= Date: Wed, 28 Nov 2001 11:47:00 +0000 Subject: [PATCH] Fixes for possible buffer overflows in sprintf() usages. --- Modules/_testcapimodule.c | 2 +- Modules/posixmodule.c | 2 +- Modules/readline.c | 4 ++-- Objects/weakrefobject.c | 2 +- Python/compile.c | 2 +- Python/dynload_os2.c | 2 +- Python/dynload_win.c | 2 +- Python/getargs.c | 23 +++++++++-------------- 8 files changed, 17 insertions(+), 22 deletions(-) diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index b17a277b9cf..01e103bd6d7 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -36,7 +36,7 @@ sizeof_error(const char* fatname, const char* typename, int expected, int got) { char buf[1024]; - sprintf(buf, "%s #define == %d but sizeof(%s) == %d", + sprintf(buf, "%.200s #define == %d but sizeof(%.200s) == %d", fatname, expected, typename, got); PyErr_SetString(TestError, buf); return (PyObject*)NULL; diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 667bb20f58f..27e7f1a9a34 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -5787,7 +5787,7 @@ static int insertvalues(PyObject *d) APIRET rc; ULONG values[QSV_MAX+1]; PyObject *v; - char *ver, tmp[10]; + char *ver, tmp[50]; Py_BEGIN_ALLOW_THREADS rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values)); diff --git a/Modules/readline.c b/Modules/readline.c index aa29a61d0db..d2139927344 100644 --- a/Modules/readline.c +++ b/Modules/readline.c @@ -165,7 +165,7 @@ set_hook(const char * funcname, PyObject **hook_var, PyThreadState **tstate, PyO { PyObject *function = Py_None; char buf[80]; - sprintf(buf, "|O:set_%s", funcname); + sprintf(buf, "|O:set_%.50s", funcname); if (!PyArg_ParseTuple(args, buf, &function)) return NULL; if (function == Py_None) { @@ -181,7 +181,7 @@ set_hook(const char * funcname, PyObject **hook_var, PyThreadState **tstate, PyO *tstate = PyThreadState_Get(); } else { - sprintf(buf, "set_%s(func): argument not callable", funcname); + sprintf(buf, "set_%.50s(func): argument not callable", funcname); PyErr_SetString(PyExc_TypeError, buf); return NULL; } diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index e9d0b4b5516..6261a8703f2 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -135,7 +135,7 @@ weakref_repr(PyWeakReference *self) (long)(self)); } else { - sprintf(buffer, "", + sprintf(buffer, "", (long)(self), PyWeakref_GET_OBJECT(self)->ob_type->tp_name, (long)(PyWeakref_GET_OBJECT(self))); } diff --git a/Python/compile.c b/Python/compile.c index b477513dc1f..1104def95ef 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -4195,7 +4195,7 @@ get_ref_type(struct compiling *c, char *name) return GLOBAL_IMPLICIT; } } - sprintf(buf, + PyOS_snprintf(buf, sizeof(buf), "unknown scope for %.100s in %.100s(%s) " "in %s\nsymbols: %s\nlocals: %s\nglobals: %s\n", name, c->c_name, diff --git a/Python/dynload_os2.c b/Python/dynload_os2.c index 24ad74ef757..a3eb46835f6 100644 --- a/Python/dynload_os2.c +++ b/Python/dynload_os2.c @@ -32,7 +32,7 @@ dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname, if (rc != NO_ERROR) { char errBuf[256]; sprintf(errBuf, - "DLL load failed, rc = %d: %s", + "DLL load failed, rc = %d: %.200s", rc, failreason); PyErr_SetString(PyExc_ImportError, errBuf); return NULL; diff --git a/Python/dynload_win.c b/Python/dynload_win.c index a5a65cf0071..155a9d64325 100644 --- a/Python/dynload_win.c +++ b/Python/dynload_win.c @@ -232,7 +232,7 @@ dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname, if (import_python && strcasecmp(buffer,import_python)) { sprintf(buffer, - "Module use of %s conflicts " + "Module use of %.150s conflicts " "with this version of Python.", import_python); PyErr_SetString(PyExc_ImportError,buffer); diff --git a/Python/getargs.c b/Python/getargs.c index 248def36cab..c80ca58fddb 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -1,11 +1,6 @@ /* New getargs implementation */ -/* XXX There are several unchecked sprintf or strcat calls in this file. - XXX The only way these can become a danger is if some C code in the - XXX Python source (or in an extension) uses ridiculously long names - XXX or ridiculously deep nesting in format strings. */ - #include "Python.h" #include @@ -140,7 +135,7 @@ vgetargs1(PyObject *args, char *format, va_list *p_va, int compat) if (max == 0) { if (args == NULL) return 1; - sprintf(msgbuf, "%s%s takes no arguments", + sprintf(msgbuf, "%.200s%s takes no arguments", fname==NULL ? "function" : fname, fname==NULL ? "" : "()"); PyErr_SetString(PyExc_TypeError, msgbuf); @@ -149,7 +144,7 @@ vgetargs1(PyObject *args, char *format, va_list *p_va, int compat) else if (min == 1 && max == 1) { if (args == NULL) { sprintf(msgbuf, - "%s%s takes at least one argument", + "%.200s%s takes at least one argument", fname==NULL ? "function" : fname, fname==NULL ? "" : "()"); PyErr_SetString(PyExc_TypeError, msgbuf); @@ -179,7 +174,7 @@ vgetargs1(PyObject *args, char *format, va_list *p_va, int compat) if (len < min || max < len) { if (message == NULL) { sprintf(msgbuf, - "%s%s takes %s %d argument%s (%d given)", + "%.150s%s takes %s %d argument%s (%d given)", fname==NULL ? "function" : fname, fname==NULL ? "" : "()", min==max ? "exactly" @@ -220,7 +215,7 @@ vgetargs1(PyObject *args, char *format, va_list *p_va, int compat) static void seterror(int iarg, char *msg, int *levels, char *fname, char *message) { - char buf[256]; + char buf[512]; int i; char *p = buf; @@ -228,14 +223,14 @@ seterror(int iarg, char *msg, int *levels, char *fname, char *message) return; else if (message == NULL) { if (fname != NULL) { - sprintf(p, "%s() ", fname); + sprintf(p, "%.200s() ", fname); p += strlen(p); } if (iarg != 0) { sprintf(p, "argument %d", iarg); i = 0; p += strlen(p); - while (levels[i] > 0) { + while (levels[i] > 0 && (int)(p-buf) < 220) { sprintf(p, ", item %d", levels[i]-1); p += strlen(p); i++; @@ -245,7 +240,7 @@ seterror(int iarg, char *msg, int *levels, char *fname, char *message) sprintf(p, "argument"); p += strlen(p); } - sprintf(p, " %s", msg); + sprintf(p, " %.256s", msg); message = buf; } PyErr_SetString(PyExc_TypeError, message); @@ -300,8 +295,8 @@ converttuple(PyObject *arg, char **p_format, va_list *p_va, int *levels, if (!PySequence_Check(arg) || PyString_Check(arg)) { levels[0] = 0; sprintf(msgbuf, - toplevel ? "expected %d arguments, not %s" : - "must be %d-item sequence, not %s", + toplevel ? "expected %d arguments, not %.50s" : + "must be %d-item sequence, not %.50s", n, arg == Py_None ? "None" : arg->ob_type->tp_name); return msgbuf; }