summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCatalin Popeanga <Catalin.Popeanga@enea.com>2014-10-09 14:23:24 +0200
committerRichard Purdie <richard.purdie@linuxfoundation.org>2014-10-13 11:18:38 +0100
commitf7dba9940cf6067f4a26de0151c0d5cc029a04f8 (patch)
tree5aa6de35e7527afedf3b7b574b6d13d708dd9502
parent634b753f8458c34b0df971084d6cb71ff8e62815 (diff)
downloadpoky-f7dba9940cf6067f4a26de0151c0d5cc029a04f8.tar.gz
bash: Fix for exported function namespace change
This is a followup patch to incomplete CVE-2014-6271 fix code execution via specially-crafted environment This patch changes the encoding bash uses for exported functions to avoid clashes with shell variables and to avoid depending only on an environment variable's contents to determine whether or not to interpret it as a shell function. (From OE-Core daisy rev: 6c51cc96d03df26d1c10867633e7a10dfbec7c45) (From OE-Core rev: af1f65b57dbfcaf5fc7c254dce80ac55f3a632cb) Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-extended/bash/bash-3.2.48/Fix-for-bash-exported-function-namespace-change.patch158
-rw-r--r--meta/recipes-extended/bash/bash-4.2/Fix-for-bash-exported-function-namespace-change.patch212
-rw-r--r--meta/recipes-extended/bash/bash_3.2.48.bb1
-rw-r--r--meta/recipes-extended/bash/bash_4.2.bb1
4 files changed, 372 insertions, 0 deletions
diff --git a/meta/recipes-extended/bash/bash-3.2.48/Fix-for-bash-exported-function-namespace-change.patch b/meta/recipes-extended/bash/bash-3.2.48/Fix-for-bash-exported-function-namespace-change.patch
new file mode 100644
index 0000000000..c087016eee
--- /dev/null
+++ b/meta/recipes-extended/bash/bash-3.2.48/Fix-for-bash-exported-function-namespace-change.patch
@@ -0,0 +1,158 @@
1Fix for exported function namespace change
2
3Upstream-Status: Backport
4
5Downloaded from: http://ftp.gnu.org/gnu/bash/bash-3.2-patches/bash32-054
6
7Author: Chet Ramey <chet.ramey@case.edu>
8Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com>
9
10
11 BASH PATCH REPORT
12 =================
13
14Bash-Release: 3.2
15Patch-ID: bash32-054
16
17Bug-Reported-by: Florian Weimer <fweimer@redhat.com>
18Bug-Reference-ID:
19Bug-Reference-URL:
20
21Bug-Description:
22
23This patch changes the encoding bash uses for exported functions to avoid
24clashes with shell variables and to avoid depending only on an environment
25variable's contents to determine whether or not to interpret it as a shell
26function.
27---
28--- a/variables.c 2014-09-16 19:10:39.000000000 -0400
29+++ b/variables.c 2014-09-27 21:02:08.000000000 -0400
30@@ -75,4 +75,9 @@
31 #define ifsname(s) ((s)[0] == 'I' && (s)[1] == 'F' && (s)[2] == 'S' && (s)[3] == '\0')
32
33+#define BASHFUNC_PREFIX "BASH_FUNC_"
34+#define BASHFUNC_PREFLEN 10 /* == strlen(BASHFUNC_PREFIX */
35+#define BASHFUNC_SUFFIX "%%"
36+#define BASHFUNC_SUFFLEN 2 /* == strlen(BASHFUNC_SUFFIX) */
37+
38 extern char **environ;
39
40@@ -242,5 +247,5 @@
41 static void dispose_temporary_env __P((sh_free_func_t *));
42
43-static inline char *mk_env_string __P((const char *, const char *));
44+static inline char *mk_env_string __P((const char *, const char *, int));
45 static char **make_env_array_from_var_list __P((SHELL_VAR **));
46 static char **make_var_export_array __P((VAR_CONTEXT *));
47@@ -310,19 +315,30 @@
48 /* If exported function, define it now. Don't import functions from
49 the environment in privileged mode. */
50- if (privmode == 0 && read_but_dont_execute == 0 && STREQN ("() {", string, 4))
51+ if (privmode == 0 && read_but_dont_execute == 0 &&
52+ STREQN (BASHFUNC_PREFIX, name, BASHFUNC_PREFLEN) &&
53+ STREQ (BASHFUNC_SUFFIX, name + char_index - BASHFUNC_SUFFLEN) &&
54+ STREQN ("() {", string, 4))
55 {
56+ size_t namelen;
57+ char *tname; /* desired imported function name */
58+
59+ namelen = char_index - BASHFUNC_PREFLEN - BASHFUNC_SUFFLEN;
60+
61+ tname = name + BASHFUNC_PREFLEN; /* start of func name */
62+ tname[namelen] = '\0'; /* now tname == func name */
63+
64 string_length = strlen (string);
65- temp_string = (char *)xmalloc (3 + string_length + char_index);
66+ temp_string = (char *)xmalloc (namelen + string_length + 2);
67
68- strcpy (temp_string, name);
69- temp_string[char_index] = ' ';
70- strcpy (temp_string + char_index + 1, string);
71+ memcpy (temp_string, tname, namelen);
72+ temp_string[namelen] = ' ';
73+ memcpy (temp_string + namelen + 1, string, string_length + 1);
74
75 /* Don't import function names that are invalid identifiers from the
76 environment. */
77- if (legal_identifier (name))
78- parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD);
79+ if (absolute_program (tname) == 0 && (posixly_correct == 0 || legal_identifier (tname)))
80+ parse_and_execute (temp_string, tname, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD);
81
82- if (temp_var = find_function (name))
83+ if (temp_var = find_function (tname))
84 {
85 VSETATTR (temp_var, (att_exported|att_imported));
86@@ -330,5 +346,8 @@
87 }
88 else
89- report_error (_("error importing function definition for `%s'"), name);
90+ report_error (_("error importing function definition for `%s'"), tname);
91+
92+ /* Restore original suffix */
93+ tname[namelen] = BASHFUNC_SUFFIX[0];
94 }
95 #if defined (ARRAY_VARS)
96@@ -2208,5 +2227,5 @@
97
98 INVALIDATE_EXPORTSTR (var);
99- var->exportstr = mk_env_string (name, value);
100+ var->exportstr = mk_env_string (name, value, 0);
101
102 array_needs_making = 1;
103@@ -2999,19 +3018,40 @@
104
105 static inline char *
106-mk_env_string (name, value)
107+mk_env_string (name, value, isfunc)
108 const char *name, *value;
109+ int isfunc;
110 {
111- int name_len, value_len;
112- char *p;
113+ size_t name_len, value_len;
114+ char *p, *q;
115
116 name_len = strlen (name);
117 value_len = STRLEN (value);
118- p = (char *)xmalloc (2 + name_len + value_len);
119- strcpy (p, name);
120- p[name_len] = '=';
121+
122+ /* If we are exporting a shell function, construct the encoded function
123+ name. */
124+ if (isfunc && value)
125+ {
126+ p = (char *)xmalloc (BASHFUNC_PREFLEN + name_len + BASHFUNC_SUFFLEN + value_len + 2);
127+ q = p;
128+ memcpy (q, BASHFUNC_PREFIX, BASHFUNC_PREFLEN);
129+ q += BASHFUNC_PREFLEN;
130+ memcpy (q, name, name_len);
131+ q += name_len;
132+ memcpy (q, BASHFUNC_SUFFIX, BASHFUNC_SUFFLEN);
133+ q += BASHFUNC_SUFFLEN;
134+ }
135+ else
136+ {
137+ p = (char *)xmalloc (2 + name_len + value_len);
138+ memcpy (p, name, name_len);
139+ q = p + name_len;
140+ }
141+
142+ q[0] = '=';
143 if (value && *value)
144- strcpy (p + name_len + 1, value);
145+ memcpy (q + 1, value, value_len + 1);
146 else
147- p[name_len + 1] = '\0';
148+ q[1] = '\0';
149+
150 return (p);
151 }
152@@ -3088,5 +3128,5 @@
153 using the cached exportstr... */
154 list[list_index] = USE_EXPORTSTR ? savestring (value)
155- : mk_env_string (var->name, value);
156+ : mk_env_string (var->name, value, function_p (var));
157
158 if (USE_EXPORTSTR == 0)
diff --git a/meta/recipes-extended/bash/bash-4.2/Fix-for-bash-exported-function-namespace-change.patch b/meta/recipes-extended/bash/bash-4.2/Fix-for-bash-exported-function-namespace-change.patch
new file mode 100644
index 0000000000..0fb2ad5d89
--- /dev/null
+++ b/meta/recipes-extended/bash/bash-4.2/Fix-for-bash-exported-function-namespace-change.patch
@@ -0,0 +1,212 @@
1Fix for exported function namespace change
2
3Upstream-Status: Backport
4
5Downloaded from: http://ftp.gnu.org/gnu/bash/bash-4.2-patches/bash42-050
6
7Author: Chet Ramey <chet.ramey@case.edu>
8Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
9
10
11 BASH PATCH REPORT
12 =================
13
14Bash-Release: 4.2
15Patch-ID: bash42-050
16
17Bug-Reported-by: Florian Weimer <fweimer@redhat.com>
18Bug-Reference-ID:
19Bug-Reference-URL:
20
21Bug-Description:
22
23This patch changes the encoding bash uses for exported functions to avoid
24clashes with shell variables and to avoid depending only on an environment
25variable's contents to determine whether or not to interpret it as a shell
26function.
27
28Patch (apply with `patch -p0'):
29
30*** ../bash-4.2.49/variables.c 2014-09-16 19:35:45.000000000 -0400
31--- variables.c 2014-09-27 20:54:00.000000000 -0400
32***************
33*** 80,83 ****
34--- 80,88 ----
35 #define ifsname(s) ((s)[0] == 'I' && (s)[1] == 'F' && (s)[2] == 'S' && (s)[3] == '\0')
36
37+ #define BASHFUNC_PREFIX "BASH_FUNC_"
38+ #define BASHFUNC_PREFLEN 10 /* == strlen(BASHFUNC_PREFIX */
39+ #define BASHFUNC_SUFFIX "%%"
40+ #define BASHFUNC_SUFFLEN 2 /* == strlen(BASHFUNC_SUFFIX) */
41+
42 extern char **environ;
43
44***************
45*** 269,273 ****
46 static void dispose_temporary_env __P((sh_free_func_t *));
47
48! static inline char *mk_env_string __P((const char *, const char *));
49 static char **make_env_array_from_var_list __P((SHELL_VAR **));
50 static char **make_var_export_array __P((VAR_CONTEXT *));
51--- 274,278 ----
52 static void dispose_temporary_env __P((sh_free_func_t *));
53
54! static inline char *mk_env_string __P((const char *, const char *, int));
55 static char **make_env_array_from_var_list __P((SHELL_VAR **));
56 static char **make_var_export_array __P((VAR_CONTEXT *));
57***************
58*** 339,357 ****
59 /* If exported function, define it now. Don't import functions from
60 the environment in privileged mode. */
61! if (privmode == 0 && read_but_dont_execute == 0 && STREQN ("() {", string, 4))
62 {
63 string_length = strlen (string);
64! temp_string = (char *)xmalloc (3 + string_length + char_index);
65
66! strcpy (temp_string, name);
67! temp_string[char_index] = ' ';
68! strcpy (temp_string + char_index + 1, string);
69
70 /* Don't import function names that are invalid identifiers from the
71 environment. */
72! if (legal_identifier (name))
73! parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD);
74
75! if (temp_var = find_function (name))
76 {
77 VSETATTR (temp_var, (att_exported|att_imported));
78--- 344,373 ----
79 /* If exported function, define it now. Don't import functions from
80 the environment in privileged mode. */
81! if (privmode == 0 && read_but_dont_execute == 0 &&
82! STREQN (BASHFUNC_PREFIX, name, BASHFUNC_PREFLEN) &&
83! STREQ (BASHFUNC_SUFFIX, name + char_index - BASHFUNC_SUFFLEN) &&
84! STREQN ("() {", string, 4))
85 {
86+ size_t namelen;
87+ char *tname; /* desired imported function name */
88+
89+ namelen = char_index - BASHFUNC_PREFLEN - BASHFUNC_SUFFLEN;
90+
91+ tname = name + BASHFUNC_PREFLEN; /* start of func name */
92+ tname[namelen] = '\0'; /* now tname == func name */
93+
94 string_length = strlen (string);
95! temp_string = (char *)xmalloc (namelen + string_length + 2);
96
97! memcpy (temp_string, tname, namelen);
98! temp_string[namelen] = ' ';
99! memcpy (temp_string + namelen + 1, string, string_length + 1);
100
101 /* Don't import function names that are invalid identifiers from the
102 environment. */
103! if (absolute_program (tname) == 0 && (posixly_correct == 0 || legal_identifier (tname)))
104! parse_and_execute (temp_string, tname, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD);
105
106! if (temp_var = find_function (tname))
107 {
108 VSETATTR (temp_var, (att_exported|att_imported));
109***************
110*** 359,363 ****
111 }
112 else
113! report_error (_("error importing function definition for `%s'"), name);
114 }
115 #if defined (ARRAY_VARS)
116--- 375,382 ----
117 }
118 else
119! report_error (_("error importing function definition for `%s'"), tname);
120!
121! /* Restore original suffix */
122! tname[namelen] = BASHFUNC_SUFFIX[0];
123 }
124 #if defined (ARRAY_VARS)
125***************
126*** 2538,2542 ****
127
128 INVALIDATE_EXPORTSTR (var);
129! var->exportstr = mk_env_string (name, value);
130
131 array_needs_making = 1;
132--- 2557,2561 ----
133
134 INVALIDATE_EXPORTSTR (var);
135! var->exportstr = mk_env_string (name, value, 0);
136
137 array_needs_making = 1;
138***************
139*** 3390,3408 ****
140
141 static inline char *
142! mk_env_string (name, value)
143 const char *name, *value;
144 {
145! int name_len, value_len;
146! char *p;
147
148 name_len = strlen (name);
149 value_len = STRLEN (value);
150! p = (char *)xmalloc (2 + name_len + value_len);
151! strcpy (p, name);
152! p[name_len] = '=';
153 if (value && *value)
154! strcpy (p + name_len + 1, value);
155 else
156! p[name_len + 1] = '\0';
157 return (p);
158 }
159--- 3409,3448 ----
160
161 static inline char *
162! mk_env_string (name, value, isfunc)
163 const char *name, *value;
164+ int isfunc;
165 {
166! size_t name_len, value_len;
167! char *p, *q;
168
169 name_len = strlen (name);
170 value_len = STRLEN (value);
171!
172! /* If we are exporting a shell function, construct the encoded function
173! name. */
174! if (isfunc && value)
175! {
176! p = (char *)xmalloc (BASHFUNC_PREFLEN + name_len + BASHFUNC_SUFFLEN + value_len + 2);
177! q = p;
178! memcpy (q, BASHFUNC_PREFIX, BASHFUNC_PREFLEN);
179! q += BASHFUNC_PREFLEN;
180! memcpy (q, name, name_len);
181! q += name_len;
182! memcpy (q, BASHFUNC_SUFFIX, BASHFUNC_SUFFLEN);
183! q += BASHFUNC_SUFFLEN;
184! }
185! else
186! {
187! p = (char *)xmalloc (2 + name_len + value_len);
188! memcpy (p, name, name_len);
189! q = p + name_len;
190! }
191!
192! q[0] = '=';
193 if (value && *value)
194! memcpy (q + 1, value, value_len + 1);
195 else
196! q[1] = '\0';
197!
198 return (p);
199 }
200***************
201*** 3490,3494 ****
202 using the cached exportstr... */
203 list[list_index] = USE_EXPORTSTR ? savestring (value)
204! : mk_env_string (var->name, value);
205
206 if (USE_EXPORTSTR == 0)
207--- 3530,3534 ----
208 using the cached exportstr... */
209 list[list_index] = USE_EXPORTSTR ? savestring (value)
210! : mk_env_string (var->name, value, function_p (var));
211
212 if (USE_EXPORTSTR == 0)
diff --git a/meta/recipes-extended/bash/bash_3.2.48.bb b/meta/recipes-extended/bash/bash_3.2.48.bb
index e6a04cd888..a5417f19cc 100644
--- a/meta/recipes-extended/bash/bash_3.2.48.bb
+++ b/meta/recipes-extended/bash/bash_3.2.48.bb
@@ -14,6 +14,7 @@ SRC_URI = "${GNU_MIRROR}/bash/bash-${PV}.tar.gz;name=tarball \
14 file://test-output.patch \ 14 file://test-output.patch \
15 file://cve-2014-6271.patch;striplevel=0 \ 15 file://cve-2014-6271.patch;striplevel=0 \
16 file://cve-2014-7169.patch \ 16 file://cve-2014-7169.patch \
17 file://Fix-for-bash-exported-function-namespace-change.patch \
17 file://run-ptest \ 18 file://run-ptest \
18 " 19 "
19 20
diff --git a/meta/recipes-extended/bash/bash_4.2.bb b/meta/recipes-extended/bash/bash_4.2.bb
index e3fa39dece..72222590ad 100644
--- a/meta/recipes-extended/bash/bash_4.2.bb
+++ b/meta/recipes-extended/bash/bash_4.2.bb
@@ -23,6 +23,7 @@ SRC_URI = "${GNU_MIRROR}/bash/${BPN}-${PV}.tar.gz;name=tarball \
23 file://test-output.patch \ 23 file://test-output.patch \
24 file://cve-2014-6271.patch;striplevel=0 \ 24 file://cve-2014-6271.patch;striplevel=0 \
25 file://cve-2014-7169.patch \ 25 file://cve-2014-7169.patch \
26 file://Fix-for-bash-exported-function-namespace-change.patch;striplevel=0 \
26 file://run-ptest \ 27 file://run-ptest \
27 " 28 "
28 29