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-10 18:06:08 +0100
commit95821e8566147841e726678b76a5397b971a6e57 (patch)
tree6b5a26ecc5b9c65095511c5f2803bb1e72fc805c
parent57138de0fc1730c8e14d19b784f1f0573fb03080 (diff)
downloadpoky-95821e8566147841e726678b76a5397b971a6e57.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 rev: 6c51cc96d03df26d1c10867633e7a10dfbec7c45) Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.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/Fix-for-bash-exported-function-namespace-change.patch175
-rw-r--r--meta/recipes-extended/bash/bash_3.2.48.bb1
-rw-r--r--meta/recipes-extended/bash/bash_4.3.bb1
4 files changed, 335 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/Fix-for-bash-exported-function-namespace-change.patch b/meta/recipes-extended/bash/bash/Fix-for-bash-exported-function-namespace-change.patch
new file mode 100644
index 0000000000..1faab04659
--- /dev/null
+++ b/meta/recipes-extended/bash/bash/Fix-for-bash-exported-function-namespace-change.patch
@@ -0,0 +1,175 @@
1Fix for exported function namespace change
2
3Upstream-Status: Backport
4
5Downloaded from: http://ftp.gnu.org/gnu/bash/bash-4.3-patches/bash43-027
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: 4.3
15Patch-ID: bash43-027
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---
28diff -ruN a/variables.c b/variables.c
29--- a/variables.c 2014-09-30 10:21:12.481674914 +0200
30+++ b/variables.c 2014-09-30 10:21:40.820459492 +0200
31@@ -83,6 +83,11 @@
32
33 #define ifsname(s) ((s)[0] == 'I' && (s)[1] == 'F' && (s)[2] == 'S' && (s)[3] == '\0')
34
35+#define BASHFUNC_PREFIX "BASH_FUNC_"
36+#define BASHFUNC_PREFLEN 10 /* == strlen(BASHFUNC_PREFIX */
37+#define BASHFUNC_SUFFIX "%%"
38+#define BASHFUNC_SUFFLEN 2 /* == strlen(BASHFUNC_SUFFIX) */
39+
40 extern char **environ;
41
42 /* Variables used here and defined in other files. */
43@@ -279,7 +284,7 @@
44 static void propagate_temp_var __P((PTR_T));
45 static void dispose_temporary_env __P((sh_free_func_t *));
46
47-static inline char *mk_env_string __P((const char *, const char *));
48+static inline char *mk_env_string __P((const char *, const char *, int));
49 static char **make_env_array_from_var_list __P((SHELL_VAR **));
50 static char **make_var_export_array __P((VAR_CONTEXT *));
51 static char **make_func_export_array __P((void));
52@@ -349,22 +354,33 @@
53
54 /* If exported function, define it now. Don't import functions from
55 the environment in privileged mode. */
56- if (privmode == 0 && read_but_dont_execute == 0 && STREQN ("() {", string, 4))
57+ if (privmode == 0 && read_but_dont_execute == 0 &&
58+ STREQN (BASHFUNC_PREFIX, name, BASHFUNC_PREFLEN) &&
59+ STREQ (BASHFUNC_SUFFIX, name + char_index - BASHFUNC_SUFFLEN) &&
60+ STREQN ("() {", string, 4))
61 {
62+ size_t namelen;
63+ char *tname; /* desired imported function name */
64+
65+ namelen = char_index - BASHFUNC_PREFLEN - BASHFUNC_SUFFLEN;
66+
67+ tname = name + BASHFUNC_PREFLEN; /* start of func name */
68+ tname[namelen] = '\0'; /* now tname == func name */
69+
70 string_length = strlen (string);
71- temp_string = (char *)xmalloc (3 + string_length + char_index);
72+ temp_string = (char *)xmalloc (namelen + string_length + 2);
73
74- strcpy (temp_string, name);
75- temp_string[char_index] = ' ';
76- strcpy (temp_string + char_index + 1, string);
77+ memcpy (temp_string, tname, namelen);
78+ temp_string[namelen] = ' ';
79+ memcpy (temp_string + namelen + 1, string, string_length + 1);
80
81 /* Don't import function names that are invalid identifiers from the
82 environment, though we still allow them to be defined as shell
83 variables. */
84- if (legal_identifier (name))
85- parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD);
86+ if (absolute_program (tname) == 0 && (posixly_correct == 0 || legal_identifier (tname)))
87+ parse_and_execute (temp_string, tname, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD);
88
89- if (temp_var = find_function (name))
90+ if (temp_var = find_function (tname))
91 {
92 VSETATTR (temp_var, (att_exported|att_imported));
93 array_needs_making = 1;
94@@ -377,8 +393,11 @@
95 array_needs_making = 1;
96 }
97 last_command_exit_value = 1;
98- report_error (_("error importing function definition for `%s'"), name);
99+ report_error (_("error importing function definition for `%s'"), tname);
100 }
101+
102+ /* Restore original suffix */
103+ tname[namelen] = BASHFUNC_SUFFIX[0];
104 }
105 #if defined (ARRAY_VARS)
106 # if ARRAY_EXPORT
107@@ -2957,7 +2976,7 @@
108 var->context = variable_context; /* XXX */
109
110 INVALIDATE_EXPORTSTR (var);
111- var->exportstr = mk_env_string (name, value);
112+ var->exportstr = mk_env_string (name, value, 0);
113
114 array_needs_making = 1;
115
116@@ -3855,21 +3874,42 @@
117 /* **************************************************************** */
118
119 static inline char *
120-mk_env_string (name, value)
121+mk_env_string (name, value, isfunc)
122 const char *name, *value;
123+ int isfunc;
124 {
125- int name_len, value_len;
126- char *p;
127+ size_t name_len, value_len;
128+ char *p, *q;
129
130 name_len = strlen (name);
131 value_len = STRLEN (value);
132- p = (char *)xmalloc (2 + name_len + value_len);
133- strcpy (p, name);
134- p[name_len] = '=';
135+
136+ /* If we are exporting a shell function, construct the encoded function
137+ name. */
138+ if (isfunc && value)
139+ {
140+ p = (char *)xmalloc (BASHFUNC_PREFLEN + name_len + BASHFUNC_SUFFLEN + value_len + 2);
141+ q = p;
142+ memcpy (q, BASHFUNC_PREFIX, BASHFUNC_PREFLEN);
143+ q += BASHFUNC_PREFLEN;
144+ memcpy (q, name, name_len);
145+ q += name_len;
146+ memcpy (q, BASHFUNC_SUFFIX, BASHFUNC_SUFFLEN);
147+ q += BASHFUNC_SUFFLEN;
148+ }
149+ else
150+ {
151+ p = (char *)xmalloc (2 + name_len + value_len);
152+ memcpy (p, name, name_len);
153+ q = p + name_len;
154+ }
155+
156+ q[0] = '=';
157 if (value && *value)
158- strcpy (p + name_len + 1, value);
159+ memcpy (q + 1, value, value_len + 1);
160 else
161- p[name_len + 1] = '\0';
162+ q[1] = '\0';
163+
164 return (p);
165 }
166
167@@ -3955,7 +3995,7 @@
168 /* Gee, I'd like to get away with not using savestring() if we're
169 using the cached exportstr... */
170 list[list_index] = USE_EXPORTSTR ? savestring (value)
171- : mk_env_string (var->name, value);
172+ : mk_env_string (var->name, value, function_p (var));
173
174 if (USE_EXPORTSTR == 0)
175 SAVE_EXPORTSTR (var, list[list_index]);
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.3.bb b/meta/recipes-extended/bash/bash_4.3.bb
index 69ddeccd35..1130c751be 100644
--- a/meta/recipes-extended/bash/bash_4.3.bb
+++ b/meta/recipes-extended/bash/bash_4.3.bb
@@ -11,6 +11,7 @@ SRC_URI = "${GNU_MIRROR}/bash/${BPN}-${PV}.tar.gz;name=tarball \
11 file://test-output.patch \ 11 file://test-output.patch \
12 file://cve-2014-6271.patch;striplevel=0 \ 12 file://cve-2014-6271.patch;striplevel=0 \
13 file://cve-2014-7169.patch \ 13 file://cve-2014-7169.patch \
14 file://Fix-for-bash-exported-function-namespace-change.patch \
14 file://run-ptest \ 15 file://run-ptest \
15 " 16 "
16 17