summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDe Huo <De.Huo@windriver.com>2020-02-04 07:06:02 -0800
committerRichard Purdie <richard.purdie@linuxfoundation.org>2020-02-04 18:43:08 +0000
commit09e695246d30ef9b73e743e0130e710e19793d14 (patch)
treeabdf9c07fbbaa837bb960537213a18b4020ed320
parent7dc72fde6edeb5d6ac6b3832530998afeea67cbc (diff)
downloadpoky-09e695246d30ef9b73e743e0130e710e19793d14.tar.gz
bash: Fix CVE-2019-18276
An issue was discovered in disable_priv_mode in shell.c in GNU Bash through 5.0 patch 11. By default, if Bash is run with its effective UID not equal to its real UID, it will drop privileges by setting its effective UID to its real UID. However, it does so incorrectly. On Linux and other systems that support "saved UID" functionality, the saved UID is not dropped. An attacker with command execution in the shell can use "enable -f" for runtime loading of a new builtin, which can be a shared object that calls setuid() and therefore regains privileges. However, binaries running with an effective UID of 0 are unaffected. Backport the CVE patche from https://github.com/bminor/bash/commit/ 951bdaad7a18cc0dc1036bba86b18b90874d39ff to fix CVE-2019-18276 (From OE-Core rev: b348e31c93f08332667df65cd2ecec63631d184e) Signed-off-by: Chet Ramey <chet.ramey@case.edu> Signed-off-by: De Huo <De.Huo@windriver.com> Signed-off-by: Armin Kuster <akuster808@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-extended/bash/bash/bash-CVE-2019-18276.patch402
-rw-r--r--meta/recipes-extended/bash/bash_5.0.bb1
2 files changed, 403 insertions, 0 deletions
diff --git a/meta/recipes-extended/bash/bash/bash-CVE-2019-18276.patch b/meta/recipes-extended/bash/bash/bash-CVE-2019-18276.patch
new file mode 100644
index 0000000000..78dcc1b636
--- /dev/null
+++ b/meta/recipes-extended/bash/bash/bash-CVE-2019-18276.patch
@@ -0,0 +1,402 @@
1From 951bdaad7a18cc0dc1036bba86b18b90874d39ff Mon Sep 17 00:00:00 2001
2From: Chet Ramey <chet.ramey@case.edu>
3Date: Mon, 1 Jul 2019 09:03:53 -0400
4Subject: [PATCH] commit bash-20190628 snapshot
5
6An issue was discovered in disable_priv_mode in shell.c in GNU Bash through 5.0 patch 11.
7By default, if Bash is run with its effective UID not equal to its real UID,
8it will drop privileges by setting its effective UID to its real UID.
9However, it does so incorrectly. On Linux and other systems that support "saved UID" functionality,
10the saved UID is not dropped. An attacker with command execution in the shell can use "enable -f" for
11runtime loading of a new builtin, which can be a shared object that calls setuid() and therefore
12regains privileges. However, binaries running with an effective UID of 0 are unaffected.
13
14Upstream-Status: Backport [https://github.com/bminor/bash/commit/951bdaad7a18cc0dc1036bba86b18b90874d39ff]
15CVE: CVE-2019-18276
16Signed-off-by: Chet Ramey <chet.ramey@case.edu>
17Signed-off-by: De Huo <De.Huo@windriver.com>
18---
19 MANIFEST | 2 ++
20 bashline.c | 50 +-------------------------------------------------
21 builtins/help.def | 2 +-
22 config.h.in | 10 +++++++++-
23 configure | 11 +++++++++++
24 configure.ac | 1 +
25 doc/bash.1 | 3 ++-
26 doc/bashref.texi | 3 ++-
27 lib/glob/glob.c | 5 ++++-
28 pathexp.c | 16 ++++++++++++++--
29 shell.c | 8 ++++++++
30 tests/glob.tests | 2 ++
31 tests/glob6.sub | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
32 tests/glob7.sub | 11 +++++++++++
33 14 files changed, 122 insertions(+), 56 deletions(-)
34 create mode 100644 tests/glob6.sub
35 create mode 100644 tests/glob7.sub
36
37diff --git a/MANIFEST b/MANIFEST
38index 03de221..f9ccad7 100644
39--- a/MANIFEST
40+++ b/MANIFEST
41@@ -1037,6 +1037,8 @@ tests/extglob3.tests f
42 tests/extglob3.right f
43 tests/extglob4.sub f
44 tests/extglob5.sub f
45+tests/glob6.sub f
46+tests/glob7.sub f
47 tests/func.tests f
48 tests/func.right f
49 tests/func1.sub f
50diff --git a/bashline.c b/bashline.c
51index 824ea9d..d86b47d 100644
52--- a/bashline.c
53+++ b/bashline.c
54@@ -3718,55 +3718,7 @@ static int
55 completion_glob_pattern (string)
56 char *string;
57 {
58- register int c;
59- char *send;
60- int open;
61-
62- DECLARE_MBSTATE;
63-
64- open = 0;
65- send = string + strlen (string);
66-
67- while (c = *string++)
68- {
69- switch (c)
70- {
71- case '?':
72- case '*':
73- return (1);
74-
75- case '[':
76- open++;
77- continue;
78-
79- case ']':
80- if (open)
81- return (1);
82- continue;
83-
84- case '+':
85- case '@':
86- case '!':
87- if (*string == '(') /*)*/
88- return (1);
89- continue;
90-
91- case '\\':
92- if (*string++ == 0)
93- return (0);
94- }
95-
96- /* Advance one fewer byte than an entire multibyte character to
97- account for the auto-increment in the loop above. */
98-#ifdef HANDLE_MULTIBYTE
99- string--;
100- ADVANCE_CHAR_P (string, send - string);
101- string++;
102-#else
103- ADVANCE_CHAR_P (string, send - string);
104-#endif
105- }
106- return (0);
107+ return (glob_pattern_p (string) == 1);
108 }
109
110 static char *globtext;
111diff --git a/builtins/help.def b/builtins/help.def
112index 006c4b5..92f9b38 100644
113--- a/builtins/help.def
114+++ b/builtins/help.def
115@@ -128,7 +128,7 @@ help_builtin (list)
116
117 /* We should consider making `help bash' do something. */
118
119- if (glob_pattern_p (list->word->word))
120+ if (glob_pattern_p (list->word->word) == 1)
121 {
122 printf ("%s", ngettext ("Shell commands matching keyword `", "Shell commands matching keywords `", (list->next ? 2 : 1)));
123 print_word_list (list, ", ");
124diff --git a/config.h.in b/config.h.in
125index 8554aec..ad4b1e8 100644
126--- a/config.h.in
127+++ b/config.h.in
128@@ -1,6 +1,6 @@
129 /* config.h -- Configuration file for bash. */
130
131-/* Copyright (C) 1987-2009,2011-2012 Free Software Foundation, Inc.
132+/* Copyright (C) 1987-2009,2011-2012,2013-2019 Free Software Foundation, Inc.
133
134 This file is part of GNU Bash, the Bourne Again SHell.
135
136@@ -807,6 +807,14 @@
137 #undef HAVE_SETREGID
138 #undef HAVE_DECL_SETREGID
139
140+/* Define if you have the setregid function. */
141+#undef HAVE_SETRESGID
142+#undef HAVE_DECL_SETRESGID
143+
144+/* Define if you have the setresuid function. */
145+#undef HAVE_SETRESUID
146+#undef HAVE_DECL_SETRESUID
147+
148 /* Define if you have the setvbuf function. */
149 #undef HAVE_SETVBUF
150
151diff --git a/configure b/configure
152index 2f62662..b3321c9 100755
153--- a/configure
154+++ b/configure
155@@ -10281,6 +10281,17 @@ cat >>confdefs.h <<_ACEOF
156 #define HAVE_DECL_SETREGID $ac_have_decl
157 _ACEOF
158
159+ac_fn_c_check_decl "$LINENO" "" "ac_cv_have_decl_" "$ac_includes_default"
160+if test "x$ac_cv_have_decl_" = xyes; then :
161+ ac_have_decl=1
162+else
163+ ac_have_decl=0
164+fi
165+
166+cat >>confdefs.h <<_ACEOF
167+#define HAVE_DECL_ $ac_have_decl
168+_ACEOF
169+(setresuid, setresgid)
170 ac_fn_c_check_decl "$LINENO" "strcpy" "ac_cv_have_decl_strcpy" "$ac_includes_default"
171 if test "x$ac_cv_have_decl_strcpy" = xyes; then :
172 ac_have_decl=1
173diff --git a/configure.ac b/configure.ac
174index 52b4cdb..549adef 100644
175--- a/configure.ac
176+++ b/configure.ac
177@@ -810,6 +810,7 @@ AC_CHECK_DECLS([confstr])
178 AC_CHECK_DECLS([printf])
179 AC_CHECK_DECLS([sbrk])
180 AC_CHECK_DECLS([setregid])
181+AC_CHECK_DECLS[(setresuid, setresgid])
182 AC_CHECK_DECLS([strcpy])
183 AC_CHECK_DECLS([strsignal])
184
185diff --git a/doc/bash.1 b/doc/bash.1
186index e6cd08d..9e58a0b 100644
187--- a/doc/bash.1
188+++ b/doc/bash.1
189@@ -4681,7 +4681,8 @@ above).
190 .PD
191 .SH "SIMPLE COMMAND EXPANSION"
192 When a simple command is executed, the shell performs the following
193-expansions, assignments, and redirections, from left to right.
194+expansions, assignments, and redirections, from left to right, in
195+the following order.
196 .IP 1.
197 The words that the parser has marked as variable assignments (those
198 preceding the command name) and redirections are saved for later
199diff --git a/doc/bashref.texi b/doc/bashref.texi
200index d33cd57..3065126 100644
201--- a/doc/bashref.texi
202+++ b/doc/bashref.texi
203@@ -2964,7 +2964,8 @@ is not specified. If the file does not exist, it is created.
204 @cindex command expansion
205
206 When a simple command is executed, the shell performs the following
207-expansions, assignments, and redirections, from left to right.
208+expansions, assignments, and redirections, from left to right, in
209+the following order.
210
211 @enumerate
212 @item
213diff --git a/lib/glob/glob.c b/lib/glob/glob.c
214index 398253b..2eaa33e 100644
215--- a/lib/glob/glob.c
216+++ b/lib/glob/glob.c
217@@ -607,6 +607,7 @@ glob_vector (pat, dir, flags)
218 register unsigned int i;
219 int mflags; /* Flags passed to strmatch (). */
220 int pflags; /* flags passed to sh_makepath () */
221+ int hasglob; /* return value from glob_pattern_p */
222 int nalloca;
223 struct globval *firstmalloc, *tmplink;
224 char *convfn;
225@@ -648,10 +649,12 @@ glob_vector (pat, dir, flags)
226 patlen = (pat && *pat) ? strlen (pat) : 0;
227
228 /* If the filename pattern (PAT) does not contain any globbing characters,
229+ or contains a pattern with only backslash escapes (hasglob == 2),
230 we can dispense with reading the directory, and just see if there is
231 a filename `DIR/PAT'. If there is, and we can access it, just make the
232 vector to return and bail immediately. */
233- if (skip == 0 && glob_pattern_p (pat) == 0)
234+ hasglob = 0;
235+ if (skip == 0 && (hasglob = glob_pattern_p (pat)) == 0 || hasglob == 2)
236 {
237 int dirlen;
238 struct stat finfo;
239diff --git a/pathexp.c b/pathexp.c
240index c1bf2d8..e6c5392 100644
241--- a/pathexp.c
242+++ b/pathexp.c
243@@ -58,7 +58,10 @@ int extended_glob = EXTGLOB_DEFAULT;
244 /* Control enabling special handling of `**' */
245 int glob_star = 0;
246
247-/* Return nonzero if STRING has any unquoted special globbing chars in it. */
248+/* Return nonzero if STRING has any unquoted special globbing chars in it.
249+ This is supposed to be called when pathname expansion is performed, so
250+ it implements the rules in Posix 2.13.3, specifically that an unquoted
251+ slash cannot appear in a bracket expression. */
252 int
253 unquoted_glob_pattern_p (string)
254 register char *string;
255@@ -85,10 +88,14 @@ unquoted_glob_pattern_p (string)
256 continue;
257
258 case ']':
259- if (open)
260+ if (open) /* XXX - if --open == 0? */
261 return (1);
262 continue;
263
264+ case '/':
265+ if (open)
266+ open = 0;
267+
268 case '+':
269 case '@':
270 case '!':
271@@ -106,6 +113,11 @@ unquoted_glob_pattern_p (string)
272 string++;
273 continue;
274 }
275+ else if (open && *string == '/')
276+ {
277+ string++; /* quoted slashes in bracket expressions are ok */
278+ continue;
279+ }
280 else if (*string == 0)
281 return (0);
282
283diff --git a/shell.c b/shell.c
284index a2b2a55..6adabc8 100644
285--- a/shell.c
286+++ b/shell.c
287@@ -1293,7 +1293,11 @@ disable_priv_mode ()
288 {
289 int e;
290
291+#if HAVE_DECL_SETRESUID
292+ if (setresuid (current_user.uid, current_user.uid, current_user.uid) < 0)
293+#else
294 if (setuid (current_user.uid) < 0)
295+#endif
296 {
297 e = errno;
298 sys_error (_("cannot set uid to %d: effective uid %d"), current_user.uid, current_user.euid);
299@@ -1302,7 +1306,11 @@ disable_priv_mode ()
300 exit (e);
301 #endif
302 }
303+#if HAVE_DECL_SETRESGID
304+ if (setresgid (current_user.gid, current_user.gid, current_user.gid) < 0)
305+#else
306 if (setgid (current_user.gid) < 0)
307+#endif
308 sys_error (_("cannot set gid to %d: effective gid %d"), current_user.gid, current_user.egid);
309
310 current_user.euid = current_user.uid;
311diff --git a/tests/glob.tests b/tests/glob.tests
312index 01913bb..fb012f7 100644
313--- a/tests/glob.tests
314+++ b/tests/glob.tests
315@@ -12,6 +12,8 @@ ${THIS_SH} ./glob1.sub
316 ${THIS_SH} ./glob2.sub
317 ${THIS_SH} ./glob3.sub
318 ${THIS_SH} ./glob4.sub
319+${THIS_SH} ./glob6.sub
320+${THIS_SH} ./glob7.sub
321
322 MYDIR=$PWD # save where we are
323
324diff --git a/tests/glob6.sub b/tests/glob6.sub
325new file mode 100644
326index 0000000..b099811
327--- /dev/null
328+++ b/tests/glob6.sub
329@@ -0,0 +1,54 @@
330+# tests of the backslash-in-glob-patterns discussion on the austin-group ML
331+
332+: ${TMPDIR:=/var/tmp}
333+
334+ORIG=$PWD
335+GLOBDIR=$TMPDIR/bash-glob-$$
336+mkdir $GLOBDIR && cd $GLOBDIR
337+
338+# does the pattern matcher allow backslashes as escape characters and remove
339+# them as part of matching?
340+touch abcdefg
341+pat='ab\cd*'
342+printf '<%s>\n' $pat
343+pat='\.'
344+printf '<%s>\n' $pat
345+rm abcdefg
346+
347+# how about when escaping pattern characters?
348+touch '*abc.c'
349+a='\**.c'
350+printf '%s\n' $a
351+rm -f '*abc.c'
352+
353+# how about when making the distinction between readable and searchable path
354+# components?
355+mkdir -m a=x searchable
356+mkdir -m a=r readable
357+
358+p='searchable/\.'
359+printf "%s\n" $p
360+
361+p='searchable/\./.'
362+printf "%s\n" $p
363+
364+p='readable/\.'
365+printf "%s\n" $p
366+
367+p='readable/\./.'
368+printf "%s\n" $p
369+
370+printf "%s\n" 'searchable/\.'
371+printf "%s\n" 'readable/\.'
372+
373+echo */.
374+
375+p='*/\.'
376+echo $p
377+
378+echo */'.'
379+
380+rmdir searchable readable
381+
382+cd $ORIG
383+rmdir $GLOBDIR
384diff --git a/tests/glob7.sub b/tests/glob7.sub
385new file mode 100644
386index 0000000..0212b8e
387--- /dev/null
388+++ b/tests/glob7.sub
389@@ -0,0 +1,11 @@
390+# according to Posix 2.13.3, a slash in a bracket expression renders that
391+# bracket expression invalid
392+shopt -s nullglob
393+
394+echo 1: [qwe/qwe]
395+echo 2: [qwe/
396+echo 3: [qwe/]
397+
398+echo 4: [qwe\/qwe]
399+echo 5: [qwe\/
400+echo 6: [qwe\/]
401--
4021.9.1
diff --git a/meta/recipes-extended/bash/bash_5.0.bb b/meta/recipes-extended/bash/bash_5.0.bb
index eadc82279d..1b7058746f 100644
--- a/meta/recipes-extended/bash/bash_5.0.bb
+++ b/meta/recipes-extended/bash/bash_5.0.bb
@@ -19,6 +19,7 @@ SRC_URI = "${GNU_MIRROR}/bash/${BP}.tar.gz;name=tarball \
19 file://run-ptest \ 19 file://run-ptest \
20 file://run-bash-ptests \ 20 file://run-bash-ptests \
21 file://fix-run-builtins.patch \ 21 file://fix-run-builtins.patch \
22 file://bash-CVE-2019-18276.patch \
22 " 23 "
23 24
24SRC_URI[tarball.md5sum] = "2b44b47b905be16f45709648f671820b" 25SRC_URI[tarball.md5sum] = "2b44b47b905be16f45709648f671820b"