From 248df18c24d2a849de984b477ca3913ce7c72441 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 15 Dec 2016 17:39:09 -0500 Subject: Handle allocation failure in commands --- sway/commands/assign.c | 3 +++ sway/commands/bar.c | 9 ++++++++- sway/commands/bar/bindsym.c | 3 +++ sway/commands/bar/colors.c | 6 ++++++ sway/commands/bind.c | 23 +++++++++++++++++++---- sway/commands/exec_always.c | 7 ++++--- sway/commands/for_window.c | 3 +++ sway/commands/mode.c | 5 ++++- sway/commands/output.c | 18 +++++++++++++----- sway/commands/set.c | 3 +++ 10 files changed, 66 insertions(+), 14 deletions(-) (limited to 'sway/commands') diff --git a/sway/commands/assign.c b/sway/commands/assign.c index 53c599ca..1824692b 100644 --- a/sway/commands/assign.c +++ b/sway/commands/assign.c @@ -27,6 +27,9 @@ struct cmd_results *cmd_assign(int argc, char **argv) { snprintf(cmdlist, arglen, "%s%s", movecmd, *argv); struct criteria *crit = malloc(sizeof(struct criteria)); + if (!crit) { + return cmd_results_new(CMD_FAILURE, "assign", "Unable to allocate criteria"); + } crit->crit_raw = strdup(criteria); crit->cmdlist = cmdlist; crit->tokens = create_list(); diff --git a/sway/commands/bar.c b/sway/commands/bar.c index 55cb0d9d..e8d24084 100644 --- a/sway/commands/bar.c +++ b/sway/commands/bar.c @@ -32,6 +32,9 @@ struct cmd_results *cmd_bar(int argc, char **argv) { // Create new bar with default values struct bar_config *bar = default_bar_config(); + if (!bar) { + return cmd_results_new(CMD_FAILURE, "bar", "Unable to allocate bar state"); + } // set bar id int i; @@ -39,7 +42,11 @@ struct cmd_results *cmd_bar(int argc, char **argv) { if (bar == config->bars->items[i]) { const int len = 5 + numlen(i); // "bar-" + i + \0 bar->id = malloc(len * sizeof(char)); - snprintf(bar->id, len, "bar-%d", i); + if (bar->id) { + snprintf(bar->id, len, "bar-%d", i); + } else { + return cmd_results_new(CMD_FAILURE, "bar", "Unable to allocate bar ID"); + } break; } } diff --git a/sway/commands/bar/bindsym.c b/sway/commands/bar/bindsym.c index bb81b4a9..5f90b51a 100644 --- a/sway/commands/bar/bindsym.c +++ b/sway/commands/bar/bindsym.c @@ -26,6 +26,9 @@ struct cmd_results *bar_cmd_bindsym(int argc, char **argv) { return cmd_results_new(CMD_INVALID, "bindsym", "Invalid mouse binding %s", argv[1]); } struct sway_mouse_binding *binding = malloc(sizeof(struct sway_mouse_binding)); + if (!binding) { + return cmd_results_new(CMD_FAILURE, "bindsym", "Unable to allocate binding"); + } binding->button = numbutton; binding->command = join_args(argv + 1, argc - 1); diff --git a/sway/commands/bar/colors.c b/sway/commands/bar/colors.c index f6fb520a..f8792973 100644 --- a/sway/commands/bar/colors.c +++ b/sway/commands/bar/colors.c @@ -9,6 +9,9 @@ static struct cmd_results *parse_single_color(char **color, const char *cmd_name if (!*color) { *color = malloc(10); + if (!*color) { + return cmd_results_new(CMD_FAILURE, cmd_name, "Unable to allocate color"); + } } error = add_color(cmd_name, *color, argv[0]); @@ -29,6 +32,9 @@ static struct cmd_results *parse_three_colors(char ***colors, const char *cmd_na for (i = 0; i < 3; i++) { if (!*colors[i]) { *(colors[i]) = malloc(10); + if (!*(colors[i])) { + return cmd_results_new(CMD_FAILURE, cmd_name, "Unable to allocate color"); + } } error = add_color(cmd_name, *(colors[i]), argv[i]); if (error) { diff --git a/sway/commands/bind.c b/sway/commands/bind.c index e8bb3ee8..8282277b 100644 --- a/sway/commands/bind.c +++ b/sway/commands/bind.c @@ -16,6 +16,10 @@ struct cmd_results *cmd_bindsym(int argc, char **argv) { } struct sway_binding *binding = malloc(sizeof(struct sway_binding)); + if (!binding) { + return cmd_results_new(CMD_FAILURE, "bindsym", + "Unable to allocate binding"); + } binding->keys = create_list(); binding->modifiers = 0; binding->release = false; @@ -46,14 +50,21 @@ struct cmd_results *cmd_bindsym(int argc, char **argv) { continue; } // Check for xkb key - xkb_keysym_t sym = xkb_keysym_from_name(split->items[i], XKB_KEYSYM_CASE_INSENSITIVE); + xkb_keysym_t sym = xkb_keysym_from_name(split->items[i], + XKB_KEYSYM_CASE_INSENSITIVE); if (!sym) { - error = cmd_results_new(CMD_INVALID, "bindsym", "Unknown key '%s'", (char *)split->items[i]); free_sway_binding(binding); - list_free(split); - return error; + free_flat_list(split); + return cmd_results_new(CMD_INVALID, "bindsym", "Unknown key '%s'", + (char *)split->items[i]); } xkb_keysym_t *key = malloc(sizeof(xkb_keysym_t)); + if (!key) { + free_sway_binding(binding); + free_flat_list(split); + return cmd_results_new(CMD_FAILURE, "bindsym", + "Unable to allocate binding"); + } *key = sym; list_add(binding->keys, key); } @@ -82,6 +93,10 @@ struct cmd_results *cmd_bindcode(int argc, char **argv) { } struct sway_binding *binding = malloc(sizeof(struct sway_binding)); + if (!binding) { + return cmd_results_new(CMD_FAILURE, "bindsym", + "Unable to allocate binding"); + } binding->keys = create_list(); binding->modifiers = 0; binding->release = false; diff --git a/sway/commands/exec_always.c b/sway/commands/exec_always.c index 157d4872..1d7cd494 100644 --- a/sway/commands/exec_always.c +++ b/sway/commands/exec_always.c @@ -39,6 +39,9 @@ struct cmd_results *cmd_exec_always(int argc, char **argv) { pid_t pid; pid_t *child = malloc(sizeof(pid_t)); // malloc'd so that Linux can avoid copying the process space + if (!child) { + return cmd_results_new(CMD_FAILURE, "exec_always", "Unable to allocate child pid"); + } // Fork process if ((pid = fork()) == 0) { // Fork child process again @@ -56,7 +59,7 @@ struct cmd_results *cmd_exec_always(int argc, char **argv) { _exit(0); // Close child process } else if (pid < 0) { free(child); - return cmd_results_new(CMD_FAILURE, "exec_always", "Command failed (sway could not fork)."); + return cmd_results_new(CMD_FAILURE, "exec_always", "fork() failed"); } close(fd[1]); // close write ssize_t s = 0; @@ -73,8 +76,6 @@ struct cmd_results *cmd_exec_always(int argc, char **argv) { pw->pid = child; pw->workspace = strdup(ws->name); pid_workspace_add(pw); - // TODO: keep track of this pid and open the corresponding view on the current workspace - // blocked pending feature in wlc } else { free(child); } diff --git a/sway/commands/for_window.c b/sway/commands/for_window.c index 2ba0ea6c..8c5722fd 100644 --- a/sway/commands/for_window.c +++ b/sway/commands/for_window.c @@ -14,6 +14,9 @@ struct cmd_results *cmd_for_window(int argc, char **argv) { char *criteria = argv[0], *cmdlist = join_args(argv + 1, argc - 1); struct criteria *crit = malloc(sizeof(struct criteria)); + if (!crit) { + return cmd_results_new(CMD_FAILURE, "for_window", "Unable to allocate criteria"); + } crit->crit_raw = strdup(criteria); crit->cmdlist = cmdlist; crit->tokens = create_list(); diff --git a/sway/commands/mode.c b/sway/commands/mode.c index f9cb271e..ed3f432f 100644 --- a/sway/commands/mode.c +++ b/sway/commands/mode.c @@ -30,7 +30,10 @@ struct cmd_results *cmd_mode(int argc, char **argv) { } // Create mode if it doesn't exist if (!mode && mode_make) { - mode = malloc(sizeof*mode); + mode = malloc(sizeof(struct sway_mode)); + if (!mode) { + return cmd_results_new(CMD_FAILURE, "mode", "Unable to allocate mode"); + } mode->name = strdup(mode_name); mode->bindings = create_list(); list_add(config->modes, mode); diff --git a/sway/commands/output.c b/sway/commands/output.c index 6c1c55b5..e150aed2 100644 --- a/sway/commands/output.c +++ b/sway/commands/output.c @@ -113,12 +113,20 @@ struct cmd_results *cmd_output(int argc, char **argv) { src = p.we_wordv[0]; if (config->reading && *src != '/') { char *conf = strdup(config->current_config); - char *conf_path = dirname(conf); - src = malloc(strlen(conf_path) + strlen(src) + 2); - sprintf(src, "%s/%s", conf_path, p.we_wordv[0]); - free(conf); + if (conf) { + char *conf_path = dirname(conf); + src = malloc(strlen(conf_path) + strlen(src) + 2); + if (src) { + sprintf(src, "%s/%s", conf_path, p.we_wordv[0]); + } else { + sway_log(L_ERROR, "Unable to allocate background source"); + } + free(conf); + } else { + sway_log(L_ERROR, "Unable to allocate background source"); + } } - if (access(src, F_OK) == -1) { + if (!src || access(src, F_OK) == -1) { return cmd_results_new(CMD_INVALID, "output", "Background file unreadable (%s)", src); } for (char *m = mode; *m; ++m) *m = tolower(*m); diff --git a/sway/commands/set.c b/sway/commands/set.c index 1f324951..8b293825 100644 --- a/sway/commands/set.c +++ b/sway/commands/set.c @@ -47,6 +47,9 @@ struct cmd_results *cmd_set(int argc, char **argv) { free(var->value); } else { var = malloc(sizeof(struct sway_variable)); + if (!var) { + return cmd_results_new(CMD_FAILURE, "set", "Unable to allocate variable"); + } var->name = strdup(argv[0]); list_add(config->symbols, var); list_qsort(config->symbols, compare_set_qsort); -- cgit v1.2.3 From 7784f1a905cad5ad805195dcc3cba23ff206501c Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 15 Dec 2016 18:10:29 -0500 Subject: Handle allocation failures in security code Note that such errors are generally going to be fatal --- sway/commands.c | 3 +++ sway/commands/permit.c | 3 +++ sway/security.c | 20 ++++++++++++++++++-- 3 files changed, 24 insertions(+), 2 deletions(-) (limited to 'sway/commands') diff --git a/sway/commands.c b/sway/commands.c index 8d199467..c15cb00a 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -575,6 +575,9 @@ struct cmd_results *config_commands_command(char *exec) { } if (!policy) { policy = alloc_command_policy(cmd); + if (!policy) { + sway_abort("Unable to allocate security policy"); + } list_add(config->command_policies, policy); } policy->context = context; diff --git a/sway/commands/permit.c b/sway/commands/permit.c index 7a25e4ce..dee246d7 100644 --- a/sway/commands/permit.c +++ b/sway/commands/permit.c @@ -50,6 +50,9 @@ static struct feature_policy *get_policy(const char *name) { } if (!policy) { policy = alloc_feature_policy(name); + if (!policy) { + sway_abort("Unable to allocate security policy"); + } list_add(config->feature_policies, policy); } return policy; diff --git a/sway/security.c b/sway/security.c index 9cccd62e..41a3b94b 100644 --- a/sway/security.c +++ b/sway/security.c @@ -15,14 +15,28 @@ struct feature_policy *alloc_feature_policy(const char *program) { } struct feature_policy *policy = malloc(sizeof(struct feature_policy)); + if (!policy) { + return NULL; + } policy->program = strdup(program); + if (!policy->program) { + free(policy); + return NULL; + } policy->features = default_policy; return policy; } struct command_policy *alloc_command_policy(const char *command) { struct command_policy *policy = malloc(sizeof(struct command_policy)); + if (!policy) { + return NULL; + } policy->command = strdup(command); + if (!policy->command) { + free(policy); + return NULL; + } policy->context = 0; return policy; } @@ -35,12 +49,14 @@ enum secure_feature get_feature_policy(pid_t pid) { #endif int pathlen = snprintf(NULL, 0, fmt, pid); char *path = malloc(pathlen + 1); - snprintf(path, pathlen + 1, fmt, pid); + if (path) { + snprintf(path, pathlen + 1, fmt, pid); + } static char link[2048]; uint32_t default_policy = 0; - ssize_t len = readlink(path, link, sizeof(link)); + ssize_t len = !path ? -1 : readlink(path, link, sizeof(link)); if (len < 0) { sway_log(L_INFO, "WARNING: unable to read %s for security check. Using default policy.", -- cgit v1.2.3 From 10c8b73075fa0dd5512cc14be7240ec47f68dece Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 15 Dec 2016 18:26:53 -0500 Subject: Handle calloc failures --- sway/commands/assign.c | 5 ++++- sway/commands/output.c | 3 +++ sway/commands/workspace.c | 4 ++++ sway/config.c | 3 +++ sway/container.c | 3 +++ sway/extensions.c | 4 ++++ sway/input.c | 10 +++++++++- sway/ipc-json.c | 9 +++++++++ 8 files changed, 39 insertions(+), 2 deletions(-) (limited to 'sway/commands') diff --git a/sway/commands/assign.c b/sway/commands/assign.c index 1824692b..992b4692 100644 --- a/sway/commands/assign.c +++ b/sway/commands/assign.c @@ -23,11 +23,14 @@ struct cmd_results *cmd_assign(int argc, char **argv) { char *movecmd = "move container to workspace "; int arglen = strlen(movecmd) + strlen(*argv) + 1; char *cmdlist = calloc(1, arglen); - + if (!cmdlist) { + return cmd_results_new(CMD_FAILURE, "assign", "Unable to allocate command list"); + } snprintf(cmdlist, arglen, "%s%s", movecmd, *argv); struct criteria *crit = malloc(sizeof(struct criteria)); if (!crit) { + free(cmdlist); return cmd_results_new(CMD_FAILURE, "assign", "Unable to allocate criteria"); } crit->crit_raw = strdup(criteria); diff --git a/sway/commands/output.c b/sway/commands/output.c index e150aed2..01ac9f4e 100644 --- a/sway/commands/output.c +++ b/sway/commands/output.c @@ -26,6 +26,9 @@ struct cmd_results *cmd_output(int argc, char **argv) { const char *name = argv[0]; struct output_config *output = calloc(1, sizeof(struct output_config)); + if (!output) { + return cmd_results_new(CMD_FAILURE, "output", "Unable to allocate output config"); + } output->x = output->y = output->width = output->height = -1; output->name = strdup(name); output->enabled = -1; diff --git a/sway/commands/workspace.c b/sway/commands/workspace.c index 35224f8a..14fe242f 100644 --- a/sway/commands/workspace.c +++ b/sway/commands/workspace.c @@ -61,6 +61,10 @@ struct cmd_results *cmd_workspace(int argc, char **argv) { return error; } struct workspace_output *wso = calloc(1, sizeof(struct workspace_output)); + if (!wso) { + return cmd_results_new(CMD_FAILURE, "workspace output", + "Unable to allocate workspace output"); + } wso->workspace = strdup(argv[0]); wso->output = strdup(argv[2]); int i = -1; diff --git a/sway/config.c b/sway/config.c index b86bacdb..4164cefa 100644 --- a/sway/config.c +++ b/sway/config.c @@ -494,6 +494,9 @@ bool load_main_config(const char *file, bool is_active) { struct sway_config *old_config = config; config = calloc(1, sizeof(struct sway_config)); + if (!config) { + sway_abort("Unable to allocate config"); + } config_defaults(config); if (is_active) { diff --git a/sway/container.c b/sway/container.c index 8a584efa..d9677cdb 100644 --- a/sway/container.c +++ b/sway/container.c @@ -23,6 +23,9 @@ static swayc_t *new_swayc(enum swayc_types type) { // next id starts at 1 because 0 is assigned to root_container in layout.c static size_t next_id = 1; swayc_t *c = calloc(1, sizeof(swayc_t)); + if (!c) { + return NULL; + } c->id = next_id++; c->handle = -1; c->gaps = -1; diff --git a/sway/extensions.c b/sway/extensions.c index 759cbb84..40702e28 100644 --- a/sway/extensions.c +++ b/sway/extensions.c @@ -23,6 +23,10 @@ static struct panel_config *find_or_create_panel_config(struct wl_resource *reso } sway_log(L_DEBUG, "Creating panel config for resource %p", resource); struct panel_config *config = calloc(1, sizeof(struct panel_config)); + if (!config) { + sway_log(L_ERROR, "Unable to create panel config"); + return NULL; + } list_add(desktop_shell.panels, config); config->wl_resource = resource; return config; diff --git a/sway/input.c b/sway/input.c index 61757ab8..249d95c6 100644 --- a/sway/input.c +++ b/sway/input.c @@ -11,8 +11,16 @@ struct input_config *new_input_config(const char* identifier) { struct input_config *input = calloc(1, sizeof(struct input_config)); + if (!input) { + sway_log(L_DEBUG, "Unable to allocate input config"); + return NULL; + } sway_log(L_DEBUG, "new_input_config(%s)", identifier); - input->identifier = strdup(identifier); + if (!(input->identifier = strdup(identifier))) { + free(input); + sway_log(L_DEBUG, "Unable to allocate input config"); + return NULL; + } input->tap = INT_MIN; input->drag_lock = INT_MIN; diff --git a/sway/ipc-json.c b/sway/ipc-json.c index e65e9de3..fd17216e 100644 --- a/sway/ipc-json.c +++ b/sway/ipc-json.c @@ -245,6 +245,15 @@ json_object *ipc_json_get_version() { #if defined SWAY_GIT_VERSION && defined SWAY_GIT_BRANCH && defined SWAY_VERSION_DATE char *full_version = calloc(strlen(SWAY_GIT_VERSION) + strlen(SWAY_GIT_BRANCH) + strlen(SWAY_VERSION_DATE) + 20, 1); + if (!full_version) { + json_object_object_add(version, "human_readable", + json_object_new_string("Allocating version string failed")); + // TODO: it's stupid that we allocate this in the first place + json_object_object_add(version, "major", json_object_new_int(0)); + json_object_object_add(version, "minor", json_object_new_int(0)); + json_object_object_add(version, "patch", json_object_new_int(0)); + return version; + } strcat(full_version, SWAY_GIT_VERSION); strcat(full_version, " ("); strcat(full_version, SWAY_VERSION_DATE); -- cgit v1.2.3 From 63d96c1bb45da39fa751fae654102e4dab36079a Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 15 Dec 2016 18:39:40 -0500 Subject: Fix indentation issues --- sway/commands/bar/colors.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sway/commands') diff --git a/sway/commands/bar/colors.c b/sway/commands/bar/colors.c index f8792973..8b3b0aac 100644 --- a/sway/commands/bar/colors.c +++ b/sway/commands/bar/colors.c @@ -32,9 +32,9 @@ static struct cmd_results *parse_three_colors(char ***colors, const char *cmd_na for (i = 0; i < 3; i++) { if (!*colors[i]) { *(colors[i]) = malloc(10); - if (!*(colors[i])) { - return cmd_results_new(CMD_FAILURE, cmd_name, "Unable to allocate color"); - } + if (!*(colors[i])) { + return cmd_results_new(CMD_FAILURE, cmd_name, "Unable to allocate color"); + } } error = add_color(cmd_name, *(colors[i]), argv[i]); if (error) { -- cgit v1.2.3