From b1dbd3071d7f778993565fa64f7a65a797e6d9c3 Mon Sep 17 00:00:00 2001 From: Jordan Milne Date: Wed, 28 Jan 2015 17:18:39 -0800 Subject: [PATCH] Handle allocation failures in C code gracefully Thanks to Nathanael A. Hoyle for the report! Some of these may have been exploitable due to pointer arithmetic before reads / writes. Just bail out if we can't allocate. --- r2/r2/lib/c/filters.c | 20 ++++++++++++++++++++ scripts/traffic/decrypt_userinfo.c | 12 ++++++++++++ scripts/traffic/parse.c | 4 ++++ 3 files changed, 36 insertions(+) diff --git a/r2/r2/lib/c/filters.c b/r2/r2/lib/c/filters.c index 5607c783dd..667fba5b56 100644 --- a/r2/r2/lib/c/filters.c +++ b/r2/r2/lib/c/filters.c @@ -54,6 +54,10 @@ filters_uwebsafe(PyObject * self, PyObject *args) len = PyUnicode_GetSize(com); buffer = (Py_UNICODE*)malloc(6*len*sizeof(Py_UNICODE)); + if (buffer == NULL) { + return PyErr_NoMemory(); + } + for(ic = 0, ib = 0; ic < len; ic++, ib++) { c = input_buffer[ic]; if (c == '&') { @@ -108,6 +112,10 @@ filters_uwebsafe_json(PyObject * self, PyObject *args) len = PyUnicode_GetSize(com); buffer = (Py_UNICODE*)malloc(6*len*sizeof(Py_UNICODE)); + if (buffer == NULL) { + return PyErr_NoMemory(); + } + for(ic = 0, ib = 0; ic < len; ic++, ib++) { c = input_buffer[ic]; if (c == '&') { @@ -153,6 +161,10 @@ filters_websafe(PyObject * self, PyObject *args) return NULL; len = strlen(input_buffer); buffer = (char*)malloc(6*len); + if (buffer == NULL) { + return PyErr_NoMemory(); + } + for(ic = 0, ib = 0; ic <= len; ic++, ib++) { c = input_buffer[ic]; if (c == '&') { @@ -231,6 +243,9 @@ filters_uspace_compress(PyObject * self, PyObject *args) { input_buffer = PyUnicode_AS_UNICODE(com); len = PyUnicode_GetSize(com); buffer = (Py_UNICODE*)malloc(len * sizeof(Py_UNICODE)); + if (buffer == NULL) { + return PyErr_NoMemory(); + } /* ic -> input buffer index, ib -> output buffer */ for(ic = 0, ib = 0; ic <= len; ic++) { @@ -295,6 +310,11 @@ static PyMethodDef FilterMethods[] = { Py_UNICODE *to_unicode(const char *c, int len) { Py_UNICODE *x = (Py_UNICODE *)malloc((len+1) * sizeof(Py_UNICODE)); + if (x == NULL) { + PyErr_NoMemory(); + return NULL; + } + int i; for(i = 0; i < len; i++) { x[i] = (Py_UNICODE)c[i]; diff --git a/scripts/traffic/decrypt_userinfo.c b/scripts/traffic/decrypt_userinfo.c index 79bf326e0a..e83c74c355 100644 --- a/scripts/traffic/decrypt_userinfo.c +++ b/scripts/traffic/decrypt_userinfo.c @@ -68,12 +68,24 @@ int main(int argc, char** argv) /* base 64 decode and decrypt the ciphertext */ BIO* bio = BIO_new_mem_buf(ciphertext, b64_size); + if (bio == NULL) { + fprintf(stderr, "Failed to allocate buffer for b64 ciphertext\n"); + return 1; + } BIO* b64 = BIO_new(BIO_f_base64()); + if (b64 == NULL) { + fprintf(stderr, "Failed to allocate base64 filter\n"); + return 1; + } BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); bio = BIO_push(b64, bio); BIO* aes = BIO_new(BIO_f_cipher()); + if (aes == NULL) { + fprintf(stderr, "Failed to allocate AES cipher\n"); + return 1; + } BIO_set_cipher( aes, cipher, diff --git a/scripts/traffic/parse.c b/scripts/traffic/parse.c index 2e5df1b1be..2722ba5c96 100644 --- a/scripts/traffic/parse.c +++ b/scripts/traffic/parse.c @@ -57,6 +57,10 @@ int main(int argc, char** argv) pcre_fullinfo(re, extra, PCRE_INFO_CAPTURECOUNT, &group_count); int match_vector_size = (group_count + 1) * 3; int *matches = malloc(sizeof(int) * match_vector_size); + if (matches == NULL) { + fprintf(stderr, "Couldn't allocate memory for regex groups!\n"); + return 1; + } /* iterate through the input */ char input_line[MAX_LINE];