diff mbox series

[BlueZ,v2,02/11] shared/shell: Free memory allocated by wordexp()

Message ID 20240705085935.1255725-3-hadess@hadess.net (mailing list archive)
State New, archived
Headers show
Series Fix a number of static analysis issues #5 | expand

Checks

Context Check Description
tedd_an/pre-ci_am success Success
tedd_an/CheckPatch success CheckPatch PASS
tedd_an/GitLint fail WARNING: I3 - ignore-body-lines: gitlint will be switching from using Python regex 'match' (match beginning) to 'search' (match anywhere) semantics. Please review your ignore-body-lines.regex option accordingly. To remove this warning, set general.regex-style-search=True. More details: https://jorisroovers.github.io/gitlint/configuration/#regex-style-search 4: B1 Line exceeds max length (111>80): "bluez-5.76/src/shared/shell.c:519:2: alloc_arg: "parse_args" allocates memory that is stored into "w.we_wordv"." 5: B1 Line exceeds max length (126>80): "bluez-5.76/src/shared/shell.c:523:3: leaked_storage: Variable "w" going out of scope leaks the storage "w.we_wordv" points to." 6: B3 Line contains hard tab characters (\t): "521| "Unable to parse mandatory command arguments: %s", man );" 7: B3 Line contains hard tab characters (\t): "522| free(man);" 8: B3 Line contains hard tab characters (\t): "523|-> return -EINVAL;" 9: B3 Line contains hard tab characters (\t): "524| }" 13: B1 Line exceeds max length (109>80): "bluez-5.76/src/shared/shell.c:1113:3: alloc_arg: "wordexp" allocates memory that is stored into "w.we_wordv"." 14: B1 Line exceeds max length (127>80): "bluez-5.76/src/shared/shell.c:1114:4: leaked_storage: Variable "w" going out of scope leaks the storage "w.we_wordv" points to." 16: B3 Line contains hard tab characters (\t): "1113| if (wordexp(rl_line_buffer, &w, WRDE_NOCMD))" 17: B3 Line contains hard tab characters (\t): "1114|-> return NULL;" 19: B3 Line contains hard tab characters (\t): "1116| matches = menu_completion(default_menu, text, w.we_wordc," 22: B1 Line exceeds max length (109>80): "bluez-5.76/src/shared/shell.c:1412:2: alloc_arg: "wordexp" allocates memory that is stored into "w.we_wordv"." 23: B1 Line exceeds max length (127>80): "bluez-5.76/src/shared/shell.c:1415:3: leaked_storage: Variable "w" going out of scope leaks the storage "w.we_wordv" points to." 24: B3 Line contains hard tab characters (\t): "1413| switch (err) {" 25: B3 Line contains hard tab characters (\t): "1414| case WRDE_BADCHAR:" 26: B3 Line contains hard tab characters (\t): "1415|-> return -EBADMSG;" 27: B3 Line contains hard tab characters (\t): "1416| case WRDE_BADVAL:" 28: B3 Line contains hard tab characters (\t): "1417| case WRDE_SYNTAX:" 31: B1 Line exceeds max length (109>80): "bluez-5.76/src/shared/shell.c:1412:2: alloc_arg: "wordexp" allocates memory that is stored into "w.we_wordv"." 32: B1 Line exceeds max length (127>80): "bluez-5.76/src/shared/shell.c:1418:3: leaked_storage: Variable "w" going out of scope leaks the storage "w.we_wordv" points to." 33: B3 Line contains hard tab characters (\t): "1416| case WRDE_BADVAL:" 34: B3 Line contains hard tab characters (\t): "1417| case WRDE_SYNTAX:" 35: B3 Line contains hard tab characters (\t): "1418|-> return -EINVAL;" 36: B3 Line contains hard tab characters (\t): "1419| case WRDE_NOSPACE:" 37: B3 Line contains hard tab characters (\t): "1420| return -ENOMEM;" 40: B1 Line exceeds max length (109>80): "bluez-5.76/src/shared/shell.c:1412:2: alloc_arg: "wordexp" allocates memory that is stored into "w.we_wordv"." 41: B1 Line exceeds max length (127>80): "bluez-5.76/src/shared/shell.c:1420:3: leaked_storage: Variable "w" going out of scope leaks the storage "w.we_wordv" points to." 42: B3 Line contains hard tab characters (\t): "1418| return -EINVAL;" 43: B3 Line contains hard tab characters (\t): "1419| case WRDE_NOSPACE:" 44: B3 Line contains hard tab characters (\t): "1420|-> return -ENOMEM;" 45: B3 Line contains hard tab characters (\t): "1421| case WRDE_CMDSUB:" 46: B3 Line contains hard tab characters (\t): "1422| if (wordexp(input, &w, 0))" 49: B1 Line exceeds max length (109>80): "bluez-5.76/src/shared/shell.c:1422:3: alloc_arg: "wordexp" allocates memory that is stored into "w.we_wordv"." 50: B1 Line exceeds max length (127>80): "bluez-5.76/src/shared/shell.c:1423:4: leaked_storage: Variable "w" going out of scope leaks the storage "w.we_wordv" points to." 51: B3 Line contains hard tab characters (\t): "1421| case WRDE_CMDSUB:" 52: B3 Line contains hard tab characters (\t): "1422| if (wordexp(input, &w, 0))" 53: B3 Line contains hard tab characters (\t): "1423|-> return -ENOEXEC;" 54: B3 Line contains hard tab characters (\t): "1424| break;" 55: B3 Line contains hard tab characters (\t): "1425| };"
tedd_an/IncrementalBuild success Incremental Build PASS

Commit Message

Bastien Nocera July 5, 2024, 8:57 a.m. UTC
Error: RESOURCE_LEAK (CWE-772): [#def38] [important]
bluez-5.76/src/shared/shell.c:519:2: alloc_arg: "parse_args" allocates memory that is stored into "w.we_wordv".
bluez-5.76/src/shared/shell.c:523:3: leaked_storage: Variable "w" going out of scope leaks the storage "w.we_wordv" points to.
521|			"Unable to parse mandatory command arguments: %s", man );
522|		free(man);
523|->		return -EINVAL;
524|	}
525|

Error: RESOURCE_LEAK (CWE-772): [#def40] [important]
bluez-5.76/src/shared/shell.c:1113:3: alloc_arg: "wordexp" allocates memory that is stored into "w.we_wordv".
bluez-5.76/src/shared/shell.c:1114:4: leaked_storage: Variable "w" going out of scope leaks the storage "w.we_wordv" points to.
1112|
1113|			if (wordexp(rl_line_buffer, &w, WRDE_NOCMD))
1114|->				return NULL;
1115|
1116|			matches = menu_completion(default_menu, text, w.we_wordc,

Error: RESOURCE_LEAK (CWE-772): [#def42] [important]
bluez-5.76/src/shared/shell.c:1412:2: alloc_arg: "wordexp" allocates memory that is stored into "w.we_wordv".
bluez-5.76/src/shared/shell.c:1415:3: leaked_storage: Variable "w" going out of scope leaks the storage "w.we_wordv" points to.
1413|		switch (err) {
1414|		case WRDE_BADCHAR:
1415|->			return -EBADMSG;
1416|		case WRDE_BADVAL:
1417|		case WRDE_SYNTAX:

Error: RESOURCE_LEAK (CWE-772): [#def43] [important]
bluez-5.76/src/shared/shell.c:1412:2: alloc_arg: "wordexp" allocates memory that is stored into "w.we_wordv".
bluez-5.76/src/shared/shell.c:1418:3: leaked_storage: Variable "w" going out of scope leaks the storage "w.we_wordv" points to.
1416|		case WRDE_BADVAL:
1417|		case WRDE_SYNTAX:
1418|->			return -EINVAL;
1419|		case WRDE_NOSPACE:
1420|			return -ENOMEM;

Error: RESOURCE_LEAK (CWE-772): [#def44] [important]
bluez-5.76/src/shared/shell.c:1412:2: alloc_arg: "wordexp" allocates memory that is stored into "w.we_wordv".
bluez-5.76/src/shared/shell.c:1420:3: leaked_storage: Variable "w" going out of scope leaks the storage "w.we_wordv" points to.
1418|			return -EINVAL;
1419|		case WRDE_NOSPACE:
1420|->			return -ENOMEM;
1421|		case WRDE_CMDSUB:
1422|			if (wordexp(input, &w, 0))

Error: RESOURCE_LEAK (CWE-772): [#def45] [important]
bluez-5.76/src/shared/shell.c:1422:3: alloc_arg: "wordexp" allocates memory that is stored into "w.we_wordv".
bluez-5.76/src/shared/shell.c:1423:4: leaked_storage: Variable "w" going out of scope leaks the storage "w.we_wordv" points to.
1421|		case WRDE_CMDSUB:
1422|			if (wordexp(input, &w, 0))
1423|->				return -ENOEXEC;
1424|			break;
1425|		};
---
 src/shared/shell.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

Comments

Bastien Nocera July 18, 2024, 12:46 p.m. UTC | #1
On Fri, 2024-07-05 at 10:57 +0200, Bastien Nocera wrote:
<snip>
> diff --git a/src/shared/shell.c b/src/shared/shell.c
> index add4fa131c7a..e8f75124f167 100644
> --- a/src/shared/shell.c
> +++ b/src/shared/shell.c
> @@ -452,13 +452,23 @@ static void shell_print_menu_zsh_complete(void)
>  	}
>  }
>  
> +static int _wordexp(const char *restrict s, wordexp_t *restrict p,
> int flags)
> +{
> +	int ret;
> +
> +	ret = wordexp(s, p, flags);
> +	if (ret != 0)
> +		wordfree(p);
> +	return ret;
> +}
> +
>  static int parse_args(char *arg, wordexp_t *w, char *del, int flags)
>  {
>  	char *str;
>  
>  	str = strdelimit(arg, del, '"');
>  
> -	if (wordexp(str, w, flags)) {
> +	if (_wordexp(str, w, flags) != 0) {
>  		free(str);
>  		return -EINVAL;
>  	}

Any reason not to pick this patch up?

You can see here:
https://sourceware.org/git/?p=glibc.git;a=blob;f=posix/wordexp.c;h=a7362ef31b05280001e961c3a630e953110b7397;hb=HEAD#l2203
that wordexp() will return without freeing we_wordv if there's an error
and the WRDE_APPEND flag isn't set.

Let me know if you want me to re-spin this one with a different style,
or want me to add the info above to the commit message.

Cheers

> @@ -537,7 +547,7 @@ static int cmd_exec(const struct
> bt_shell_menu_entry *entry,
>  		goto fail;
>  	}
>  
> -	flags |= WRDE_APPEND;
> +	flags |= WRDE_APPEND | WRDE_REUSE;
>  	opt = strdup(entry->arg + len + 1);
>  
>  optional:
> @@ -1043,7 +1053,7 @@ static char **args_completion(const struct
> bt_shell_menu_entry *entry, int argc,
>  	args.we_offs = 0;
>  	wordfree(&args);
>  
> -	if (wordexp(str, &args, WRDE_NOCMD))
> +	if (_wordexp(str, &args, WRDE_NOCMD))
>  		goto done;
>  
>  	rl_completion_display_matches_hook = NULL;
> @@ -1115,7 +1125,7 @@ static char **shell_completion(const char
> *text, int start, int end)
>  	if (start > 0) {
>  		wordexp_t w;
>  
> -		if (wordexp(rl_line_buffer, &w, WRDE_NOCMD))
> +		if (_wordexp(rl_line_buffer, &w, WRDE_NOCMD))
>  			return NULL;
>  
>  		matches = menu_completion(default_menu, text,
> w.we_wordc,
> @@ -1416,7 +1426,7 @@ int bt_shell_exec(const char *input)
>  	if (data.monitor)
>  		bt_log_printf(0xffff, data.name, LOG_INFO, "%s",
> input);
>  
> -	err = wordexp(input, &w, WRDE_NOCMD);
> +	err = _wordexp(input, &w, WRDE_NOCMD);
>  	switch (err) {
>  	case WRDE_BADCHAR:
>  		return -EBADMSG;
> @@ -1426,7 +1436,7 @@ int bt_shell_exec(const char *input)
>  	case WRDE_NOSPACE:
>  		return -ENOMEM;
>  	case WRDE_CMDSUB:
> -		if (wordexp(input, &w, 0))
> +		if (_wordexp(input, &w, 0))
>  			return -ENOEXEC;
>  		break;
>  	};
diff mbox series

Patch

diff --git a/src/shared/shell.c b/src/shared/shell.c
index add4fa131c7a..e8f75124f167 100644
--- a/src/shared/shell.c
+++ b/src/shared/shell.c
@@ -452,13 +452,23 @@  static void shell_print_menu_zsh_complete(void)
 	}
 }
 
+static int _wordexp(const char *restrict s, wordexp_t *restrict p, int flags)
+{
+	int ret;
+
+	ret = wordexp(s, p, flags);
+	if (ret != 0)
+		wordfree(p);
+	return ret;
+}
+
 static int parse_args(char *arg, wordexp_t *w, char *del, int flags)
 {
 	char *str;
 
 	str = strdelimit(arg, del, '"');
 
-	if (wordexp(str, w, flags)) {
+	if (_wordexp(str, w, flags) != 0) {
 		free(str);
 		return -EINVAL;
 	}
@@ -537,7 +547,7 @@  static int cmd_exec(const struct bt_shell_menu_entry *entry,
 		goto fail;
 	}
 
-	flags |= WRDE_APPEND;
+	flags |= WRDE_APPEND | WRDE_REUSE;
 	opt = strdup(entry->arg + len + 1);
 
 optional:
@@ -1043,7 +1053,7 @@  static char **args_completion(const struct bt_shell_menu_entry *entry, int argc,
 	args.we_offs = 0;
 	wordfree(&args);
 
-	if (wordexp(str, &args, WRDE_NOCMD))
+	if (_wordexp(str, &args, WRDE_NOCMD))
 		goto done;
 
 	rl_completion_display_matches_hook = NULL;
@@ -1115,7 +1125,7 @@  static char **shell_completion(const char *text, int start, int end)
 	if (start > 0) {
 		wordexp_t w;
 
-		if (wordexp(rl_line_buffer, &w, WRDE_NOCMD))
+		if (_wordexp(rl_line_buffer, &w, WRDE_NOCMD))
 			return NULL;
 
 		matches = menu_completion(default_menu, text, w.we_wordc,
@@ -1416,7 +1426,7 @@  int bt_shell_exec(const char *input)
 	if (data.monitor)
 		bt_log_printf(0xffff, data.name, LOG_INFO, "%s", input);
 
-	err = wordexp(input, &w, WRDE_NOCMD);
+	err = _wordexp(input, &w, WRDE_NOCMD);
 	switch (err) {
 	case WRDE_BADCHAR:
 		return -EBADMSG;
@@ -1426,7 +1436,7 @@  int bt_shell_exec(const char *input)
 	case WRDE_NOSPACE:
 		return -ENOMEM;
 	case WRDE_CMDSUB:
-		if (wordexp(input, &w, 0))
+		if (_wordexp(input, &w, 0))
 			return -ENOEXEC;
 		break;
 	};