diff --git a/Checking-return-value-of-strdup-in-collect_full_irq_.patch b/Checking-return-value-of-strdup-in-collect_full_irq_.patch new file mode 100644 index 0000000..30266a3 --- /dev/null +++ b/Checking-return-value-of-strdup-in-collect_full_irq_.patch @@ -0,0 +1,29 @@ +From 7dafc4d5c8d8229f107c90d97f33a4094eb89c6e Mon Sep 17 00:00:00 2001 +From: liuchao173 +Date: Thu, 7 Nov 2019 09:12:42 +0000 +Subject: [PATCH 1/8] backport: Checking return value of strdup() in + collect_full_irq_list() + +strdup() may return NULL if memory allocation fail, checking the return +value before reference. + +Signed-off-by: Yunfeng Ye +--- + procinterrupts.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/procinterrupts.c b/procinterrupts.c +index 2c8118a..87fae2f 100644 +--- a/procinterrupts.c ++++ b/procinterrupts.c +@@ -188,6 +188,8 @@ GList* collect_full_irq_list() + continue; + + savedline = strdup(line); ++ if (!savedline) ++ break; + irq_name = strtok_r(savedline, " ", &savedptr); + if (strstr(irq_name, "xen-dyn") != NULL) + is_xen_dyn = 1; +-- +2.19.1 diff --git a/bugfix-fix-strcat-may-cause-buffer-overrun.patch b/bugfix-fix-strcat-may-cause-buffer-overrun.patch new file mode 100644 index 0000000..4c571c4 --- /dev/null +++ b/bugfix-fix-strcat-may-cause-buffer-overrun.patch @@ -0,0 +1,64 @@ +From f4d052d7b210612a7ffbdd7c3cfbce213c9a0e21 Mon Sep 17 00:00:00 2001 +From: liuchao173 +Date: Fri, 8 Nov 2019 08:47:43 +0000 +Subject: [PATCH] irqbalance: fix strcat may cause buffer overrun + +when the sum length of irq_name and saveptr is more than PATH_MAX, strcat will cause buffer overrun +--- + procinterrupts.c | 26 ++++++++++++++++++-------- + 1 file changed, 18 insertions(+), 8 deletions(-) + +diff --git a/procinterrupts.c b/procinterrupts.c +index 373d8b5..0b24b56 100644 +--- a/procinterrupts.c ++++ b/procinterrupts.c +@@ -205,6 +205,7 @@ static void init_irq_class_and_type(char *savedline, struct irq_info *info, int + int is_xen_dyn = 0; + #ifdef AARCH64 + char *tmp = NULL; ++ char irq_fullname_valid = 1; + char irq_fullname[PATH_MAX] = {0}; + #endif + +@@ -236,12 +237,16 @@ static void init_irq_class_and_type(char *savedline, struct irq_info *info, int + if (tmp) + *tmp = 0; + +- strcat(irq_fullname, irq_name); +- strcat(irq_fullname, " "); +- strcat(irq_fullname, savedptr); +- tmp = strchr(irq_fullname, '\n'); +- if (tmp) +- *tmp = 0; ++ if (strlen(irq_name) + strlen(savedptr) + 1 < PATH_MAX) { ++ strcat(irq_fullname, irq_name); ++ strcat(irq_fullname, " "); ++ strcat(irq_fullname, savedptr); ++ tmp = strchr(irq_fullname, '\n'); ++ if (tmp) ++ *tmp = 0; ++ } else { ++ irq_fullname_valid = 0; ++ } + #endif + irq_mod = last_token; + info->irq = irq; +@@ -251,8 +256,13 @@ static void init_irq_class_and_type(char *savedline, struct irq_info *info, int + info->class = IRQ_VIRT_EVENT; + } else { + #ifdef AARCH64 +- irq_name = irq_fullname; +- guess_arm_irq_hints(irq_name, info); ++ if (irq_fullname_valid) { ++ irq_name = irq_fullname; ++ guess_arm_irq_hints(irq_name, info); ++ } else { ++ info->type = IRQ_TYPE_LEGACY; ++ info->class = IRQ_OTHER; ++ } + #else + info->type = IRQ_TYPE_LEGACY; + info->class = IRQ_OTHER; +-- +2.19.1 + diff --git a/correct-to-use-realloc-function.patch b/correct-to-use-realloc-function.patch new file mode 100644 index 0000000..636bd4a --- /dev/null +++ b/correct-to-use-realloc-function.patch @@ -0,0 +1,106 @@ +From 22a40e9d0dd59ee58ff06d2b6360007e046d608f Mon Sep 17 00:00:00 2001 +From: liuchao173 +Date: Thu, 7 Nov 2019 09:33:47 +0000 +Subject: [PATCH 6/8] irqbalance: correct to use realloc() function + +The man doc about realloc() say: + " + If realloc() fails the original block is left untouched; it is not + freed or move + " + +So make the handling of realloc() function correctly. + +In addition, there is another problem about parameter using in +sock_handle(), it should be use the address of @setup instead of @setup. + +Signed-off-by: Yunfeng Ye +--- + irqbalance.c | 33 +++++++++++++++++++++++---------- + 1 file changed, 23 insertions(+), 10 deletions(-) + +diff --git a/irqbalance.c b/irqbalance.c +index c9378d0..cace4d8 100644 +--- a/irqbalance.c ++++ b/irqbalance.c +@@ -321,14 +321,18 @@ gboolean scan(gpointer data) + void get_irq_data(struct irq_info *irq, void *data) + { + char **irqdata = (char **)data; ++ char *newptr = NULL; ++ + if (!*irqdata) +- *irqdata = calloc(24 + 1 + 11 + 20 + 20 + 11, 1); ++ newptr = calloc(24 + 1 + 11 + 20 + 20 + 11, 1); + else +- *irqdata = realloc(*irqdata, strlen(*irqdata) + 24 + 1 + 11 + 20 + 20 + 11); ++ newptr = realloc(*irqdata, strlen(*irqdata) + 24 + 1 + 11 + 20 + 20 + 11); + +- if (!*irqdata) ++ if (!newptr) + return; + ++ *irqdata = newptr; ++ + sprintf(*irqdata + strlen(*irqdata), + "IRQ %d LOAD %lu DIFF %lu CLASS %d ", irq->irq, irq->load, + (irq->irq_count - irq->last_irq_count), irq->class); +@@ -338,6 +342,7 @@ void get_object_stat(struct topo_obj *object, void *data) + { + char **stats = (char **)data; + char *irq_data = NULL; ++ char *newptr = NULL; + size_t irqdlen; + + if (g_list_length(object->interrupts) > 0) { +@@ -355,13 +360,17 @@ void get_object_stat(struct topo_obj *object, void *data) + * This should be adjusted if the string in the sprintf is changed + */ + if (!*stats) { +- *stats = calloc(irqdlen + 31 + 11 + 20 + 11 + 1, 1); ++ newptr = calloc(irqdlen + 31 + 11 + 20 + 11 + 1, 1); + } else { +- *stats = realloc(*stats, strlen(*stats) + irqdlen + 31 + 11 + 20 + 11 + 1); ++ newptr = realloc(*stats, strlen(*stats) + irqdlen + 31 + 11 + 20 + 11 + 1); + } + +- if (!*stats) ++ if (!newptr) { ++ free(irq_data); + return; ++ } ++ ++ *stats = newptr; + + sprintf(*stats + strlen(*stats), "TYPE %d NUMBER %d LOAD %lu SAVE_MODE %d %s", + object->obj_type, object->number, object->load, +@@ -475,19 +484,23 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri + if (!strncmp(buff, "setup", strlen("setup"))) { + char banned[512]; + char *setup = calloc(strlen("SLEEP ") + 11 + 1, 1); ++ char *newptr = NULL; + if (!setup) + goto out_close; + snprintf(setup, strlen("SLEEP ") + 11 + 1, "SLEEP %d ", sleep_interval); + if(g_list_length(cl_banned_irqs) > 0) { +- for_each_irq(cl_banned_irqs, get_irq_data, setup); ++ for_each_irq(cl_banned_irqs, get_irq_data, &setup); + } + cpumask_scnprintf(banned, 512, banned_cpus); +- setup = realloc(setup, strlen(setup) + strlen(banned) + 7 + 1); +- if (!setup) +- goto out_close; ++ newptr = realloc(setup, strlen(setup) + strlen(banned) + 7 + 1); ++ if (!newptr) ++ goto out_free_setup; ++ ++ setup = newptr; + snprintf(setup + strlen(setup), strlen(banned) + 7 + 1, + "BANNED %s", banned); + send(sock, setup, strlen(setup), 0); ++out_free_setup: + free(setup); + } + +-- +2.19.1 diff --git a/fix-resource-leak-for-not-invoking-closedir-after-op.patch b/fix-resource-leak-for-not-invoking-closedir-after-op.patch new file mode 100644 index 0000000..5df1888 --- /dev/null +++ b/fix-resource-leak-for-not-invoking-closedir-after-op.patch @@ -0,0 +1,27 @@ +From d85897487c5f523ebc9ba8a56de911592703fed3 Mon Sep 17 00:00:00 2001 +From: liuchao173 +Date: Thu, 7 Nov 2019 09:27:55 +0000 +Subject: [PATCH 5/8] backport: fix resource leak for not invoking closedir() + after opendir() + +fix resource leak for not invoking closedir() after opendir() + +Signed-off-by: Yunfeng Ye +--- + ui/irqbalance-ui.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/ui/irqbalance-ui.c b/ui/irqbalance-ui.c +index 47dd5dc..4dfbd46 100644 +--- a/ui/irqbalance-ui.c ++++ b/ui/irqbalance-ui.c +@@ -418,6 +418,7 @@ int main(int argc, char **argv) + fclose(f); + } + } while((entry) && (irqbalance_pid == -1)); ++ closedir(dir); + } + if(irqbalance_pid == -1) { + printf("Unable to determine irqbalance PID\n"); +-- +2.19.1 diff --git a/fix-resource-leak-on-the-error-paths-in-main.patch b/fix-resource-leak-on-the-error-paths-in-main.patch new file mode 100644 index 0000000..5303715 --- /dev/null +++ b/fix-resource-leak-on-the-error-paths-in-main.patch @@ -0,0 +1,69 @@ +From 4bddf961e18f59b27301b73895c0ae3a6cde9b7b Mon Sep 17 00:00:00 2001 +From: liuchao173 +Date: Thu, 7 Nov 2019 09:38:21 +0000 +Subject: [PATCH 8/8] backport: fix resource leak on the error paths in main() + +Currently, both checking for core count < 2 and init_socket() fail, just +return directly, so lead to resource leak. + +Make it correct to free resource when on these situation. + +Signed-off-by: Yunfeng Ye +--- + irqbalance.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/irqbalance.c b/irqbalance.c +index cace4d8..5e5ef9b 100644 +--- a/irqbalance.c ++++ b/irqbalance.c +@@ -556,6 +556,7 @@ int init_socket() + int main(int argc, char** argv) + { + sigset_t sigset, old_sigset; ++ int ret = EXIT_SUCCESS; + + sigemptyset(&sigset); + sigaddset(&sigset,SIGINT); +@@ -636,7 +637,7 @@ int main(int argc, char** argv) + "single cpu. Shutting down\n"; + + log(TO_ALL, LOG_WARNING, "%s", msg); +- exit(EXIT_SUCCESS); ++ goto out; + } + + if (!foreground_mode) { +@@ -673,7 +674,8 @@ int main(int argc, char** argv) + parse_proc_stat(); + + if (init_socket()) { +- return EXIT_FAILURE; ++ ret = EXIT_FAILURE; ++ goto out; + } + main_loop = g_main_loop_new(NULL, FALSE); + int *last_interval = &sleep_interval; +@@ -682,6 +684,7 @@ int main(int argc, char** argv) + + g_main_loop_quit(main_loop); + ++out: + free_object_tree(); + free_cl_opts(); + +@@ -689,9 +692,10 @@ int main(int argc, char** argv) + if (!foreground_mode && pidfile) + unlink(pidfile); + /* Remove socket */ +- close(socket_fd); ++ if (socket_fd > 0) ++ close(socket_fd); + if (socket_name[0]) + unlink(socket_name); + +- return EXIT_SUCCESS; ++ return ret; + } +-- +2.19.1 diff --git a/fix-the-problem-of-banmod-that-memory-is-freed-befor.patch b/fix-the-problem-of-banmod-that-memory-is-freed-befor.patch new file mode 100644 index 0000000..ee735b0 --- /dev/null +++ b/fix-the-problem-of-banmod-that-memory-is-freed-befor.patch @@ -0,0 +1,66 @@ +From 559980c2e1dea1082949c17d52794c43c35f40ce Mon Sep 17 00:00:00 2001 +From: liuchao173 +Date: Thu, 7 Nov 2019 09:35:42 +0000 +Subject: [PATCH 7/8] backport: fix the problem of banmod that memory is freed + before using + +Currently strdupa() is used to allocate memory for irq_info's name in +collect_full_irq_list(), we know that it allocate memory from stack, +when the invoking function return, the memory will be freed. so if the +irq_info's name is invalid, it will lead to check_for_module_ban() no +correct. + + check_for_irq_ban + check_for_module_ban(res->name) // res->name is not valid + +Use strdup() instead of strdupa(), and free the memory of irq_info's +name before freeing the irq_info. + +Signed-off-by: Yunfeng Ye +--- + classify.c | 9 ++++++++- + procinterrupts.c | 2 +- + 2 files changed, 9 insertions(+), 2 deletions(-) + +diff --git a/classify.c b/classify.c +index 3136fc3..ed3f3ba 100644 +--- a/classify.c ++++ b/classify.c +@@ -748,6 +748,13 @@ static void add_missing_irq(struct irq_info *info, void *attr) + add_new_irq(info->irq, info, proc_interrupts); + } + ++static void free_tmp_irqs(gpointer data) ++{ ++ struct irq_info *info = data; ++ ++ free(info->name); ++ free(info); ++} + + void rebuild_irq_db(void) + { +@@ -777,7 +784,7 @@ void rebuild_irq_db(void) + + for_each_irq(tmp_irqs, add_missing_irq, interrupts_db); + +- g_list_free_full(tmp_irqs, free); ++ g_list_free_full(tmp_irqs, free_tmp_irqs); + + } + +diff --git a/procinterrupts.c b/procinterrupts.c +index 87fae2f..11fe1bc 100644 +--- a/procinterrupts.c ++++ b/procinterrupts.c +@@ -228,7 +228,7 @@ GList* collect_full_irq_list() + info->class = IRQ_OTHER; + #endif + } +- info->name = strdupa(irq_mod); ++ info->name = strdup(irq_mod); + tmp_list = g_list_append(tmp_list, info); + } + free(savedline); +-- +2.19.1 diff --git a/free-the-memory-when-getline-fail-in-add_one_node.patch b/free-the-memory-when-getline-fail-in-add_one_node.patch new file mode 100644 index 0000000..0ff2294 --- /dev/null +++ b/free-the-memory-when-getline-fail-in-add_one_node.patch @@ -0,0 +1,35 @@ +From 0f7965c9cc3963c4dbfa7b61820ff973ef5da539 Mon Sep 17 00:00:00 2001 +From: liuchao173 +Date: Thu, 7 Nov 2019 09:22:15 +0000 +Subject: [PATCH 3/8] backport: free the memory when getline() fail in + add_one_node() + +when getline() fail, the memory still need to be freed. + +Signed-off-by: Yunfeng Ye +--- + numa.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/numa.c b/numa.c +index f0b1a98..542e1f4 100644 +--- a/numa.c ++++ b/numa.c +@@ -74,12 +74,11 @@ static void add_one_node(const char *nodename) + cpus_clear(new->mask); + } else { + ret = getline(&cpustr, &blen, f); +- if (ret <= 0) { ++ if (ret <= 0) + cpus_clear(new->mask); +- } else { ++ else + cpumask_parse_user(cpustr, ret, new->mask); +- free(cpustr); +- } ++ free(cpustr); + } + fclose(f); + new->obj_type = OBJ_TYPE_NODE; +-- +2.19.1 diff --git a/getline-clean-up-freeing-of-lines-from-getline.patch b/getline-clean-up-freeing-of-lines-from-getline.patch new file mode 100644 index 0000000..87f85b9 --- /dev/null +++ b/getline-clean-up-freeing-of-lines-from-getline.patch @@ -0,0 +1,106 @@ +From 9fd716f6627c0bb3b63cef94780e20101d9616c3 Mon Sep 17 00:00:00 2001 +From: liuchao173 +Date: Thu, 7 Nov 2019 09:19:33 +0000 +Subject: [PATCH 2/8] backport: + getline-clean-up-freeing-of-lines-from-getline.patch + +It was noted that several calls to getline failed to free the resultant line, +which the man page for getline says to do even if the call fails. Clean that up +here + +And while we're at it, merge some of the free calls so they're common to a +function where they can be, and not strewn all over the place + +Signed-off-by: Neil Horman +--- + cputree.c | 29 +++++++++++++++++------------ + 1 file changed, 17 insertions(+), 12 deletions(-) + +diff --git a/cputree.c b/cputree.c +index 5551784..91919ec 100644 +--- a/cputree.c ++++ b/cputree.c +@@ -91,10 +91,10 @@ static void setup_banned_cpus(void) + if (getline(&line, &size, file) > 0) { + if (strlen(line) && line[0] != '\n') + cpulist_parse(line, strlen(line), isolated_cpus); +- free(line); +- line = NULL; +- size = 0; + } ++ free(line); ++ line = NULL; ++ size = 0; + fclose(file); + } + +@@ -103,10 +103,10 @@ static void setup_banned_cpus(void) + if (getline(&line, &size, file) > 0) { + if (strlen(line) && line[0] != '\n') + cpulist_parse(line, strlen(line), nohz_full); +- free(line); +- line = NULL; +- size = 0; + } ++ free(line); ++ line = NULL; ++ size = 0; + fclose(file); + } + +@@ -271,6 +271,7 @@ static void do_one_cpu(char *path) + int nodeid; + int packageid = 0; + unsigned int max_cache_index, cache_index, cache_stat; ++ int ret = 1; + + /* skip offline cpus */ + snprintf(new_path, ADJ_SIZE(path,"/online"), "%s/online", path); +@@ -278,14 +279,12 @@ static void do_one_cpu(char *path) + if (file) { + char *line = NULL; + size_t size = 0; +- if (getline(&line, &size, file)==0) +- return; ++ if (getline(&line, &size, file)>0) ++ ret = (line && line[0]=='0') ? 1 : 0; + fclose(file); +- if (line && line[0]=='0') { +- free(line); +- return; +- } + free(line); ++ if (ret) ++ return; + } + + cpu = calloc(sizeof(struct topo_obj), 1); +@@ -327,6 +326,8 @@ static void do_one_cpu(char *path) + cpumask_parse_user(line, strlen(line), package_mask); + fclose(file); + free(line); ++ line = NULL; ++ size = 0; + } + /* try to read the package id */ + snprintf(new_path, ADJ_SIZE(path, "/topology/physical_package_id"), +@@ -339,6 +340,8 @@ static void do_one_cpu(char *path) + packageid = strtoul(line, NULL, 10); + fclose(file); + free(line); ++ line = NULL; ++ size = 0; + } + + /* try to read the cache mask; if it doesn't exist assume solitary */ +@@ -372,6 +375,8 @@ static void do_one_cpu(char *path) + cpumask_parse_user(line, strlen(line), cache_mask); + fclose(file); + free(line); ++ line = NULL; ++ size = 0; + } + } + +-- +2.19.1 diff --git a/prevent-NULL-pointer-dereference-when-memory-allocat.patch b/prevent-NULL-pointer-dereference-when-memory-allocat.patch new file mode 100644 index 0000000..c500928 --- /dev/null +++ b/prevent-NULL-pointer-dereference-when-memory-allocat.patch @@ -0,0 +1,109 @@ +From f37fe357b21ffd7ab210b088c36300d9562406cb Mon Sep 17 00:00:00 2001 +From: liuchao173 +Date: Thu, 7 Nov 2019 09:26:30 +0000 +Subject: [PATCH 4/8] backport: prevent NULL pointer dereference when memory + allocation failure + +There are several places where memory allocation does not check return +values, adding null pointer checks. + +Signed-off-by: Yunfeng Ye +--- + cputree.c | 2 ++ + irqbalance.c | 20 ++++++++++++++++++++ + 2 files changed, 22 insertions(+) + +diff --git a/cputree.c b/cputree.c +index 91919ec..9cd2db8 100644 +--- a/cputree.c ++++ b/cputree.c +@@ -432,6 +432,8 @@ static void dump_irq(struct irq_info *info, void *data) + int i; + char * indent = malloc (sizeof(char) * (spaces + 1)); + ++ if (!indent) ++ return; + for ( i = 0; i < spaces; i++ ) + indent[i] = log_indent[0]; + +diff --git a/irqbalance.c b/irqbalance.c +index 93e4909..c9378d0 100644 +--- a/irqbalance.c ++++ b/irqbalance.c +@@ -326,6 +326,9 @@ void get_irq_data(struct irq_info *irq, void *data) + else + *irqdata = realloc(*irqdata, strlen(*irqdata) + 24 + 1 + 11 + 20 + 20 + 11); + ++ if (!*irqdata) ++ return; ++ + sprintf(*irqdata + strlen(*irqdata), + "IRQ %d LOAD %lu DIFF %lu CLASS %d ", irq->irq, irq->load, + (irq->irq_count - irq->last_irq_count), irq->class); +@@ -357,6 +360,9 @@ void get_object_stat(struct topo_obj *object, void *data) + *stats = realloc(*stats, strlen(*stats) + irqdlen + 31 + 11 + 20 + 11 + 1); + } + ++ if (!*stats) ++ return; ++ + sprintf(*stats + strlen(*stats), "TYPE %d NUMBER %d LOAD %lu SAVE_MODE %d %s", + object->obj_type, object->number, object->load, + object->powersave_mode, irq_data ? irq_data : ""); +@@ -393,6 +399,10 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri + goto out_close; + } + cmsg = CMSG_FIRSTHDR(&msg); ++ if (!cmsg) { ++ log(TO_ALL, LOG_WARNING, "Connection no memory.\n"); ++ goto out_close; ++ } + if ((cmsg->cmsg_level == SOL_SOCKET) && + (cmsg->cmsg_type == SCM_CREDENTIALS)) { + struct ucred *credentials = (struct ucred *) CMSG_DATA(cmsg); +@@ -416,6 +426,8 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri + strlen("sleep ")))) { + char *sleep_string = malloc( + sizeof(char) * (recv_size - strlen("settings sleep "))); ++ if (!sleep_string) ++ goto out_close; + strncpy(sleep_string, buff + strlen("settings sleep "), + recv_size - strlen("settings sleep ")); + int new_iterval = strtoul(sleep_string, NULL, 10); +@@ -428,6 +440,8 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri + char *end; + char *irq_string = malloc( + sizeof(char) * (recv_size - strlen("settings ban irqs "))); ++ if (!irq_string) ++ goto out_close; + strncpy(irq_string, buff + strlen("settings ban irqs "), + recv_size - strlen("settings ban irqs ")); + g_list_free_full(cl_banned_irqs, free); +@@ -446,6 +460,8 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri + strlen("cpus")))) { + char *cpu_ban_string = malloc( + sizeof(char) * (recv_size - strlen("settings cpus "))); ++ if (!cpu_ban_string) ++ goto out_close; + strncpy(cpu_ban_string, buff + strlen("settings cpus "), + recv_size - strlen("settings cpus ")); + banned_cpumask_from_ui = strtok(cpu_ban_string, " "); +@@ -459,12 +475,16 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri + if (!strncmp(buff, "setup", strlen("setup"))) { + char banned[512]; + char *setup = calloc(strlen("SLEEP ") + 11 + 1, 1); ++ if (!setup) ++ goto out_close; + snprintf(setup, strlen("SLEEP ") + 11 + 1, "SLEEP %d ", sleep_interval); + if(g_list_length(cl_banned_irqs) > 0) { + for_each_irq(cl_banned_irqs, get_irq_data, setup); + } + cpumask_scnprintf(banned, 512, banned_cpus); + setup = realloc(setup, strlen(setup) + strlen(banned) + 7 + 1); ++ if (!setup) ++ goto out_close; + snprintf(setup + strlen(setup), strlen(banned) + 7 + 1, + "BANNED %s", banned); + send(sock, setup, strlen(setup), 0); +-- +2.19.1