diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 4ae6b56dd..f9a92c466 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -6167,3 +6167,37 @@ doc/{bash.1,bashref.texi} - pathname expansion: note that under some circumstances the shell will invoke the matching engine for words with unquoted backslashes - posixglob: document the new shell option and its effects + + 6/27 + ---- +{config.h.in,configure.ac} + - setresuid,setresgid: check and set HAVE_{DECL,}_SETRES[UG]ID as + appropriate + +shell.c + - disable_priv_mode: if we have setres[ug]id, use them over + set[ug]id, which only set the save user-id and group-id if the + process is running as root. From Ian Eldred Pudney + in https://savannah.gnu.org/patch/?9822 + + 6/28 + ---- +lib/glob/glob.c + - glob_vector: don't bother trying to read the directory if the filename + pattern doesn't have any globbing characters except backslash; just + dequote the pattern and try to lstat(2) it as if there were no + globbing characters at all. From an austingroup-bugs discussion + message from Stephane Chazelas + +bashline.c + - completion_glob_pattern: just call glob_pattern_p and make sure it + returns 1 (non-backslash globbing characters) + +builtins/help.def + - help_builtin: don't try pattern matching the help topic argument + unless glob_pattern_p returns 1 + +pathexp.c + - unquoted_glob_pattern_p: when in a bracket expression (open > 0), + don't allow an unquoted slash as part of the bracket expression. + Report from Stephane Chazelas diff --git a/MANIFEST b/MANIFEST index ac2d288f9..75c1ef902 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1100,6 +1100,8 @@ tests/glob2.sub f tests/glob3.sub f tests/glob4.sub f tests/glob5.sub f +tests/glob6.sub f +tests/glob7.sub f tests/glob.right f tests/globstar.tests f tests/globstar.right f diff --git a/bashline.c b/bashline.c index 81bc214d4..dc976525b 100644 --- a/bashline.c +++ b/bashline.c @@ -3846,55 +3846,7 @@ static int completion_glob_pattern (string) char *string; { - register int c; - char *send; - int open; - - DECLARE_MBSTATE; - - open = 0; - send = string + strlen (string); - - while (c = *string++) - { - switch (c) - { - case '?': - case '*': - return (1); - - case '[': - open++; - continue; - - case ']': - if (open) - return (1); - continue; - - case '+': - case '@': - case '!': - if (*string == '(') /*)*/ - return (1); - continue; - - case '\\': - if (*string++ == 0) - return (0); - } - - /* Advance one fewer byte than an entire multibyte character to - account for the auto-increment in the loop above. */ -#ifdef HANDLE_MULTIBYTE - string--; - ADVANCE_CHAR_P (string, send - string); - string++; -#else - ADVANCE_CHAR_P (string, send - string); -#endif - } - return (0); + return (glob_pattern_p (string) == 1); } static char *globtext; diff --git a/builtins/help.def b/builtins/help.def index 006c4b5d1..92f9b382a 100644 --- a/builtins/help.def +++ b/builtins/help.def @@ -128,7 +128,7 @@ help_builtin (list) /* We should consider making `help bash' do something. */ - if (glob_pattern_p (list->word->word)) + if (glob_pattern_p (list->word->word) == 1) { printf ("%s", ngettext ("Shell commands matching keyword `", "Shell commands matching keywords `", (list->next ? 2 : 1))); print_word_list (list, ", "); diff --git a/config.h.in b/config.h.in index d8f5b8824..92633057e 100644 --- a/config.h.in +++ b/config.h.in @@ -1,6 +1,6 @@ /* config.h -- Configuration file for bash. */ -/* Copyright (C) 1987-2009,2011-2012 Free Software Foundation, Inc. +/* Copyright (C) 1987-2009,2011-2012,2013-2019 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -813,6 +813,14 @@ #undef HAVE_SETREGID #undef HAVE_DECL_SETREGID +/* Define if you have the setregid function. */ +#undef HAVE_SETRESGID +#undef HAVE_DECL_SETRESGID + +/* Define if you have the setresuid function. */ +#undef HAVE_SETRESUID +#undef HAVE_DECL_SETRESUID + /* Define if you have the setvbuf function. */ #undef HAVE_SETVBUF diff --git a/configure b/configure index 08a9c16d4..8f37d2af0 100755 --- a/configure +++ b/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.ac for Bash 5.0, version 5.010. +# From configure.ac for Bash 5.0, version 5.011. # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for bash 5.0-maint. # @@ -14239,6 +14239,17 @@ cat >>confdefs.h <<_ACEOF #define HAVE_DECL_SETREGID $ac_have_decl _ACEOF +ac_fn_c_check_decl "$LINENO" "" "ac_cv_have_decl_" "$ac_includes_default" +if test "x$ac_cv_have_decl_" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_ $ac_have_decl +_ACEOF +(setresuid, setresgid) ac_fn_c_check_decl "$LINENO" "strcpy" "ac_cv_have_decl_strcpy" "$ac_includes_default" if test "x$ac_cv_have_decl_strcpy" = xyes; then : ac_have_decl=1 diff --git a/configure.ac b/configure.ac index 400089cdc..84de396b8 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ dnl Process this file with autoconf to produce a configure script. # You should have received a copy of the GNU General Public License # along with this program. If not, see . -AC_REVISION([for Bash 5.0, version 5.010])dnl +AC_REVISION([for Bash 5.0, version 5.011])dnl define(bashvers, 5.0) define(relstatus, maint) @@ -850,6 +850,7 @@ AC_CHECK_DECLS([confstr]) AC_CHECK_DECLS([printf]) AC_CHECK_DECLS([sbrk]) AC_CHECK_DECLS([setregid]) +AC_CHECK_DECLS[(setresuid, setresgid]) AC_CHECK_DECLS([strcpy]) AC_CHECK_DECLS([strsignal]) diff --git a/doc/bash.1 b/doc/bash.1 index f25be1035..fc243aceb 100644 --- a/doc/bash.1 +++ b/doc/bash.1 @@ -4702,7 +4702,8 @@ above). .PD .SH "SIMPLE COMMAND EXPANSION" When a simple command is executed, the shell performs the following -expansions, assignments, and redirections, from left to right. +expansions, assignments, and redirections, from left to right, in +the following order. .IP 1. The words that the parser has marked as variable assignments (those preceding the command name) and redirections are saved for later diff --git a/doc/bashref.texi b/doc/bashref.texi index 14367ec17..00ce43f37 100644 --- a/doc/bashref.texi +++ b/doc/bashref.texi @@ -2968,7 +2968,8 @@ is not specified. If the file does not exist, it is created. @cindex command expansion When a simple command is executed, the shell performs the following -expansions, assignments, and redirections, from left to right. +expansions, assignments, and redirections, from left to right, in +the following order. @enumerate @item diff --git a/lib/glob/glob.c b/lib/glob/glob.c index e1cbce28b..b7f2d8307 100644 --- a/lib/glob/glob.c +++ b/lib/glob/glob.c @@ -634,6 +634,7 @@ glob_vector (pat, dir, flags) register unsigned int i; int mflags; /* Flags passed to strmatch (). */ int pflags; /* flags passed to sh_makepath () */ + int hasglob; /* return value from glob_pattern_p */ int nalloca; struct globval *firstmalloc, *tmplink; char *convfn; @@ -675,10 +676,12 @@ glob_vector (pat, dir, flags) patlen = (pat && *pat) ? strlen (pat) : 0; /* If the filename pattern (PAT) does not contain any globbing characters, + or contains a pattern with only backslash escapes (hasglob == 2), we can dispense with reading the directory, and just see if there is a filename `DIR/PAT'. If there is, and we can access it, just make the vector to return and bail immediately. */ - if (skip == 0 && glob_pattern_p (pat) == 0) + hasglob = 0; + if (skip == 0 && (hasglob = glob_pattern_p (pat)) == 0 || hasglob == 2) { int dirlen; struct stat finfo; diff --git a/pathexp.c b/pathexp.c index eee5dad80..0c2ab273c 100644 --- a/pathexp.c +++ b/pathexp.c @@ -61,7 +61,10 @@ int glob_star = 0; /* Do we handle backslashes in patterns the way Posix specifies? */ int posix_glob_backslash = 1; -/* Return nonzero if STRING has any unquoted special globbing chars in it. */ +/* Return nonzero if STRING has any unquoted special globbing chars in it. + This is supposed to be called when pathname expansion is performed, so + it implements the rules in Posix 2.13.3, specifically that an unquoted + slash cannot appear in a bracket expression. */ int unquoted_glob_pattern_p (string) register char *string; @@ -88,10 +91,14 @@ unquoted_glob_pattern_p (string) continue; case ']': - if (open) + if (open) /* XXX - if --open == 0? */ return (1); continue; + case '/': + if (open) + open = 0; + case '+': case '@': case '!': @@ -109,6 +116,11 @@ unquoted_glob_pattern_p (string) string++; continue; } + else if (open && *string == '/') + { + string++; /* quoted slashes in bracket expressions are ok */ + continue; + } else if (*string == 0) return (0); diff --git a/shell.c b/shell.c index c82b815a5..cfaf73f3e 100644 --- a/shell.c +++ b/shell.c @@ -1293,7 +1293,11 @@ disable_priv_mode () { int e; +#if HAVE_DECL_SETRESUID + if (setresuid (current_user.uid, current_user.uid, current_user.uid) < 0) +#else if (setuid (current_user.uid) < 0) +#endif { e = errno; sys_error (_("cannot set uid to %d: effective uid %d"), current_user.uid, current_user.euid); @@ -1302,7 +1306,11 @@ disable_priv_mode () exit (e); #endif } +#if HAVE_DECL_SETRESGID + if (setresgid (current_user.gid, current_user.gid, current_user.gid) < 0) +#else if (setgid (current_user.gid) < 0) +#endif sys_error (_("cannot set gid to %d: effective gid %d"), current_user.gid, current_user.egid); current_user.euid = current_user.uid; diff --git a/tests/glob.tests b/tests/glob.tests index a40dbbbbc..dc86437e2 100644 --- a/tests/glob.tests +++ b/tests/glob.tests @@ -13,6 +13,8 @@ ${THIS_SH} ./glob2.sub ${THIS_SH} ./glob3.sub ${THIS_SH} ./glob4.sub ${THIS_SH} ./glob5.sub +${THIS_SH} ./glob6.sub +${THIS_SH} ./glob7.sub MYDIR=$PWD # save where we are diff --git a/tests/glob6.sub b/tests/glob6.sub new file mode 100644 index 000000000..b099811db --- /dev/null +++ b/tests/glob6.sub @@ -0,0 +1,54 @@ +# tests of the backslash-in-glob-patterns discussion on the austin-group ML + +: ${TMPDIR:=/var/tmp} + +ORIG=$PWD +GLOBDIR=$TMPDIR/bash-glob-$$ +mkdir $GLOBDIR && cd $GLOBDIR + +# does the pattern matcher allow backslashes as escape characters and remove +# them as part of matching? +touch abcdefg +pat='ab\cd*' +printf '<%s>\n' $pat +pat='\.' +printf '<%s>\n' $pat +rm abcdefg + +# how about when escaping pattern characters? +touch '*abc.c' +a='\**.c' +printf '%s\n' $a +rm -f '*abc.c' + +# how about when making the distinction between readable and searchable path +# components? +mkdir -m a=x searchable +mkdir -m a=r readable + +p='searchable/\.' +printf "%s\n" $p + +p='searchable/\./.' +printf "%s\n" $p + +p='readable/\.' +printf "%s\n" $p + +p='readable/\./.' +printf "%s\n" $p + +printf "%s\n" 'searchable/\.' +printf "%s\n" 'readable/\.' + +echo */. + +p='*/\.' +echo $p + +echo */'.' + +rmdir searchable readable + +cd $ORIG +rmdir $GLOBDIR diff --git a/tests/glob7.sub b/tests/glob7.sub new file mode 100644 index 000000000..0212b8e59 --- /dev/null +++ b/tests/glob7.sub @@ -0,0 +1,11 @@ +# according to Posix 2.13.3, a slash in a bracket expression renders that +# bracket expression invalid +shopt -s nullglob + +echo 1: [qwe/qwe] +echo 2: [qwe/ +echo 3: [qwe/] + +echo 4: [qwe\/qwe] +echo 5: [qwe\/ +echo 6: [qwe\/]