From 83ea625615b6b299dc44fccc5c53f9d174bad0b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Nykr=C3=BDn?= Date: Tue, 5 Mar 2024 16:25:27 +0100 Subject: [PATCH 1/4] fix(dracut-util): memory leak Error: RESOURCE_LEAK (CWE-772): src/util/util.c:188: alloc_fn: Storage is returned from allocation function "strdup". src/util/util.c:188: var_assign: Assigning: "cmdline" = storage returned from "strdup(p)". src/util/util.c:209: identity_transfer: Passing "cmdline" as argument 1 to function "next_arg", which returns an offset off that argument. src/util/util.c:209: identity_transfer: Passing "cmdline" as argument 1 to function "next_arg", which sets "key" to an offset off that argument. src/util/util.c:209: identity_transfer: Passing "cmdline" as argument 1 to function "next_arg", which sets "value" to an offset off that argument. src/util/util.c:209: var_assign: Assigning: "cmdline" = storage returned from "next_arg(cmdline, &key, &value)". src/util/util.c:210: noescape: Resource "key" is not freed or pointed-to in "strcmp". src/util/util.c:219: leaked_storage: Variable "value" going out of scope leaks the storage it points to. src/util/util.c:219: leaked_storage: Variable "key" going out of scope leaks the storage it points to. src/util/util.c:209: identity_transfer: Passing "cmdline" as argument 1 to function "next_arg", which returns an offset off that argument. src/util/util.c:209: identity_transfer: Passing "cmdline" as argument 1 to function "next_arg", which sets "key" to an offset off that argument. src/util/util.c:209: identity_transfer: Passing "cmdline" as argument 1 to function "next_arg", which sets "value" to an offset off that argument. src/util/util.c:209: var_assign: Assigning: "cmdline" = storage returned from "next_arg(cmdline, &key, &value)". src/util/util.c:210: noescape: Resource "key" is not freed or pointed-to in "strcmp". src/util/util.c:219: leaked_storage: Variable "value" going out of scope leaks the storage it points to. src/util/util.c:219: leaked_storage: Variable "key" going out of scope leaks the storage it points to. src/util/util.c:238: leaked_storage: Variable "cmdline" going out of scope leaks the storage it points to. --- src/util/util.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/util/util.c b/src/util/util.c index b3498df6cd..4558a20e1d 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -180,12 +180,12 @@ static int getarg(int argc, char **argv) char *end_value = NULL; bool bool_value = false; char *cmdline = NULL; + char *cmdline_iter = NULL; char *p = getenv("CMDLINE"); if (p == NULL) { usage(GETARG, EXIT_FAILURE, "CMDLINE env not set"); } - cmdline = strdup(p); if (argc != 2) { usage(GETARG, EXIT_FAILURE, "Number of arguments invalid"); @@ -204,9 +204,16 @@ static int getarg(int argc, char **argv) if (strlen(search_key) == 0) usage(GETARG, EXIT_FAILURE, "search key undefined"); + cmdline = strdup(p); + if (cmdline == NULL) { + fprintf(stderr, "ERROR: out of memory.\n"); + exit(EXIT_FAILURE); + } + cmdline_iter = cmdline; + do { char *key = NULL, *value = NULL; - cmdline = next_arg(cmdline, &key, &value); + cmdline = next_arg(cmdline_iter, &key, &value); if (strcmp(key, search_key) == 0) { if (value) { end_value = value; @@ -216,7 +223,9 @@ static int getarg(int argc, char **argv) bool_value = true; } } - } while (cmdline[0]); + } while (cmdline_iter[0]); + + free(cmdline); if (search_value) { if (end_value && strcmp(end_value, search_value) == 0) { From 6e7c1c02b872d8c494d78f1c0b623d36aa27ae24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Nykr=C3=BDn?= Date: Tue, 5 Mar 2024 16:26:52 +0100 Subject: [PATCH 2/4] fix(dracut-install): buffer overrun Error: OVERRUN (CWE-119): src/install/dracut-install.c:464: identity_transfer: Passing "4097UL" as argument 3 to function "readlink", which returns that argument. [Note: The source code implementation of the function has been overridden by a builtin model.] src/install/dracut-install.c:464: assignment: Assigning: "linksz" = "readlink(fullsrcpath, linktarget, 4097UL)". The value of "linksz" is now 4097. src/install/dracut-install.c:467: overrun-local: Overrunning array "linktarget" of 4097 bytes at byte offset 4097 using index "linksz" (which evaluates to 4097). 465| if (linksz < 0) 466| return NULL; 467|-> linktarget[linksz] = '\0'; 468| 469| log_debug("get_real_file: readlink('%s') returns '%s'", fullsrcpath, linktarget); --- src/install/dracut-install.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/install/dracut-install.c b/src/install/dracut-install.c index 485143a58a..227321b9f7 100644 --- a/src/install/dracut-install.c +++ b/src/install/dracut-install.c @@ -473,7 +473,7 @@ static char *get_real_file(const char *src, bool fullyresolve) return NULL; } - linksz = readlink(fullsrcpath, linktarget, sizeof(linktarget)); + linksz = readlink(fullsrcpath, linktarget, sizeof(linktarget) - 1); if (linksz < 0) return NULL; linktarget[linksz] = '\0'; From 88918bf991f8144df8625c195fcc4591829afbf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Nykr=C3=BDn?= Date: Tue, 5 Mar 2024 16:54:01 +0100 Subject: [PATCH 3/4] fix(dracut-util): memory leak "Error: RESOURCE_LEAK (CWE-772): src/util/util.c:252: alloc_fn: Storage is returned from allocation function ""strdup"". src/util/util.c:252: var_assign: Assigning: ""cmdline"" = storage returned from ""strdup(p)"". src/util/util.c:273: identity_transfer: Passing ""cmdline"" as argument 1 to function ""next_arg"", which returns an offset off that argument. src/util/util.c:273: identity_transfer: Passing ""cmdline"" as argument 1 to function ""next_arg"", which sets ""key"" to an offset off that argument. src/util/util.c:273: identity_transfer: Passing ""cmdline"" as argument 1 to function ""next_arg"", which sets ""value"" to an offset off that argument. src/util/util.c:273: var_assign: Assigning: ""cmdline"" = storage returned from ""next_arg(cmdline, &key, &value)"". src/util/util.c:274: noescape: Resource ""key"" is not freed or pointed-to in ""strcmp"". src/util/util.c:289: leaked_storage: Variable ""value"" going out of scope leaks the storage it points to. src/util/util.c:289: leaked_storage: Variable ""key"" going out of scope leaks the storage it points to. src/util/util.c:273: identity_transfer: Passing ""cmdline"" as argument 1 to function ""next_arg"", which returns an offset off that argument. src/util/util.c:273: identity_transfer: Passing ""cmdline"" as argument 1 to function ""next_arg"", which sets ""key"" to an offset off that argument. src/util/util.c:273: identity_transfer: Passing ""cmdline"" as argument 1 to function ""next_arg"", which sets ""value"" to an offset off that argument. src/util/util.c:273: var_assign: Assigning: ""cmdline"" = storage returned from ""next_arg(cmdline, &key, &value)"". src/util/util.c:274: noescape: Resource ""key"" is not freed or pointed-to in ""strcmp"". src/util/util.c:289: leaked_storage: Variable ""value"" going out of scope leaks the storage it points to. src/util/util.c:289: leaked_storage: Variable ""key"" going out of scope leaks the storage it points to. src/util/util.c:290: leaked_storage: Variable ""cmdline"" going out of scope leaks the storage it points to. 288| } 289| } while (cmdline[0]); 290|-> return found_value ? EXIT_SUCCESS : EXIT_FAILURE; 291| } 292| " --- src/util/util.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/util/util.c b/src/util/util.c index 4558a20e1d..ba88350986 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -253,16 +253,15 @@ static int getargs(int argc, char **argv) char *search_value; bool found_value = false; char *cmdline = NULL; + char *cmdline_iter = NULL; char *p = getenv("CMDLINE"); if (p == NULL) { usage(GETARGS, EXIT_FAILURE, "CMDLINE env not set"); } - cmdline = strdup(p); - if (argc != 2) { + if (argc != 2) usage(GETARGS, EXIT_FAILURE, "Number of arguments invalid"); - } search_key = argv[1]; @@ -277,9 +276,16 @@ static int getargs(int argc, char **argv) if (strlen(search_key) == 0) usage(GETARGS, EXIT_FAILURE, "search key undefined"); + cmdline = strdup(p); + if (cmdline == NULL) { + fprintf(stderr, "ERROR: out of memory.\n"); + exit(EXIT_FAILURE); + } + cmdline_iter = cmdline; + do { char *key = NULL, *value = NULL; - cmdline = next_arg(cmdline, &key, &value); + cmdline = next_arg(cmdline_iter, &key, &value); if (strcmp(key, search_key) == 0) { if (search_value) { if (strcmp(value, search_value) == 0) { @@ -295,7 +301,10 @@ static int getargs(int argc, char **argv) found_value = true; } } - } while (cmdline[0]); + } while (cmdline_iter[0]); + + free(cmdline_iter); + return found_value ? EXIT_SUCCESS : EXIT_FAILURE; } From 9d1742a36eb1f60b985a659a47b1b9ed76096647 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Nykr=C3=BDn?= Date: Tue, 5 Mar 2024 17:11:02 +0100 Subject: [PATCH 4/4] fix(dracut-install): memory leak "Error: RESOURCE_LEAK (CWE-772): src/install/dracut-install.c:1135: alloc_fn: Storage is returned from allocation function ""strv_split"". src/install/dracut-install.c:1135: var_assign: Assigning: ""firmwaredirs"" = storage returned from ""strv_split(optarg, "":"")"". src/install/dracut-install.c:1135: overwrite_var: Overwriting ""firmwaredirs"" in ""firmwaredirs = strv_split(optarg, "":"")"" leaks the storage that ""firmwaredirs"" points to. 1133| break; 1134| case ARG_FIRMWAREDIRS: 1135|-> firmwaredirs = strv_split(optarg, "":""); 1136| break; 1137| case 'f':" --- src/install/dracut-install.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/install/dracut-install.c b/src/install/dracut-install.c index 227321b9f7..8c0e482f40 100644 --- a/src/install/dracut-install.c +++ b/src/install/dracut-install.c @@ -1140,6 +1140,7 @@ static int parse_argv(int argc, char *argv[]) kerneldir = optarg; break; case ARG_FIRMWAREDIRS: + strv_free(firmwaredirs); firmwaredirs = strv_split(optarg, ":"); break; case 'f':