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-16 16:05:55 +0200
commitb91889fb3e98069b7d5e9c8a544ed511d6544f24 (patch)
tree492a9f957622384342a79583e811e6afc66e973e
parent35ed0a06be953512847fe281596351c2119fd6e0 (diff)
downloadpoky-b91889fb3e98069b7d5e9c8a544ed511d6544f24.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: 998cd2c6dd3709ae0d47c845dff227680bda96f5) 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 8362c27fc1..1e6e3f3a28 100644
--- a/meta/recipes-extended/bash/bash_3.2.48.bb
+++ b/meta/recipes-extended/bash/bash_3.2.48.bb
@@ -12,6 +12,7 @@ SRC_URI = "${GNU_MIRROR}/bash/bash-${PV}.tar.gz;name=tarball \
12 file://mkbuiltins_have_stringize.patch \ 12 file://mkbuiltins_have_stringize.patch \
13 file://cve-2014-6271.patch;striplevel=0 \ 13 file://cve-2014-6271.patch;striplevel=0 \
14 file://cve-2014-7169.patch \ 14 file://cve-2014-7169.patch \
15 file://Fix-for-bash-exported-function-namespace-change.patch \
15 " 16 "
16 17
17SRC_URI[tarball.md5sum] = "338dcf975a93640bb3eaa843ca42e3f8" 18SRC_URI[tarball.md5sum] = "338dcf975a93640bb3eaa843ca42e3f8"
diff --git a/meta/recipes-extended/bash/bash_4.2.bb b/meta/recipes-extended/bash/bash_4.2.bb
index 67b1924c85..515bdc99f0 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://cve-2014-7169.patch \ 23 file://cve-2014-7169.patch \
24 file://build-tests.patch \ 24 file://build-tests.patch \
25 file://test-output.patch \ 25 file://test-output.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