149 lines
3.2 KiB
Diff
149 lines
3.2 KiB
Diff
|
From 9883307a527a0d0e39fe9d500c22ef3eccda83ba Mon Sep 17 00:00:00 2001
|
||
|
From: Andrei Borzenkov <arvidjaar@gmail.com>
|
||
|
Date: Wed, 28 Jan 2015 20:35:28 +0300
|
||
|
Subject: [PATCH 270/506] script/execute.c: fix memory leak.
|
||
|
|
||
|
Make sure to continue loop over array after failure to free
|
||
|
allocated strings.
|
||
|
|
||
|
Found by: Coverity scan.
|
||
|
---
|
||
|
grub-core/script/execute.c | 120 ++++++++++++++++++++++++++-------------------
|
||
|
1 file changed, 70 insertions(+), 50 deletions(-)
|
||
|
|
||
|
diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
|
||
|
index afd5513..bb70ebf 100644
|
||
|
--- a/grub-core/script/execute.c
|
||
|
+++ b/grub-core/script/execute.c
|
||
|
@@ -635,57 +635,77 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist,
|
||
|
{
|
||
|
case GRUB_SCRIPT_ARG_TYPE_VAR:
|
||
|
case GRUB_SCRIPT_ARG_TYPE_DQVAR:
|
||
|
- values = grub_script_env_get (arg->str, arg->type);
|
||
|
- for (i = 0; values && values[i]; i++)
|
||
|
- {
|
||
|
- if (i != 0 && grub_script_argv_next (&result))
|
||
|
- goto fail;
|
||
|
+ {
|
||
|
+ int need_cleanup = 0;
|
||
|
|
||
|
- if (arg->type == GRUB_SCRIPT_ARG_TYPE_VAR)
|
||
|
- {
|
||
|
- int len;
|
||
|
- char ch;
|
||
|
- char *p;
|
||
|
- char *op;
|
||
|
- const char *s = values[i];
|
||
|
-
|
||
|
- len = grub_strlen (values[i]);
|
||
|
- /* \? -> \\\? */
|
||
|
- /* \* -> \\\* */
|
||
|
- /* \ -> \\ */
|
||
|
- p = grub_malloc (len * 2 + 1);
|
||
|
- if (! p)
|
||
|
- goto fail;
|
||
|
-
|
||
|
- op = p;
|
||
|
- while ((ch = *s++))
|
||
|
- {
|
||
|
- if (ch == '\\')
|
||
|
- {
|
||
|
- *op++ = '\\';
|
||
|
- if (*s == '?' || *s == '*')
|
||
|
- *op++ = '\\';
|
||
|
- }
|
||
|
- *op++ = ch;
|
||
|
- }
|
||
|
- *op = '\0';
|
||
|
-
|
||
|
- if (grub_script_argv_append (&result, p, op - p))
|
||
|
- {
|
||
|
- grub_free (p);
|
||
|
- goto fail;
|
||
|
- }
|
||
|
- }
|
||
|
- else
|
||
|
- {
|
||
|
- if (append (&result, values[i], 1))
|
||
|
- goto fail;
|
||
|
- }
|
||
|
-
|
||
|
- grub_free (values[i]);
|
||
|
- }
|
||
|
- grub_free (values);
|
||
|
- break;
|
||
|
+ values = grub_script_env_get (arg->str, arg->type);
|
||
|
+ for (i = 0; values && values[i]; i++)
|
||
|
+ {
|
||
|
+ if (!need_cleanup)
|
||
|
+ {
|
||
|
+ if (i != 0 && grub_script_argv_next (&result))
|
||
|
+ {
|
||
|
+ need_cleanup = 1;
|
||
|
+ goto cleanup;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (arg->type == GRUB_SCRIPT_ARG_TYPE_VAR)
|
||
|
+ {
|
||
|
+ int len;
|
||
|
+ char ch;
|
||
|
+ char *p;
|
||
|
+ char *op;
|
||
|
+ const char *s = values[i];
|
||
|
+
|
||
|
+ len = grub_strlen (values[i]);
|
||
|
+ /* \? -> \\\? */
|
||
|
+ /* \* -> \\\* */
|
||
|
+ /* \ -> \\ */
|
||
|
+ p = grub_malloc (len * 2 + 1);
|
||
|
+ if (! p)
|
||
|
+ {
|
||
|
+ need_cleanup = 1;
|
||
|
+ goto cleanup;
|
||
|
+ }
|
||
|
+
|
||
|
+ op = p;
|
||
|
+ while ((ch = *s++))
|
||
|
+ {
|
||
|
+ if (ch == '\\')
|
||
|
+ {
|
||
|
+ *op++ = '\\';
|
||
|
+ if (*s == '?' || *s == '*')
|
||
|
+ *op++ = '\\';
|
||
|
+ }
|
||
|
+ *op++ = ch;
|
||
|
+ }
|
||
|
+ *op = '\0';
|
||
|
+
|
||
|
+ if (grub_script_argv_append (&result, p, op - p))
|
||
|
+ {
|
||
|
+ grub_free (p);
|
||
|
+ need_cleanup = 1;
|
||
|
+ /* Fall through to cleanup */
|
||
|
+ }
|
||
|
+ }
|
||
|
+ else
|
||
|
+ {
|
||
|
+ if (append (&result, values[i], 1))
|
||
|
+ need_cleanup = 1;
|
||
|
+ /* Fall through to cleanup */
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+cleanup:
|
||
|
+ grub_free (values[i]);
|
||
|
+ }
|
||
|
+ grub_free (values);
|
||
|
+
|
||
|
+ if (need_cleanup)
|
||
|
+ goto fail;
|
||
|
+
|
||
|
+ break;
|
||
|
+ }
|
||
|
|
||
|
case GRUB_SCRIPT_ARG_TYPE_BLOCK:
|
||
|
{
|
||
|
--
|
||
|
2.4.3
|
||
|
|