From 71d303a1805b454395b9b2ed4d1007699b9d1314 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Sun, 15 Oct 2017 13:43:35 +0100 Subject: fix unchecked heap allocation returns Alastair Hughes provided a patch in the bug tracker which I based this implementation upon. Closes: #2553 --- src/cursor.c | 8 +++++++- src/nsfb.h | 3 ++- src/plot/generic.c | 10 +++++++++- src/surface/ram.c | 37 +++++++++++++++++++++++++++++++++---- src/surface/wld.c | 26 +++++++++++++++----------- src/surface/x.c | 17 +++++++++++++---- 6 files changed, 79 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/cursor.c b/src/cursor.c index 87633dc..1f107a5 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -99,7 +99,13 @@ bool nsfb_cursor_plot(nsfb_t *nsfb, struct nsfb_cursor_s *cursor) sav_size = cursor->sav_width * cursor->sav_height * sizeof(nsfb_colour_t); if (cursor->sav_size < sav_size) { - cursor->sav = realloc(cursor->sav, sav_size); + nsfb_colour_t *nsav; + + nsav = realloc(cursor->sav, sav_size); + if (nsav == NULL) { + return false; + } + cursor->sav = nsav; cursor->sav_size = sav_size; } diff --git a/src/nsfb.h b/src/nsfb.h index 9a61775..73f6678 100644 --- a/src/nsfb.h +++ b/src/nsfb.h @@ -14,7 +14,8 @@ #include -/** NS Framebuffer context +/** + * Framebuffer context */ struct nsfb_s { int width; /**< Visible width. */ diff --git a/src/plot/generic.c b/src/plot/generic.c index 0c3d9e8..a6dd549 100644 --- a/src/plot/generic.c +++ b/src/plot/generic.c @@ -799,6 +799,9 @@ path(nsfb_t *nsfb, int pathc, nsfb_plot_pathop_t *pathop, nsfb_plot_pen_t *pen) /* allocate storage for the vertexes */ curpt = pts = malloc(ptc * sizeof(nsfb_point_t)); + if (curpt == NULL) { + return false; + } for (path_loop = 0; path_loop < pathc; path_loop++) { switch (pathop[path_loop].operation) { @@ -906,10 +909,15 @@ bool select_plotters(nsfb_t *nsfb) return false; } - if (nsfb->plotter_fns != NULL) + if (nsfb->plotter_fns != NULL) { free(nsfb->plotter_fns); + } nsfb->plotter_fns = calloc(1, sizeof(nsfb_plotter_fns_t)); + if (nsfb->plotter_fns == NULL) { + return false; + } + memcpy(nsfb->plotter_fns, table, sizeof(nsfb_plotter_fns_t)); /* set the generics */ diff --git a/src/surface/ram.c b/src/surface/ram.c index 4deabda..da769b6 100644 --- a/src/surface/ram.c +++ b/src/surface/ram.c @@ -35,19 +35,35 @@ static int ram_defaults(nsfb_t *nsfb) static int ram_initialise(nsfb_t *nsfb) { - size_t size = (nsfb->width * nsfb->height * nsfb->bpp) / 8; + size_t size; + uint8_t *fbptr; - nsfb->ptr = realloc(nsfb->ptr, size); + size = (nsfb->width * nsfb->height * nsfb->bpp) / 8; + fbptr = realloc(nsfb->ptr, size); + if (fbptr == NULL) { + return -1; + } + + nsfb->ptr = fbptr; nsfb->linelen = (nsfb->width * nsfb->bpp) / 8; return 0; } -static int ram_set_geometry(nsfb_t *nsfb, int width, int height, enum nsfb_format_e format) +static int +ram_set_geometry(nsfb_t *nsfb, int width, int height, enum nsfb_format_e format) { int startsize; int endsize; + int prev_width; + int prev_height; + enum nsfb_format_e prev_format; + + prev_width = nsfb->width; + prev_height = nsfb->height; + prev_format = nsfb->format; + startsize = (nsfb->width * nsfb->height * nsfb->bpp) / 8; if (width > 0) { @@ -65,10 +81,23 @@ static int ram_set_geometry(nsfb_t *nsfb, int width, int height, enum nsfb_forma /* select soft plotters appropriate for format */ select_plotters(nsfb); + /* reallocate surface memory if necessary */ endsize = (nsfb->width * nsfb->height * nsfb->bpp) / 8; if ((nsfb->ptr != NULL) && (startsize != endsize)) { - nsfb->ptr = realloc(nsfb->ptr, endsize); + uint8_t *fbptr; + fbptr = realloc(nsfb->ptr, endsize); + if (fbptr == NULL) { + /* allocation failed so put everything back as it was */ + nsfb->width = prev_width; + nsfb->height = prev_height; + nsfb->format = prev_format; + select_plotters(nsfb); + + return -1; + } + nsfb->ptr = fbptr; } + nsfb->linelen = (nsfb->width * nsfb->bpp) / 8; return 0; diff --git a/src/surface/wld.c b/src/surface/wld.c index 29f9ae2..9ef3c40 100644 --- a/src/surface/wld.c +++ b/src/surface/wld.c @@ -48,7 +48,7 @@ struct wld_connection { struct wl_display *display; /**< connection object */ struct wl_registry *registry; /**< registry object */ - /** compositor object, available once teh registry messages have + /** compositor object, available once the registry messages have * been processed */ struct wl_compositor *compositor; @@ -975,13 +975,14 @@ pointer_handle_motion(void *data, UNUSED(time); event = calloc(1, sizeof(struct wld_event)); + if (event != NULL) { + event->event.type = NSFB_EVENT_MOVE_ABSOLUTE; + event->event.value.vector.x = wl_fixed_to_int(sx_w); + event->event.value.vector.y = wl_fixed_to_int(sy_w); + event->event.value.vector.z = 0; - event->event.type = NSFB_EVENT_MOVE_ABSOLUTE; - event->event.value.vector.x = wl_fixed_to_int(sx_w); - event->event.value.vector.y = wl_fixed_to_int(sy_w); - event->event.value.vector.z = 0; - - enqueue_wld_event(input->connection, event); + enqueue_wld_event(input->connection, event); + } } static void @@ -997,7 +998,9 @@ pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial, UNUSED(time); event = calloc(1, sizeof(struct wld_event)); - + if (event == NULL) { + return; + } if (state == WL_POINTER_BUTTON_STATE_PRESSED) { event->event.type = NSFB_EVENT_KEY_DOWN; } else { @@ -1259,7 +1262,6 @@ new_connection(void) struct wld_connection* connection; connection = calloc(1, sizeof(struct wld_connection)); - if (connection == NULL) { return NULL; } @@ -1456,8 +1458,9 @@ os_create_anonymous_file(off_t size) } name = malloc(strlen(path) + sizeof(template)); - if (!name) + if (name == NULL) { return -1; + } strcpy(name, path); strcat(name, template); @@ -1657,8 +1660,9 @@ static int x_initialise(nsfb_t *nsfb) return -1; xstate = calloc(1, sizeof(xstate_t)); - if (xstate == NULL) + if (xstate == NULL) { return -1; /* no memory */ + } /* open connection with the server */ xstate->connection = xcb_connect(NULL, NULL); diff --git a/src/surface/x.c b/src/surface/x.c index f5ee01b..c011b38 100644 --- a/src/surface/x.c +++ b/src/surface/x.c @@ -846,10 +846,19 @@ static int x_initialise(nsfb_t *nsfb) mask, values); /* set size hits on window */ hints = xcb_alloc_size_hints(); - xcb_size_hints_set_max_size(hints, xstate->image->width, xstate->image->height); - xcb_size_hints_set_min_size(hints, xstate->image->width, xstate->image->height); - xcb_set_wm_size_hints(xstate->connection, xstate->window, WM_NORMAL_HINTS, hints); - xcb_free_size_hints(hints); + if (hints != NULL) { + xcb_size_hints_set_max_size(hints, + xstate->image->width, + xstate->image->height); + xcb_size_hints_set_min_size(hints, + xstate->image->width, + xstate->image->height); + xcb_set_wm_size_hints(xstate->connection, + xstate->window, + WM_NORMAL_HINTS, + hints); + xcb_free_size_hints(hints); + } /* create backing pixmap */ xstate->pmap = xcb_generate_id(xstate->connection); -- cgit v1.2.3