Bug#479406: su fails for users with a POSIX script as their login shell
On Mon, Jul 20, 2009 at 03:41:40PM +0100, stephane_chaze...@yahoo.fr wrote: 2009-07-20 16:03:35 +0200, Nicolas François: [...] login is the easiest, su is more complex because the behavior of su -c command must be defined in this case. So I will just make it as /bin/sh shell -c command [..] + if (access (file, R_OK|X_OK) == 0) { + /* +* Assume this is a shell script (with no shebang). +* Interpret it with /bin/sh +*/ + execle (/bin/sh, sh, file, (char *)0, envp); [...] There should be a macro that defines the PATH to sh. On some systems (like Solaris), the standard sh is not in /bin. And you might find that some will have several sh, one for every standard or version of standard they conform to, and that being defined either at compile time or run time. Thanks. That should be fixed now. Using execvp() would make sure you do the same choice of a shell as the libc and would avoid potential problems in future hypothetical versions of debian that support several standards. I would like to avoid having to sanitize the shell, and thus would prefer not to use execvp. You may want to do: execle (/bin/sh, sh, -, file, (char *)0, envp); Done. Best Regards, -- Nekral -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of unsubscribe. Trouble? Contact listmas...@lists.debian.org
Bug#479406: su fails for users with a POSIX script as their login shell
tags 479406 pending thanks Hi, On Sun, Jul 19, 2009 at 08:58:49PM +0100, stephane_chaze...@yahoo.fr wrote: 2009-07-18 21:26:56 +0200, Nicolas François: Ping Sorry, forgot to reply to your earlier email. No problem (it took me a year for the previous answer ;) Are there other su / login implementations which behave that way? [...] AFAICS, the login from util-linux (derived from BSD) and the one from NetBSD and OpenBSD at least do use the exec?p variants (from a quick look at there source code). The OpenSolaris one seems to be checking for that case (pw_shell being a shell script) explicitely and treats it specially: http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/login/login.c#2507 login is the easiest, su is more complex because the behavior of su -c command must be defined in this case. So I will just make it as /bin/sh shell -c command I will commit and test the attached patch, which should fix it for both login and su. Best Regards, -- Nekral Index: libmisc/shell.c === --- libmisc/shell.c (révision 3031) +++ libmisc/shell.c (copie de travail) @@ -79,6 +80,15 @@ execle (file, arg, (char *) 0, envp); err = errno; + if (access (file, R_OK|X_OK) == 0) { + /* + * Assume this is a shell script (with no shebang). + * Interpret it with /bin/sh + */ + execle (/bin/sh, sh, file, (char *)0, envp); + err = errno; + } + /* * Obviously something is really wrong - I can't figure out * how to execute this stupid shell, so I might as well give Index: src/su.c === --- src/su.c (révision 3031) +++ src/su.c (copie de travail) @@ -174,7 +174,41 @@ exit (1); } +/* + * execve_shell - Execute a shell with execve, or interpret it with + * /bin/sh + */ +void execve_shell (const char *shellstr, char *args[], char *const envp[]) +{ + int err; + (void) execve (shellstr, (char **) args, envp); + err = errno; + if (access (shellstr, R_OK|X_OK) == 0) { + /* + * Assume this is a shell script (with no shebang). + * Interpret it with /bin/sh + */ + size_t n_args = 0; + char **targs; + while (NULL != args[n_args]) { + n_args++; + } + targs = (char **) xmalloc ((n_args + 2) * sizeof (args[0])); + targs[0] = sh; + targs[1] = xstrdup (shellstr); + targs[n_args+1] = NULL; + while (1 != n_args) { + targs[n_args] = args[n_args - 1]; + n_args--; + } + + (void) execve (/bin/sh, targs, envp); + } else { + errno = err; + } +} + #ifdef USE_PAM /* Signal handler for parent process later */ static void catch_signals (unused int sig) @@ -206,8 +240,9 @@ if (doshell) { (void) shell (shellstr, (char *) args[0], envp); } else { - (void) execve (shellstr, (char **) args, envp); + execve_shell (shellstr, (char **) args, envp); } + exit (errno == ENOENT ? E_CMD_NOTFOUND : E_CMD_NOEXEC); } else if ((pid_t)-1 == child) { (void) fprintf (stderr, %s: Cannot fork user shell\n, Prog); @@ -949,7 +984,7 @@ */ argv[-1] = shellstr; #ifndef USE_PAM - (void) execve (shellstr, argv[-1], environ); + execve_shell (shellstr, argv[-1], environ); err = errno; (void) fputs (_(No shell\n), stderr); SYSLOG ((LOG_WARN, Cannot execute %s, shellstr));
Bug#479406: su fails for users with a POSIX script as their login shell
2009-07-20 16:03:35 +0200, Nicolas François: [...] login is the easiest, su is more complex because the behavior of su -c command must be defined in this case. So I will just make it as /bin/sh shell -c command [..] + if (access (file, R_OK|X_OK) == 0) { + /* + * Assume this is a shell script (with no shebang). + * Interpret it with /bin/sh + */ + execle (/bin/sh, sh, file, (char *)0, envp); [...] There should be a macro that defines the PATH to sh. On some systems (like Solaris), the standard sh is not in /bin. And you might find that some will have several sh, one for every standard or version of standard they conform to, and that being defined either at compile time or run time. Using execvp() would make sure you do the same choice of a shell as the libc and would avoid potential problems in future hypothetical versions of debian that support several standards. You may want to do: execle (/bin/sh, sh, -, file, (char *)0, envp); regards, Stephane -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of unsubscribe. Trouble? Contact listmas...@lists.debian.org
Bug#479406: su fails for users with a POSIX script as their login shell
2009-07-18 21:26:56 +0200, Nicolas François: Ping Sorry, forgot to reply to your earlier email. Any opinion on this? My current preference would be to close the bug. It could also be tagged wontfix: I'm not sure the feature is that useful, and switching to execlp/execvp/system could break existing behaviors. What kind of existing behavior would that break when using execvp instead of execve? It's more a matter of consistence to me. But it's true it's no big deal. [...] Are there other su / login implementations which behave that way? [...] AFAICS, the login from util-linux (derived from BSD) and the one from NetBSD and OpenBSD at least do use the exec?p variants (from a quick look at there source code). The OpenSolaris one seems to be checking for that case (pw_shell being a shell script) explicitely and treats it specially: http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/login/login.c#2507 Best regards, Stephane -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of unsubscribe. Trouble? Contact listmas...@lists.debian.org
Bug#479406: su fails for users with a POSIX script as their login shell
Ping Any opinion on this? My current preference would be to close the bug. It could also be tagged wontfix: I'm not sure the feature is that useful, and switching to execlp/execvp/system could break existing behaviors. On Tue, May 12, 2009 at 12:43:41AM +0200, Nicolas François wrote: Hello, On Sun, May 04, 2008 at 05:46:49PM +0100, Stephane Chazelas wrote: (Note that the same applies to login). With this password entry: test:x:1000:1000:test:/:/tmp/x And /tmp/x being an executable file containing this only line: echo test [...] Although not widely known that way of writing shell scripts is *the* standard (POSIX and Unix) way. The behavior is unspecified as per POSIX if your file starts with #!. I would definitely prefer that the admin define the shell that has to interpret the file. Yes, it is mentioned in http://www.opengroup.org/onlinepubs/9699919799/functions/exec.html , but is it a common practice to have a shell script as a shell and that the shell which should interpret that script is not specified? An option could be to use execlp or execvp, and also make sure the shell is an absolute path. All the utilities specified by POSIX and that may execute commands (sh, env, exec, ex, vi, awk...) and the execvp/execlp/system/popen libc functions are meant to recognise those files (the text files that don't start with #!): upon a ENOEXEC, they should have the file interpreted by a standard sh. I did not find any usage of ENOEXEC/execlp/execvp in elvis, nvi, mawk, gawk. They probably use system(). I'm not really a surprise that sh, env, and exec do that but it will be much easier for them to choose the shell. I'll concede login and su are not specified by POSIX, but it would make more sense that they behave the same way as other standard utilities. Are there other su / login implementations which behave that way? On Mon, 5 May 2008 11:18:47 +0100, Stephane Chazelas wrote: BTW, this code (thanksfully disabled on Linux) is wrong: /* Linux handles #! in the kernel, and bash doesn't make sense of #! so it wouldn't work anyway... --marekm */ #ifndef __linux__ [...] Yes, this should be removed. This part is done. -- Nekral -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of unsubscribe. Trouble? Contact listmas...@lists.debian.org
Bug#479406: su fails for users with a POSIX script as their login shell
severity 479406 wishlist thanks Hello, On Sun, May 04, 2008 at 05:46:49PM +0100, Stephane Chazelas wrote: (Note that the same applies to login). With this password entry: test:x:1000:1000:test:/:/tmp/x And /tmp/x being an executable file containing this only line: echo test [...] Although not widely known that way of writing shell scripts is *the* standard (POSIX and Unix) way. The behavior is unspecified as per POSIX if your file starts with #!. I would definitely prefer that the admin define the shell that has to interpret the file. Yes, it is mentioned in http://www.opengroup.org/onlinepubs/9699919799/functions/exec.html , but is it a common practice to have a shell script as a shell and that the shell which should interpret that script is not specified? An option could be to use execlp or execvp, and also make sure the shell is an absolute path. All the utilities specified by POSIX and that may execute commands (sh, env, exec, ex, vi, awk...) and the execvp/execlp/system/popen libc functions are meant to recognise those files (the text files that don't start with #!): upon a ENOEXEC, they should have the file interpreted by a standard sh. I did not find any usage of ENOEXEC/execlp/execvp in elvis, nvi, mawk, gawk. They probably use system(). I'm not really a surprise that sh, env, and exec do that but it will be much easier for them to choose the shell. I'll concede login and su are not specified by POSIX, but it would make more sense that they behave the same way as other standard utilities. Are there other su / login implementations which behave that way? On Mon, 5 May 2008 11:18:47 +0100, Stephane Chazelas wrote: BTW, this code (thanksfully disabled on Linux) is wrong: /* Linux handles #! in the kernel, and bash doesn't make sense of #! so it wouldn't work anyway... --marekm */ #ifndef __linux__ [...] Yes, this should be removed. Best Regards, -- Nekral -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of unsubscribe. Trouble? Contact listmas...@lists.debian.org
Bug#479406: su fails for users with a POSIX script as their login shell
BTW, this code (thanksfully disabled on Linux) is wrong: /* Linux handles #! in the kernel, and bash doesn't make sense of #! so it wouldn't work anyway... --marekm */ #ifndef __linux__ /* * It is perfectly OK to have a shell script for a login * shell, and this code attempts to support that. It * relies on the standard shell being able to make sense * of the #! magic number. */ if (err == ENOEXEC) { FILE *fp; if ((fp = fopen (file, r))) { if (getc (fp) == '#' getc (fp) == '!') { fclose (fp); execle (/bin/sh, sh, file, (char *) 0, envp); err = errno; } else { fclose (fp); } } } #endif (in libmisc/shell.c) No standard shell would ever parse the #! if called as sh the-file. Some (such as zsh or some other shells compiled on systems that don't support #! (basically, no modern one)) may parse that line if called as sh -c 'that-file' as they would try to execute it (not interprete it) and upon the ENOEXEC parse the #! line to substitute for the kernel that fails to do this. The end result is that it causes sh (instead of the specified interpreter) to interpret the script. I think that code should be removed altogether. Cheers, Stéphane -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]
Bug#479406: su fails for users with a POSIX script as their login shell
Package: login Version: 1:4.1.1-1 Severity: normal (Note that the same applies to login). With this password entry: test:x:1000:1000:test:/:/tmp/x And /tmp/x being an executable file containing this only line: echo test When logging in as user test, or with su test you get: Cannot execute /tmp/x: Exec format error Although not widely known that way of writing shell scripts is *the* standard (POSIX and Unix) way. The behavior is unspecified as per POSIX if your file starts with #!. All the utilities specified by POSIX and that may execute commands (sh, env, exec, ex, vi, awk...) and the execvp/execlp/system/popen libc functions are meant to recognise those files (the text files that don't start with #!): upon a ENOEXEC, they should have the file interpreted by a standard sh. I'll concede login and su are not specified by POSIX, but it would make more sense that they behave the same way as other standard utilities. -- System Information: Debian Release: lenny/sid APT prefers unstable APT policy: (500, 'unstable') Architecture: i386 (i686) Kernel: Linux 2.6.25-rc8 (PREEMPT) Locale: LANG=en_GB.ISO-8859-15, LC_CTYPE=en_US.ISO-8859-15 (charmap=ISO-8859-15) Shell: /bin/sh linked to /bin/bash Versions of packages login depends on: ii libc6 2.7-10 GNU C Library: Shared libraries ii libpam-modules0.99.7.1-6 Pluggable Authentication Modules f ii libpam-runtime0.99.7.1-6 Runtime support for the PAM librar ii libpam0g 0.99.7.1-6 Pluggable Authentication Modules l login recommends no packages. -- debconf-show failed -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]