From eaf1784964f6d2b42b7d4cf1cd6a615b8b2bd169 Mon Sep 17 00:00:00 2001 From: Graham Dumpleton Date: Thu, 8 Aug 2024 20:33:01 +1000 Subject: [PATCH] Fix process crashing when receive non UTF-8 data. --- docs/release-notes.rst | 1 + docs/release-notes/version-5.0.1.rst | 14 +++++++ src/server/mod_wsgi.c | 56 ++++++++++++++++++++++++++-- 3 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 docs/release-notes/version-5.0.1.rst diff --git a/docs/release-notes.rst b/docs/release-notes.rst index cca9d19a..985fbc86 100644 --- a/docs/release-notes.rst +++ b/docs/release-notes.rst @@ -5,6 +5,7 @@ Release Notes .. toctree:: :maxdepth: 2 + release-notes/version-5.0.1 release-notes/version-5.0.0 release-notes/version-4.9.4 diff --git a/docs/release-notes/version-5.0.1.rst b/docs/release-notes/version-5.0.1.rst new file mode 100644 index 00000000..36fceeca --- /dev/null +++ b/docs/release-notes/version-5.0.1.rst @@ -0,0 +1,14 @@ +============= +Version 5.0.1 +============= + +Version 5.0.1 of mod_wsgi can be obtained from: + + https://codeload.github.com/GrahamDumpleton/mod_wsgi/tar.gz/5.0.1 + +Bugs Fixed +---------- + +* Fix issue which could result in process crashing when values were supplied + for user/password/realm of HTTP basic authentication which weren't compliant + with UTF-8 encoding format. diff --git a/src/server/mod_wsgi.c b/src/server/mod_wsgi.c index 671dc4ff..1c4d7b24 100644 --- a/src/server/mod_wsgi.c +++ b/src/server/mod_wsgi.c @@ -14885,14 +14885,27 @@ static authn_status wsgi_check_password(request_rec *r, const char *user, adapter = newAuthObject(r, config); if (adapter) { + PyObject *user_string = NULL; + PyObject *password_string = NULL; + +#if PY_MAJOR_VERSION >= 3 + user_string = PyUnicode_DecodeLatin1(user, strlen(user), NULL); + password_string = PyUnicode_DecodeLatin1(password, strlen(password), NULL); +#else + user_string = PyString_FromString(user); + password_string = PyString_FromString(password); +#endif + vars = Auth_environ(adapter, group); Py_INCREF(object); - args = Py_BuildValue("(Oss)", vars, user, password); + args = Py_BuildValue("(OOO)", vars, user_string, password_string); result = PyObject_CallObject(object, args); Py_DECREF(args); Py_DECREF(object); Py_DECREF(vars); + Py_DECREF(user_string); + Py_DECREF(password_string); if (result) { if (result == Py_None) { @@ -15128,14 +15141,27 @@ static authn_status wsgi_get_realm_hash(request_rec *r, const char *user, adapter = newAuthObject(r, config); if (adapter) { + PyObject *user_string = NULL; + PyObject *realm_string = NULL; + +#if PY_MAJOR_VERSION >= 3 + user_string = PyUnicode_DecodeLatin1(user, strlen(user), NULL); + realm_string = PyUnicode_DecodeLatin1(realm, strlen(realm), NULL); +#else + user_string = PyString_FromString(user); + realm_string = PyString_FromString(realm); +#endif + vars = Auth_environ(adapter, group); Py_INCREF(object); - args = Py_BuildValue("(Oss)", vars, user, realm); + args = Py_BuildValue("(OOO)", vars, user_string, realm_string); result = PyObject_CallObject(object, args); Py_DECREF(args); Py_DECREF(object); Py_DECREF(vars); + Py_DECREF(user_string); + Py_DECREF(realm_string); if (result) { if (result == Py_None) { @@ -15379,14 +15405,23 @@ static int wsgi_groups_for_user(request_rec *r, WSGIRequestConfig *config, adapter = newAuthObject(r, config); if (adapter) { + PyObject *user_string = NULL; + +#if PY_MAJOR_VERSION >= 3 + user_string = PyUnicode_DecodeLatin1(r->user, strlen(r->user), NULL); +#else + user_string = PyString_FromString(r->user); +#endif + vars = Auth_environ(adapter, group); Py_INCREF(object); - args = Py_BuildValue("(Os)", vars, r->user); + args = Py_BuildValue("(OO)", vars, user_string); result = PyObject_CallObject(object, args); Py_DECREF(args); Py_DECREF(object); Py_DECREF(vars); + Py_DECREF(user_string); if (result) { PyObject *iterator; @@ -15930,14 +15965,27 @@ static int wsgi_hook_check_user_id(request_rec *r) adapter = newAuthObject(r, config); if (adapter) { + PyObject *user_string = NULL; + PyObject *password_string = NULL; + +#if PY_MAJOR_VERSION >= 3 + user_string = PyUnicode_DecodeLatin1(r->user, strlen(r->user), NULL); + password_string = PyUnicode_DecodeLatin1(password, strlen(password), NULL); +#else + user_string = PyString_FromString(r->user); + password_string = PyString_FromString(password); +#endif + vars = Auth_environ(adapter, group); Py_INCREF(object); - args = Py_BuildValue("(Oss)", vars, r->user, password); + args = Py_BuildValue("(OOO)", vars, user_string, password_string); result = PyObject_CallObject(object, args); Py_DECREF(args); Py_DECREF(object); Py_DECREF(vars); + Py_DECREF(user_string); + Py_DECREF(password_string); if (result) { if (result == Py_None) {