summaryrefslogtreecommitdiffstats
path: root/meta/recipes-bsp/grub/files/CVE-2020-15706-script-Avoid-a-use-after-free-when-redefining-a-func.patch
blob: 329e554a682e744d071f1da5e0420f2dc6acf4f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
From c65fc7e75b7b7e880d90766057040011701e97f4 Mon Sep 17 00:00:00 2001
From: Chris Coulson <chris.coulson@canonical.com>
Date: Fri, 10 Jul 2020 14:41:45 +0100
Subject: [PATCH 8/9] script: Avoid a use-after-free when redefining a function
 during execution

Defining a new function with the same name as a previously defined
function causes the grub_script and associated resources for the
previous function to be freed. If the previous function is currently
executing when a function with the same name is defined, this results
in use-after-frees when processing subsequent commands in the original
function.

Instead, reject a new function definition if it has the same name as
a previously defined function, and that function is currently being
executed. Although a behavioural change, this should be backwards
compatible with existing configurations because they can't be
dependent on the current behaviour without being broken.

Fixes: CVE-2020-15706

Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>

Upstream-Status: Backport
CVE: CVE-2020-15706

Reference to upstream patch:
https://git.savannah.gnu.org/cgit/grub.git/commit/?id=426f57383d647406ae9c628c472059c27cd6e040

Signed-off-by: Yongxin Liu <yongxin.liu@windriver.com>
---
 grub-core/script/execute.c  |  2 ++
 grub-core/script/function.c | 16 +++++++++++++---
 grub-core/script/parser.y   |  3 ++-
 include/grub/script_sh.h    |  2 ++
 4 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
index c8d6806..7e028e1 100644
--- a/grub-core/script/execute.c
+++ b/grub-core/script/execute.c
@@ -838,7 +838,9 @@ grub_script_function_call (grub_script_function_t func, int argc, char **args)
   old_scope = scope;
   scope = &new_scope;
 
+  func->executing++;
   ret = grub_script_execute (func->func);
+  func->executing--;
 
   function_return = 0;
   active_loops = loops;
diff --git a/grub-core/script/function.c b/grub-core/script/function.c
index d36655e..3aad04b 100644
--- a/grub-core/script/function.c
+++ b/grub-core/script/function.c
@@ -34,6 +34,7 @@ grub_script_function_create (struct grub_script_arg *functionname_arg,
   func = (grub_script_function_t) grub_malloc (sizeof (*func));
   if (! func)
     return 0;
+  func->executing = 0;
 
   func->name = grub_strdup (functionname_arg->str);
   if (! func->name)
@@ -60,10 +61,19 @@ grub_script_function_create (struct grub_script_arg *functionname_arg,
       grub_script_function_t q;
 
       q = *p;
-      grub_script_free (q->func);
-      q->func = cmd;
       grub_free (func);
-      func = q;
+      if (q->executing > 0)
+        {
+          grub_error (GRUB_ERR_BAD_ARGUMENT,
+		      N_("attempt to redefine a function being executed"));
+          func = NULL;
+        }
+      else
+        {
+          grub_script_free (q->func);
+          q->func = cmd;
+          func = q;
+        }
     }
   else
     {
diff --git a/grub-core/script/parser.y b/grub-core/script/parser.y
index 4f0ab83..f80b86b 100644
--- a/grub-core/script/parser.y
+++ b/grub-core/script/parser.y
@@ -289,7 +289,8 @@ function: "function" "name"
 	      grub_script_mem_free (state->func_mem);
 	    else {
 	      script->children = state->scripts;
-	      grub_script_function_create ($2, script);
+	      if (!grub_script_function_create ($2, script))
+		grub_script_free (script);
 	    }
 
 	    state->scripts = $<scripts>3;
diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h
index b382bcf..6c48e07 100644
--- a/include/grub/script_sh.h
+++ b/include/grub/script_sh.h
@@ -361,6 +361,8 @@ struct grub_script_function
 
   /* The next element.  */
   struct grub_script_function *next;
+
+  unsigned executing;
 };
 typedef struct grub_script_function *grub_script_function_t;
 
-- 
2.14.4