From 390be5517ebd2dc233f7eb7f4487ba870ae938d2 Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Fri, 12 Feb 2016 00:22:44 +0300 Subject: [PATCH] Fix null-pointer dereferences in case of out-of-memory in cord * cord/cordprnt.c: Include (for abort() declaration). * cord/cordprnt.c (OUT_OF_MEMORY): New macro. * cord/tests/de.c (OUT_OF_MEMORY): Likewise. * cord/cordprnt.c (CORD_vsprintf): Execute OUT_OF_MEMORY if GC_MALLOC_ATOMIC returns NULL. * cord/cordxtra.c (CORD_ec_flush_buf): Likewise. * cord/tests/de.c (replace_line, main): Likewise. * tests/cordtest.c (test_extras): Declare "u" local variable; do ABORT if CORD_substr returns NULL (to avoid null pointer dereference in strcmp). * cord/tests/de_win.c (plain_chars, control_chars): Return NULL if GC_MALLOC_ATOMIC returns NULL. * cord/tests/de_win.c (WndProc): Execute de_error() (with the appropriate message) if plain_chars() or control_chars() returned NULL (and do not call the corresponding TextOutA in such a case). --- cord/cordprnt.c | 12 +++++++++++- cord/cordxtra.c | 1 + cord/tests/cordtest.c | 6 ++++-- cord/tests/de.c | 11 ++++++++++- cord/tests/de_win.c | 15 +++++++++++---- 5 files changed, 37 insertions(+), 8 deletions(-) diff --git a/cord/cordprnt.c b/cord/cordprnt.c index 7e7745b..6e36c09 100644 --- a/cord/cordprnt.c +++ b/cord/cordprnt.c @@ -30,9 +30,12 @@ #include "cord.h" #include "ec.h" -#include + #include +#include +#include #include + #include "gc.h" #define CONV_SPEC_LEN 50 /* Maximum length of a single */ @@ -41,6 +44,11 @@ /* conversion with default */ /* width and prec. */ +#define OUT_OF_MEMORY do { \ + if (CORD_oom_fn != 0) (*CORD_oom_fn)(); \ + fprintf(stderr, "Out of memory\n"); \ + abort(); \ + } while (0) static int ec_len(CORD_ec x) { @@ -225,6 +233,7 @@ int CORD_vsprintf(CORD * out, CORD format, va_list args) if (width != NONE && len < (size_t)width) { char * blanks = GC_MALLOC_ATOMIC(width-len+1); + if (NULL == blanks) OUT_OF_MEMORY; memset(blanks, ' ', width-len); blanks[width-len] = '\0'; if (left_adj) { @@ -281,6 +290,7 @@ int CORD_vsprintf(CORD * out, CORD format, va_list args) max_size += CONV_RESULT_LEN; if (max_size >= CORD_BUFSZ) { buf = GC_MALLOC_ATOMIC(max_size + 1); + if (NULL == buf) OUT_OF_MEMORY; } else { if (CORD_BUFSZ - (result[0].ec_bufptr-result[0].ec_buf) < max_size) { diff --git a/cord/cordxtra.c b/cord/cordxtra.c index 610ea89..28ed886 100644 --- a/cord/cordxtra.c +++ b/cord/cordxtra.c @@ -428,6 +428,7 @@ void CORD_ec_flush_buf(CORD_ec x) if (len == 0) return; s = GC_MALLOC_ATOMIC(len+1); + if (NULL == s) OUT_OF_MEMORY; memcpy(s, x[0].ec_buf, len); s[len] = '\0'; x[0].ec_cord = CORD_cat_char_star(x[0].ec_cord, s, len); diff --git a/cord/tests/cordtest.c b/cord/tests/cordtest.c index 906f739..4706c2b 100644 --- a/cord/tests/cordtest.c +++ b/cord/tests/cordtest.c @@ -128,7 +128,7 @@ void test_extras(void) register int i; CORD y = "abcdefghijklmnopqrstuvwxyz0123456789"; CORD x = "{}"; - CORD w, z; + CORD u, w, z; FILE *f; FILE *f1a, *f1b, *f2; @@ -180,7 +180,9 @@ void test_extras(void) ABORT("file substr wrong"); if (strcmp(CORD_to_char_star(CORD_substr(w, 1000*36, 36)), y) != 0) ABORT("char * file substr wrong"); - if (strcmp(CORD_substr(w, 1000*36, 2), "ab") != 0) + u = CORD_substr(w, 1000*36, 2); + if (!u) ABORT("CORD_substr returned NULL"); + if (strcmp(u, "ab") != 0) ABORT("short file substr wrong"); if (CORD_str(x,1,"9a") != 35) ABORT("CORD_str failed 1"); if (CORD_str(x,0,"9abcdefghijk") != 35) ABORT("CORD_str failed 2"); diff --git a/cord/tests/de.c b/cord/tests/de.c index 28182dd..6f1a5e6 100644 --- a/cord/tests/de.c +++ b/cord/tests/de.c @@ -67,6 +67,11 @@ #endif #include "de_cmds.h" +#define OUT_OF_MEMORY do { \ + fprintf(stderr, "Out of memory\n"); \ + exit(3); \ + } while (0) + /* List of line number to position mappings, in descending order. */ /* There may be holes. */ typedef struct LineMapRep { @@ -215,6 +220,7 @@ void replace_line(int i, CORD s) if (screen == 0 || LINES > screen_size) { screen_size = LINES; screen = (CORD *)GC_MALLOC(screen_size * sizeof(CORD)); + if (NULL == screen) OUT_OF_MEMORY; } # if !defined(MACINTOSH) /* A gross workaround for an apparent curses bug: */ @@ -562,6 +568,7 @@ int argc; char ** argv; { int c; + void *buf; #if defined(MACINTOSH) console_options.title = "\pDumb Editor"; @@ -572,7 +579,9 @@ char ** argv; if (argc != 2) goto usage; arg_file_name = argv[1]; - setvbuf(stdout, GC_MALLOC_ATOMIC(8192), _IOFBF, 8192); + buf = GC_MALLOC_ATOMIC(8192); + if (NULL == buf) OUT_OF_MEMORY; + setvbuf(stdout, buf, _IOFBF, 8192); initscr(); noecho(); nonl(); cbreak(); generic_init(); diff --git a/cord/tests/de_win.c b/cord/tests/de_win.c index a19ff49..ecbd604 100644 --- a/cord/tests/de_win.c +++ b/cord/tests/de_win.c @@ -131,6 +131,7 @@ char * plain_chars(char * text, size_t len) char * result = GC_MALLOC_ATOMIC(len + 1); register size_t i; + if (NULL == result) return NULL; for (i = 0; i < len; i++) { if (iscntrl(((unsigned char *)text)[i])) { result[i] = ' '; @@ -149,6 +150,7 @@ char * control_chars(char * text, size_t len) char * result = GC_MALLOC_ATOMIC(len + 1); register size_t i; + if (NULL == result) return NULL; for (i = 0; i < len; i++) { if (iscntrl(((unsigned char *)text)[i])) { result[i] = text[i] + 0x40; @@ -317,20 +319,25 @@ LRESULT CALLBACK WndProc (HWND hwnd, UINT message, char * blanks = CORD_to_char_star(CORD_chars(' ', COLS - len)); char * control = control_chars(text, len); + if (NULL == plain || NULL == control) + de_error("Out of memory!"); + # define RED RGB(255,0,0) SetBkMode(dc, OPAQUE); SetTextColor(dc, GetSysColor(COLOR_WINDOWTEXT)); - TextOutA(dc, this_line.left, this_line.top, - plain, (int)len); + if (plain != NULL) + TextOutA(dc, this_line.left, this_line.top, + plain, (int)len); TextOutA(dc, this_line.left + (int)len * char_width, this_line.top, blanks, (int)(COLS - len)); SetBkMode(dc, TRANSPARENT); SetTextColor(dc, RED); - TextOutA(dc, this_line.left, this_line.top, - control, (int)strlen(control)); + if (control != NULL) + TextOutA(dc, this_line.left, this_line.top, + control, (int)strlen(control)); } } EndPaint(hwnd, &ps); -- 2.7.4