Bug 1494 - doesn't look on path for $SHELL
Summary: doesn't look on path for $SHELL
Status: CLOSED WONTFIX
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: ssh (show other bugs)
Version: 5.1p1
Hardware: Other Linux
: P2 normal
Assignee: Assigned to nobody
URL: http://bugs.debian.org/cgi-bin/bugrep...
Keywords:
Depends on:
Blocks:
 
Reported: 2008-07-29 19:52 AEST by Colin Watson
Modified: 2017-06-27 12:22 AEST (History)
2 users (show)

See Also:


Attachments
look on $PATH for $SHELL (855 bytes, patch)
2008-07-29 19:52 AEST, Colin Watson
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Colin Watson 2008-07-29 19:52:08 AEST
In http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=492728, Vincent Lefevre reported this regression in 4.9p1 and above:

"For a host for which I have a ProxyCommand:

vin:~> echo $SHELL
zsh
vin:~> ssh xxxxxx.xxxxx.xx
zsh: No such file or directory
ssh_exchange_identification: Connection closed by remote host

Note: POSIX does not require that SHELL contain a full pathname."

There doesn't seem to be any harm in using exec*p functions here. Patch attached.
Comment 1 Colin Watson 2008-07-29 19:52:40 AEST
Created attachment 1552 [details]
look on $PATH for $SHELL
Comment 2 Damien Miller 2009-01-21 20:26:23 AEDT
This is because of this commit to sshconnect.c:

> revision 1.201
> date: 2007/08/23 03:23:26;  author: djm;  state: Exp;  lines: +6 -3
> Execute ProxyCommands with $SHELL rather than /bin/sh unconditionally

We started using $SHELL to avoid ssh ProxyCommand support being a way out of restricted shells like rbash. I'm not sure what the implications of changing the execution to execlp() would be, but I think the assertion that this behaviour is somehow supported by POSIX to be in error.

My copy of Single Unix Specification states:

> SHELL
>     This variable shall represent a pathname of the user's
>     preferred command language interpreter. [...]

Its definition of "pathname":

> A character string that is used to identify a file. 
> [...]
> Note:
>     Pathname Resolution is defined in detail in _Pathname Resolution_.

I'd say that a non-absolute pathname for $SHELL clearly does not "identify a file" unless one happens to be in the same directory as the shell itself and the "Pathname Resolution" section doesn't specify that pathnames be resolved using $PATH.

Depending on $SHELL to be resolved by $PATH is at best implementation-defined, and IMO probably only works by accident.
Comment 3 Vincent Lefevre 2009-01-21 22:19:06 AEDT
(In reply to comment #2)
> My copy of Single Unix Specification states:

I'd rather use POSIX.1-2008.

> > SHELL
> >     This variable shall represent a pathname of the user's
> >     preferred command language interpreter. [...]

POSIX.1-2008 says the same thing (note: just "pathname", not "absolute pathname").

> Its definition of "pathname":
> 
> > A character string that is used to identify a file. 
> > [...]
> > Note:
> >     Pathname Resolution is defined in detail in _Pathname Resolution_.

POSIX.1-2008 says more:

3.266 Pathname
  A character string that is used to identify a file. In the context
  of POSIX.1-2008, a pathname may be limited to {PATH_MAX} bytes,
  including the terminating null byte. It has an optional beginning
  <slash>, followed by zero or more filenames separated by <slash>
  characters. [...]

  Note: Pathname Resolution is defined in detail in Section 4.12
  (on page 111).

It has also the notion of absolute pathname (when the pathname begins with a slash) and relative pathname (when the pathname does not begin with a slash).

> I'd say that a non-absolute pathname for $SHELL clearly does not
> "identify a file"

According to POSIX.1-2008, relative pathnames identify a file, otherwise there would be only one kind of pathnames: absolute ones. POSIX uses the term "pathname" also for execvp, for instance.

> unless one happens to be in the same directory as the
> shell itself and the "Pathname Resolution" section doesn't specify that
> pathnames be resolved using $PATH.

Because it is context-dependent. For instance, relative pathnames are sometimes resolved against the current working directory, not by using $PATH.

IMHO, if POSIX wanted to disallow relative pathnames for $SHELL, it would have said "absolute pathname". It does not say to use $PATH, but this is implicit: in the PATH definition: "This variable shall represent the sequence of path prefixes that certain functions and utilities apply in searching for an executable file known only by a filename." For $SHELL, we are also in the case of an executable.
Comment 4 Damien Miller 2010-04-26 10:45:23 AEST
WONTFIX - I don't accept that logic (you wouldn't specify "zsh" as your shell in /etc/passwd without a path). Furthermore, I don't think it is too hard to specify a path when a user overrides $SHELL.
Comment 5 Vincent Lefevre 2010-04-26 18:41:52 AEST
(In reply to comment #4)
> WONTFIX - I don't accept that logic (you wouldn't specify "zsh" as
> your shell in /etc/passwd without a path).

I wouldn't do it because the environment (in particular, $PATH) at this time may be unspecified. So, it wouldn't make sense. For SHELL, this is different: when I set $SHELL, I already have a $PATH value that I control.

Note that one of the reasons why I don't always have a full pathname is that I do from my .zshenv:

[[ -o login ]] && SHELL=${0#-}

Then one may wonder why $0 doesn't have an absolute pathname...

> Furthermore, I don't think it is too hard to specify a path when a
> user overrides $SHELL.

Yes, for the use of SSH, probably.

Note that a relative pathname could still be useful in some context, e.g. when one needs to set SHELL from a config file which accepts only hardcoded values (e.g. no references to environment variables such as $HOME) and that would be shared under NFS. However, I don't think this is a problem as far as SSH is concerned (at least until now).
Comment 6 Damien Miller 2011-01-24 12:34:05 AEDT
Move resolved bugs to CLOSED after 5.7 release
Comment 7 Vincent Lefevre 2017-06-27 12:22:19 AEST
(In reply to Damien Miller from comment #2)
> My copy of Single Unix Specification states:
> 
> > SHELL
> >     This variable shall represent a pathname of the user's
> >     preferred command language interpreter. [...]
> 
> Its definition of "pathname":
> 
> > A character string that is used to identify a file. 
> > [...]
> > Note:
> >     Pathname Resolution is defined in detail in _Pathname Resolution_.
> 
> I'd say that a non-absolute pathname for $SHELL clearly does not
> "identify a file" unless one happens to be in the same directory as
> the shell itself and the "Pathname Resolution" section doesn't
> specify that pathnames be resolved using $PATH.

There would be the same issue with $EDITOR, while POSIX also says "pathname" for EDITOR and gives an example with EDITOR=vi (i.e. not an absolute pathname).

According to a mail in the Austin Group mailing-list, the valid values for $SHELL should be documented by the platform. For Debian, I've reported:

  https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=866060

(bug against the manpages package, which provides the environ(7) man page).