From 5cc7342606dbbd5e6932b39e6b1b5645164669bf Mon Sep 17 00:00:00 2001 From: Calvin Lee Date: Tue, 15 Aug 2017 07:56:47 +0200 Subject: Prevent alloc errors from crashing Resolves #76 --- backend/libinput/events.c | 50 +++++++++++++++++++++++++++++++++++++++++++-- backend/libinput/keyboard.c | 6 ++++-- backend/multi/backend.c | 6 +++++- backend/wayland/wl_seat.c | 2 +- 4 files changed, 58 insertions(+), 6 deletions(-) (limited to 'backend') diff --git a/backend/libinput/events.c b/backend/libinput/events.c index 0e434b7c..37ec6f4c 100644 --- a/backend/libinput/events.c +++ b/backend/libinput/events.c @@ -39,8 +39,10 @@ static struct wlr_input_device *allocate_device( int vendor = libinput_device_get_id_vendor(libinput_dev); int product = libinput_device_get_id_product(libinput_dev); const char *name = libinput_device_get_name(libinput_dev); - struct wlr_libinput_input_device *wlr_libinput_dev = - calloc(1, sizeof(struct wlr_libinput_input_device)); + struct wlr_libinput_input_device *wlr_libinput_dev; + if (!(wlr_libinput_dev = calloc(1, sizeof(struct wlr_libinput_input_device)))) { + return NULL; + } struct wlr_input_device *wlr_dev = &wlr_libinput_dev->wlr_input_device; wlr_libinput_dev->handle = libinput_dev; libinput_device_ref(libinput_dev); @@ -63,36 +65,74 @@ static void handle_device_added(struct wlr_libinput_backend *backend, int product = libinput_device_get_id_product(libinput_dev); const char *name = libinput_device_get_name(libinput_dev); list_t *wlr_devices = list_create(); + if (!wlr_devices) { + goto fail; + } wlr_log(L_DEBUG, "Added %s [%d:%d]", name, vendor, product); if (libinput_device_has_capability(libinput_dev, LIBINPUT_DEVICE_CAP_KEYBOARD)) { struct wlr_input_device *wlr_dev = allocate_device(backend, libinput_dev, wlr_devices, WLR_INPUT_DEVICE_KEYBOARD); + if (!wlr_dev) { + goto fail; + } wlr_dev->keyboard = wlr_libinput_keyboard_create(libinput_dev); + if (!wlr_dev->keyboard) { + free(wlr_dev); + goto fail; + } wl_signal_emit(&backend->backend.events.input_add, wlr_dev); } if (libinput_device_has_capability(libinput_dev, LIBINPUT_DEVICE_CAP_POINTER)) { struct wlr_input_device *wlr_dev = allocate_device(backend, libinput_dev, wlr_devices, WLR_INPUT_DEVICE_POINTER); + if (!wlr_dev) { + goto fail; + } wlr_dev->pointer = wlr_libinput_pointer_create(libinput_dev); + if (!wlr_dev->pointer) { + free(wlr_dev); + goto fail; + } wl_signal_emit(&backend->backend.events.input_add, wlr_dev); } if (libinput_device_has_capability(libinput_dev, LIBINPUT_DEVICE_CAP_TOUCH)) { struct wlr_input_device *wlr_dev = allocate_device(backend, libinput_dev, wlr_devices, WLR_INPUT_DEVICE_TOUCH); + if (!wlr_dev) { + goto fail; + } wlr_dev->touch = wlr_libinput_touch_create(libinput_dev); + if (!wlr_dev->touch) { + free(wlr_dev); + goto fail; + } wl_signal_emit(&backend->backend.events.input_add, wlr_dev); } if (libinput_device_has_capability(libinput_dev, LIBINPUT_DEVICE_CAP_TABLET_TOOL)) { struct wlr_input_device *wlr_dev = allocate_device(backend, libinput_dev, wlr_devices, WLR_INPUT_DEVICE_TABLET_TOOL); + if (!wlr_dev) { + goto fail; + } wlr_dev->tablet_tool = wlr_libinput_tablet_tool_create(libinput_dev); + if (!wlr_dev->tablet_tool) { + free(wlr_dev); + goto fail; + } wl_signal_emit(&backend->backend.events.input_add, wlr_dev); } if (libinput_device_has_capability(libinput_dev, LIBINPUT_DEVICE_CAP_TABLET_PAD)) { struct wlr_input_device *wlr_dev = allocate_device(backend, libinput_dev, wlr_devices, WLR_INPUT_DEVICE_TABLET_PAD); + if (!wlr_dev) { + goto fail; + } wlr_dev->tablet_pad = wlr_libinput_tablet_pad_create(libinput_dev); + if (!wlr_dev->tablet_pad) { + free(wlr_dev); + goto fail; + } wl_signal_emit(&backend->backend.events.input_add, wlr_dev); } if (libinput_device_has_capability(libinput_dev, LIBINPUT_DEVICE_CAP_GESTURE)) { @@ -108,6 +148,12 @@ static void handle_device_added(struct wlr_libinput_backend *backend, } else { list_free(wlr_devices); } + return; + +fail: + wlr_log(L_ERROR, "Could not allocate new device"); + list_foreach(wlr_devices, free); + list_free(wlr_devices); } static void handle_device_removed(struct wlr_libinput_backend *backend, diff --git a/backend/libinput/keyboard.c b/backend/libinput/keyboard.c index db4ac0ed..1c52a6b8 100644 --- a/backend/libinput/keyboard.c +++ b/backend/libinput/keyboard.c @@ -32,8 +32,10 @@ struct wlr_keyboard_impl impl = { struct wlr_keyboard *wlr_libinput_keyboard_create( struct libinput_device *libinput_dev) { assert(libinput_dev); - struct wlr_libinput_keyboard *wlr_libinput_kb = - calloc(1, sizeof(struct wlr_libinput_keyboard)); + struct wlr_libinput_keyboard *wlr_libinput_kb; + if (!(wlr_libinput_kb= calloc(1, sizeof(struct wlr_libinput_keyboard)))) { + return NULL; + } wlr_libinput_kb->libinput_dev = libinput_dev; libinput_device_ref(libinput_dev); libinput_device_led_update(libinput_dev, 0); diff --git a/backend/multi/backend.c b/backend/multi/backend.c index 9afca47d..290b9678 100644 --- a/backend/multi/backend.c +++ b/backend/multi/backend.c @@ -115,7 +115,11 @@ void wlr_multi_backend_add(struct wlr_backend *_multi, assert(wlr_backend_is_multi(_multi)); struct wlr_multi_backend *multi = (struct wlr_multi_backend *)_multi; - struct subbackend_state *sub = calloc(1, sizeof(struct subbackend_state)); + struct subbackend_state *sub; + if (!(sub = calloc(1, sizeof(struct subbackend_state)))) { + wlr_log(L_ERROR, "Could not add backend: allocation failed"); + return; + } sub->backend = backend; sub->container = &multi->backend; diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c index 6e645a58..3742d4fb 100644 --- a/backend/wayland/wl_seat.c +++ b/backend/wayland/wl_seat.c @@ -239,7 +239,7 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, struct wlr_input_device *wlr_device = allocate_device(backend, WLR_INPUT_DEVICE_KEYBOARD); if (!wlr_device) { - wlr_log(L_ERROR, "Unable to allocate wl_pointer device"); + wlr_log(L_ERROR, "Unable to allocate wl_keyboard device"); return; } wlr_device->keyboard = calloc(1, sizeof(struct wlr_keyboard)); -- cgit v1.2.3