Package init

This commit is contained in:
dogsheng 2019-11-19 14:11:38 +08:00
parent 02658ac8c8
commit deb8249f89
9 changed files with 611 additions and 0 deletions

View File

@ -0,0 +1,29 @@
From 7dafc4d5c8d8229f107c90d97f33a4094eb89c6e Mon Sep 17 00:00:00 2001
From: liuchao173 <liuchao173@huawei.com>
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 <yeyunfeng@huawei.com>
---
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

View File

@ -0,0 +1,64 @@
From f4d052d7b210612a7ffbdd7c3cfbce213c9a0e21 Mon Sep 17 00:00:00 2001
From: liuchao173 <liuchao173@huawei.com>
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

View File

@ -0,0 +1,106 @@
From 22a40e9d0dd59ee58ff06d2b6360007e046d608f Mon Sep 17 00:00:00 2001
From: liuchao173 <liuchao173@huawei.com>
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 <yeyunfeng@huawei.com>
---
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

View File

@ -0,0 +1,27 @@
From d85897487c5f523ebc9ba8a56de911592703fed3 Mon Sep 17 00:00:00 2001
From: liuchao173 <liuchao173@huawei.com>
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 <yeyunfeng@huawei.com>
---
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

View File

@ -0,0 +1,69 @@
From 4bddf961e18f59b27301b73895c0ae3a6cde9b7b Mon Sep 17 00:00:00 2001
From: liuchao173 <liuchao173@huawei.com>
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 <yeyunfeng@huawei.com>
---
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

View File

@ -0,0 +1,66 @@
From 559980c2e1dea1082949c17d52794c43c35f40ce Mon Sep 17 00:00:00 2001
From: liuchao173 <liuchao173@huawei.com>
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 <yeyunfeng@huawei.com>
---
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

View File

@ -0,0 +1,35 @@
From 0f7965c9cc3963c4dbfa7b61820ff973ef5da539 Mon Sep 17 00:00:00 2001
From: liuchao173 <liuchao173@huawei.com>
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 <yeyunfeng@huawei.com>
---
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

View File

@ -0,0 +1,106 @@
From 9fd716f6627c0bb3b63cef94780e20101d9616c3 Mon Sep 17 00:00:00 2001
From: liuchao173 <liuchao173@huawei.com>
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 <nhorman@tuxdriver.com>
---
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

View File

@ -0,0 +1,109 @@
From f37fe357b21ffd7ab210b088c36300d9562406cb Mon Sep 17 00:00:00 2001
From: liuchao173 <liuchao173@huawei.com>
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 <yeyunfeng@huawei.com>
---
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