fix for internal redirection flags colliding with open/fcntl flags; call memfd_create with MFD_NOEXEC_SEAL; fix for setting $BASH in su-started login shell; fix for unsetting $REPLY after nofork comsubs

This commit is contained in:
Chet Ramey
2024-05-01 11:39:51 -04:00
parent 9c430f6bf3
commit 1f42d15864
17 changed files with 118 additions and 357 deletions
+3
View File
@@ -148,6 +148,9 @@ lib/readline/doc/rluserman.tp
lib/readline/doc/rluserman.vr
lib/readline/doc/rluserman.vrs
doc/oldbash.texi
doc/newbash.texi
# example loadable builtins
examples/loadables/accept
+46
View File
@@ -9231,3 +9231,49 @@ support/bashversion.c,version.c
support/printenv.c,support/recho.c,support/xcase.c,support/zecho.c
- now assumes a C90 compilation environment and POSIX.1-1990 execution
environment
4/26
----
redir.h
- RX_INTERNAL, RX_USER (unused), RX_SAVCLEXEC, RX_SAVEFD, RX_EXPANDED:
new values starting at 0x80, now intended for rflags member of a
struct redirect; don't want them colliding with O_XX flags for open
and fcntl
redir.c
- rflags: save redirect->rflags and pass it to make_redirection if
we're translating a redirection into a new one
- new_redirect: pass rflags to all calls to make_redirection now that
it holds more than REDIR_VARASSIGN
- RX_INTERNAL, RX_USER (unused), RX_SAVCLEXEC, RX_SAVEFD, RX_EXPANDED:
check and assign these in the rflags member; they're only used here
- do_redirection_internal: assign new_redirect->rflags back to
redirect->rflags since it can possibly be modified with RX_EXPANDED
- do_redirection_internal: take care not to leave REDIR_VARASSIGN in
new_redirect->rflags, since it will cause redirector to be freed,
leading to accessing freed memory
From a report by Clark Wang <dearvoid@gmail.com> and a hint from
<oguzismailuysal@gmail.com> and Grisha Levit <grishalevit@gmail.com>
4/28
----
lib/sh/anonfile.c
- anonopen: call memfd_create with MFD_NOEXEC_SEAL
From a report by Kerin Millar <kfm@plushkava.net>
4/29
----
shell.c,shell.h
- su_shell: now global
variables.c
- get_bash_name: use the user's login shell for $BASH if the shell is
a login shell and the name is "-su".
From https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1069978
subst.c
- uw_unbind_localvar: unwind-protect to unbind a local variable at
the current function context
- function_substitute: make sure we unbind the local REPLY we created
at the current (fake) context
From a report by Koichi Murase <myoga.murase@gmail.com>
-80
View File
@@ -1,80 +0,0 @@
This file is inlib.def, from which is created inlib.c.
It implements the Apollo-specific builtin "inlib" in Bash.
Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
$PRODUCES inlib.c
#include <config.h>
#include <stdio.h>
#include "../shell.h"
$BUILTIN inlib
$FUNCTION inlib_builtin
$DEPENDS_ON apollo
$SHORT_DOC inlib pathname [pathname...]
Install user-supplied library.
Install a user-supplied library specified by pathname in the current
shell process. The library is used to resolve external references
in programs and libraries loaded after its installation. Note
that the library is not loaded into the address space unless it is
needed to resolve an external reference. The list of inlibed
libraries is passed to all children of the current shell.
Exit Status:
Returns success unless PATHNAME is not found or an error occurs.
$END
#if defined (apollo)
#include <apollo/base.h>
#include <apollo/loader.h>
inlib_builtin (list)
WORD_LIST *list;
{
status_$t status;
int return_value;
short len;
if (!list)
{
builtin_usage ();
return (EX_USAGE);
}
return_value = EXECUTION_SUCCESS;
while (list)
{
len = (short)strlen (list->word->word);
loader_$inlib (list->word->word, len, &status);
if (status.all != status_$ok)
{
builtin_error (_("%s: inlib failed"), list->word->word);
return_value = EXECUTION_FAILURE;
}
list = list->next;
}
return (return_value);
}
#endif /* apollo */
-3
View File
@@ -1,3 +0,0 @@
You are a software developer writing a widely-user open source software package. You are discussing a new feature with a user. Write an email declining the user's proposal because it is too complicated.
+1 -2
View File
@@ -763,8 +763,7 @@ The words between the \fB[[\fP and \fB]]\fP do not undergo word splitting
and pathname expansion.
The shell performs tilde expansion, parameter and
variable expansion, arithmetic expansion, command substitution, process
substitution, and quote removal on those words
(the expansions that would occur if the words were enclosed in double quotes).
substitution, and quote removal on those words.
Conditional operators such as \fB\-f\fP must be unquoted to be recognized
as primaries.
.IP
+1 -2
View File
@@ -1154,8 +1154,7 @@ The words between the @code{[[} and @code{]]} do not undergo word splitting
and filename expansion.
The shell performs tilde expansion, parameter and
variable expansion, arithmetic expansion, command substitution, process
substitution, and quote removal on those words
(the expansions that would occur if the words were enclosed in double quotes).
substitution, and quote removal on those words.
Conditional operators such as @samp{-f} must be unquoted to be recognized
as primaries.
-44
View File
@@ -1,44 +0,0 @@
#! /bin/sh
#
# mkinstall - make the INSTALL file from the `Installing Bash' node of the
# texinfo manual
#
NODE="Installing Bash"
SUBNODE="Basic Installation"
TEXI=bashref.texi
TMPINFO=temp.info
TMPOUT=INSTALL.tmp
OUT=${1:-INSTALL}
trap 'rm -f $TMPOUT $TMPINFO $OUT; trap '' 0; exit 1' 1 2 3 6 15
#trap 'rm -f $TMPOUT $TMPINFO' 0
# create an info file without paragraph indentation
makeinfo --no-split -I../lib/readline/doc --paragraph-indent 0 -o $TMPINFO $TEXI
# write out the text from the `Installing Bash' node to INSTALL.tmp
info --file $TMPINFO --node "$NODE" --subnodes --output $TMPOUT
exit 0
# remove the info traversal information and the initial menu, and squeeze
# out multiple consecutive blank lines like `cat -s'
awk 'BEGIN { printline = 0; newlines = 0; }
/^File: '$TMPINFO'/ { next; }
/^'"$SUBNODE"'/ { printline = 1; }
/^$/ { if (printline) newlines = 1; next; }
/$/ { if (printline) {
if (newlines) {
printf "\n";
newlines = 0;
}
print $0;
}
}' < $TMPOUT > $OUT
exit 0
-127
View File
@@ -1,127 +0,0 @@
1\input texinfo @c -*- texinfo -*-
@c %**start of header
@setfilename bash.info
@settitle GNU Bourne Again SHell
@setchapternewpage odd
@c %**end of header
@c DON'T RUN FINALOUT YET UNTIL FINAL STAGES
@ignore
@iftex
@finalout
@end iftex
@end ignore
@ifinfo
This file documents the GNU Bourne Again SHell.
Copyright @copyright{} 1992 Free Software Foundation, Inc.
@end ifinfo
@titlepage
@sp 10
@center @titlefont{GNU Bash, the Bourne Again SHell}
@center Unproofed Draft
@sp 10
@center Brian Fox, Chet Ramey
@center @today{}
@page
This document describes GNU Bash, a Bourne shell compatible
command language interpreter which executes commands read from the
standard input or from a file.
Published by the Free Software Foundation @*
675 Massachusetts Avenue, @*
Cambridge, MA 02139 USA
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions,
except that this permission notice may be stated in a translation approved
by the Foundation.
@vskip 0pt plus 1filll
Copyright @copyright{} 1992 Free Software Foundation, Inc.
@end titlepage
@ifinfo
This document describes GNU Bash, a Bourne shell compatible
command language interpreter which executes commands read from the
standard input or from a file.
Published by the Free Software Foundation @*
675 Massachusetts Avenue, @*
Cambridge, MA 02139 USA
@ignore
Permission is granted to process this file through TeX and print the
results, provided the printed document carries copying permission
notice identical to this one except for the removal of this paragraph
(this paragraph not being relevant to the printed manual).
@end ignore
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions,
except that this permission notice may be stated in a translation approved
by the Foundation.
@end ifinfo
I Tutorial
i Describe what Bash does.
1) What a shell is for.
2) How Bash is different from other shells.
ii Superficial description of how the shell works.
1) Parts of a command.
a) Command words.
b) Command separators.
c) Redirection words.
iii Hands on Experience.
1) Starting a shell.
a) startup files.
b) switching from Csh.
Using alias.conv
2) The Environment.
a) Description of "environment".
b) Some important environment variables.
c) Other common environment variables.
3) Issuing command lines.
a) Example
II Reference
i Shell Syntax
1) Parts of "speech".
a) Command Words.
b) Command Seprators.
c) Redirection Words.
2) Quoting Syntax.
3) Common Idioms.
ii Guide by feature.
1) Builtins.
2) Variables.
ii Guide by task.
III Indices
i
+5 -1
View File
@@ -37,6 +37,10 @@
static int anonunlink (const char *);
#if defined (HAVE_MEMFD_CREATE) && !defined (MFD_NOEXEC_SEAL)
# define MFD_NOEXEC_SEAL 0
#endif
#if defined (HAVE_SHM_OPEN)
#ifndef O_NOFOLLOW
# define O_NOFOLLOW 0
@@ -104,7 +108,7 @@ anonopen (const char *name, int flags, char **fn)
#if defined (HAVE_MEMFD_CREATE)
/* "Names do not affect the behavior of the file descriptor." */
fd = memfd_create ("anonopen", 0);
fd = memfd_create ("anonopen", MFD_NOEXEC_SEAL);
if (fd >= 0)
{
if (fn)
+36 -23
View File
@@ -761,7 +761,7 @@ static int
do_redirection_internal (REDIRECT *redirect, int flags, char **fnp)
{
WORD_DESC *redirectee;
int redir_fd, fd, redirector, r, oflags;
int redir_fd, fd, redirector, r, oflags, rflags;
intmax_t lfd;
char *redirectee_word;
enum r_instruction ri;
@@ -773,8 +773,7 @@ do_redirection_internal (REDIRECT *redirect, int flags, char **fnp)
redirector = redirect->redirector.dest;
ri = redirect->instruction;
if (redirect->flags & RX_INTERNAL)
flags |= RX_INTERNAL;
rflags = redirect->rflags; /* for new redirection */
if (TRANSLATE_REDIRECT (ri))
{
@@ -789,7 +788,7 @@ do_redirection_internal (REDIRECT *redirect, int flags, char **fnp)
{
sd = redirect->redirector;
rd.dest = 0;
new_redirect = make_redirection (sd, r_close_this, rd, 0);
new_redirect = make_redirection (sd, r_close_this, rd, rflags);
}
else if (redirectee_word == 0)
return (AMBIGUOUS_REDIRECT);
@@ -797,7 +796,7 @@ do_redirection_internal (REDIRECT *redirect, int flags, char **fnp)
{
sd = redirect->redirector;
rd.dest = 0;
new_redirect = make_redirection (sd, r_close_this, rd, 0);
new_redirect = make_redirection (sd, r_close_this, rd, rflags);
}
else if (all_digits (redirectee_word))
{
@@ -809,16 +808,16 @@ do_redirection_internal (REDIRECT *redirect, int flags, char **fnp)
switch (ri)
{
case r_duplicating_input_word:
new_redirect = make_redirection (sd, r_duplicating_input, rd, 0);
new_redirect = make_redirection (sd, r_duplicating_input, rd, rflags);
break;
case r_duplicating_output_word:
new_redirect = make_redirection (sd, r_duplicating_output, rd, 0);
new_redirect = make_redirection (sd, r_duplicating_output, rd, rflags);
break;
case r_move_input_word:
new_redirect = make_redirection (sd, r_move_input, rd, 0);
new_redirect = make_redirection (sd, r_move_input, rd, rflags);
break;
case r_move_output_word:
new_redirect = make_redirection (sd, r_move_output, rd, 0);
new_redirect = make_redirection (sd, r_move_output, rd, rflags);
break;
default:
break; /* shut up gcc */
@@ -828,8 +827,8 @@ do_redirection_internal (REDIRECT *redirect, int flags, char **fnp)
{
sd = redirect->redirector;
rd.filename = make_bare_word (redirectee_word);
new_redirect = make_redirection (sd, r_err_and_out, rd, 0);
new_redirect->flags |= RX_EXPANDED; /* we already expanded this */
new_redirect = make_redirection (sd, r_err_and_out, rd, rflags);
new_redirect->rflags |= RX_EXPANDED; /* we already expanded this */
}
else
{
@@ -864,8 +863,22 @@ do_redirection_internal (REDIRECT *redirect, int flags, char **fnp)
redirector = new_redirect->redirector.dest;
ri = new_redirect->instruction;
/* Overwrite the flags element of the old redirect with the new value. */
/* Overwrite the flags elements of the old redirect with the new values. */
redirect->flags = new_redirect->flags;
redirect->rflags = new_redirect->rflags;
/* In all these cases, we don't duplicate redirect->redirector into
new_redirect; we just assign sd (see make_cmd.c:make_redirection()).
We don't want to dispose the word here, since that will invalidate
redirect->redirector (see dispose_cmd.c:dispose_redirect()). So we
set it to NULL and turn off REDIR_VARASSIGN so dispose_redirect()
won't try to free it. */
if (rflags & REDIR_VARASSIGN)
{
new_redirect->redirector.filename = 0;
new_redirect->rflags &= ~REDIR_VARASSIGN;
}
dispose_redirects (new_redirect);
}
@@ -884,7 +897,7 @@ do_redirection_internal (REDIRECT *redirect, int flags, char **fnp)
oflags = redirectee->flags;
redirectee->flags |= W_NOGLOB;
}
if ((redirect->flags & RX_EXPANDED) == 0)
if ((redirect->rflags & RX_EXPANDED) == 0)
redirectee_word = redirection_expand (redirectee);
else
redirectee_word = savestring (redirectee->word);
@@ -1157,7 +1170,7 @@ do_redirection_internal (REDIRECT *redirect, int flags, char **fnp)
if (((fcntl (redir_fd, F_GETFD, 0) == 1) || redir_fd < 2 || (flags & RX_CLEXEC)) &&
(redirector > 2))
#else
if (((fcntl (redir_fd, F_GETFD, 0) == 1) || (redir_fd < 2 && (flags & RX_INTERNAL)) || (flags & RX_CLEXEC)) &&
if (((fcntl (redir_fd, F_GETFD, 0) == 1) || (redir_fd < 2 && (rflags & RX_INTERNAL)) || (flags & RX_CLEXEC)) &&
(redirector > 2))
#endif
SET_CLOSE_ON_EXEC (redirector);
@@ -1166,7 +1179,7 @@ do_redirection_internal (REDIRECT *redirect, int flags, char **fnp)
file descriptors >= SHELL_FD_BASE, we set the saving fd to be
close-on-exec and use a flag to decide how to set close-on-exec
when the fd is restored. */
if ((redirect->flags & RX_INTERNAL) && (redirect->flags & RX_SAVCLEXEC) && redirector >= 3 && (redir_fd >= SHELL_FD_BASE || (redirect->flags & RX_SAVEFD)))
if ((rflags & RX_INTERNAL) && (rflags & RX_SAVCLEXEC) && redirector >= 3 && (redir_fd >= SHELL_FD_BASE || (rflags & RX_SAVEFD)))
SET_OPEN_ON_EXEC (redirector);
/* dup-and-close redirection */
@@ -1212,7 +1225,7 @@ do_redirection_internal (REDIRECT *redirect, int flags, char **fnp)
check_bash_input (redirector);
r = close_buffered_fd (redirector);
if (r < 0 && (flags & RX_INTERNAL) && (errno == EIO || errno == ENOSPC))
if (r < 0 && (rflags & RX_INTERNAL) && (errno == EIO || errno == ENOSPC))
REDIRECTION_ERROR (r, errno, -1);
}
break;
@@ -1266,7 +1279,7 @@ add_undo_redirect (int fd, enum r_instruction ri, int fdbase)
sd.dest = new_fd;
rd.dest = 0;
closer = make_redirection (sd, r_close_this, rd, 0);
closer->flags |= RX_INTERNAL;
closer->rflags |= RX_INTERNAL;
dummy_redirect = copy_redirects (closer);
sd.dest = fd;
@@ -1275,11 +1288,11 @@ add_undo_redirect (int fd, enum r_instruction ri, int fdbase)
new_redirect = make_redirection (sd, r_duplicating_input, rd, 0);
else
new_redirect = make_redirection (sd, r_duplicating_output, rd, 0);
new_redirect->flags |= RX_INTERNAL;
new_redirect->rflags |= RX_INTERNAL;
if (savefd_flag)
new_redirect->flags |= RX_SAVEFD;
new_redirect->rflags |= RX_SAVEFD;
if (clexec_flag == 0 && fd >= 3 && (new_fd >= SHELL_FD_BASE || savefd_flag))
new_redirect->flags |= RX_SAVCLEXEC;
new_redirect->rflags |= RX_SAVCLEXEC;
new_redirect->next = closer;
closer->next = redirection_undo_list;
@@ -1302,7 +1315,7 @@ add_undo_redirect (int fd, enum r_instruction ri, int fdbase)
sd.dest = fd;
rd.dest = new_fd;
new_redirect = make_redirection (sd, r_duplicating_output, rd, 0);
new_redirect->flags |= RX_INTERNAL;
new_redirect->rflags |= RX_INTERNAL;
add_exec_redirect (new_redirect);
}
@@ -1317,7 +1330,7 @@ add_undo_redirect (int fd, enum r_instruction ri, int fdbase)
and the restore above in do_redirection() will take care of it. */
if (clexec_flag || fd < 3)
SET_CLOSE_ON_EXEC (new_fd);
else if (redirection_undo_list->flags & RX_SAVCLEXEC)
else if (redirection_undo_list->rflags & RX_SAVCLEXEC)
SET_CLOSE_ON_EXEC (new_fd);
return (0);
@@ -1334,7 +1347,7 @@ add_undo_close_redirect (int fd)
sd.dest = fd;
rd.dest = 0;
closer = make_redirection (sd, r_close_this, rd, 0);
closer->flags |= RX_INTERNAL;
closer->rflags |= RX_INTERNAL;
closer->next = redirection_undo_list;
redirection_undo_list = closer;
+8 -5
View File
@@ -27,11 +27,14 @@
#define RX_ACTIVE 0x01 /* do it; don't just go through the motions */
#define RX_UNDOABLE 0x02 /* make a list to undo these redirections */
#define RX_CLEXEC 0x04 /* set close-on-exec for opened fds > 2 */
#define RX_INTERNAL 0x08
#define RX_USER 0x10
#define RX_SAVCLEXEC 0x20 /* set close-on-exec off in restored fd even though saved on has it on */
#define RX_SAVEFD 0x40 /* fd used to save another even if < SHELL_FD_BASE */
#define RX_EXPANDED 0x80 /* this redirection has already been expanded */
/* Values for rflags member of struct redirect; low seven bits reserved
(see REDIR_VARASSIGN in command.h) */
#define RX_INTERNAL 0x0080
#define RX_USER 0x0100
#define RX_SAVCLEXEC 0x0200 /* set close-on-exec off in restored fd even though saved on has it on */
#define RX_SAVEFD 0x0400 /* fd used to save another even if < SHELL_FD_BASE */
#define RX_EXPANDED 0x0800 /* this redirection has already been expanded */
extern void redirection_error (REDIRECT *, int, char *);
extern int do_redirections (REDIRECT *, int);
+3 -3
View File
@@ -134,6 +134,9 @@ char *current_host_name = (char *)NULL;
*/
int login_shell = 0;
/* Non-zero if this shell is being run by `su'. */
int su_shell = 0;
/* Non-zero means that at this moment, the shell is interactive. In
general, this means that the shell is at this moment reading input
from the keyboard. */
@@ -205,9 +208,6 @@ static char *bashrc_file;
/* Non-zero means to act more like the Bourne shell on startup. */
static int act_like_sh;
/* Non-zero if this shell is being run by `su'. */
static int su_shell;
/* Non-zero if we have already expanded and sourced $ENV. */
static int sourced_env;
+3 -1
View File
@@ -96,7 +96,9 @@ extern WORD_LIST *rest_of_args;
extern char *command_execution_string;
extern int debugging_mode;
extern int executing, login_shell;
extern int executing;
extern int login_shell;
extern int su_shell;
extern int parsing_command;
extern int interactive, interactive_shell;
extern int startup_state;
+11 -1
View File
@@ -6897,6 +6897,16 @@ uw_unbind_variable (void *name)
unbind_variable_noref (name);
}
static void
uw_unbind_localvar (void *name)
{
SHELL_VAR *v;
v = find_variable_noref (name);
if (v && local_p (v) && v->context == variable_context)
makunbound (name, shell_variables);
}
static void
uw_restore_pipeline (void *discard)
{
@@ -7075,7 +7085,7 @@ function_substitute (char *string, int quoted, int flags)
v = make_local_variable ("REPLY", 0); /* should be new instance */
/* We don't check $REPLY for readonly yet, but we could */
if (v)
add_unwind_protect (uw_unbind_variable, "REPLY");
add_unwind_protect (uw_unbind_localvar, "REPLY");
}
old_frozen = freeze_jobs_list ();
-8
View File
@@ -1,8 +0,0 @@
FROM alpine:3.17
RUN apk add --no-cache bison coreutils gcc libc-dev make
ncurses-dev libncurses5-dev libncursesw5-dev
WORKDIR /tmp/bash
COPY . .
RUN ./configure --enable-readline --with-curses
RUN make
RUN make tests
-56
View File
@@ -1,56 +0,0 @@
#! /bin/sh
#
# relicense - change copyrights between GPL2 and GPL3
#
# usage: relicense [n]
#
# n is `2' or `3'. The default `n' is 2
#
# Chet Ramey
# chet.ramey@case.edu
#
SRC=/usr/homes/chet/src/bash/src
V=2
if [ ! -f parse.y ]; then
echo "relicense: must be run from source directory to be relicensed" >&2
exit 2
fi
case "$1" in
2) V=2 ;;
3) V=3 ;;
"") ;;
*) echo "relicense: usage: relicense [2|3]" >&2 ; exit 2 ;;
esac
LIC2="version 2 of the License"
LIC3="version 3 of the License"
VS2='GPLv2+: GNU GPL version 2 or later'
VS3='GPLv3+: GNU GPL version 3 or later'
case "$V" in
2) PAT1="$LIC3" REP1="$LIC2" PAT2="$VS3" REP2="$VS2" ;;
3) PAT1="$LIC2" REP1="$LIC3" PAT2="$VS2" REP2="$VS3" ;;
esac
find . -type f -print |
while read fn ; do
BASE=${fn##*/}
sed -e "s|$PAT1|$REP1|g" -e "s|$PAT2|$REP2|g" < $fn > /tmp/$BASE && touch -r $fn /tmp/$BASE
cmp -s /tmp/$BASE $fn || mv /tmp/$BASE $fn
echo $fn
rm -f /tmp/$BASE
done
echo "relicense: copying appropriate license file"
case "$V" in
2) cp -p $SRC/COPYINGv2 COPYING
cp -p $SRC/COPYINGv2 lib/readline/COPYING ;;
3) cp -p $SRC/COPYINGv3 COPYING
cp -p $SRC/COPYINGv3 lib/readline/COPYING ;;
esac
exit 0
+1 -1
View File
@@ -776,7 +776,7 @@ get_bash_name (void)
{
char *name;
if ((login_shell == 1) && RELPATH(shell_name))
if ((login_shell == 1) && su_shell)
{
if (current_user.shell == 0)
get_current_user_info ();