Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues with zeroth argument going into shell #4

Closed
Rutherther opened this issue May 11, 2024 · 11 comments · Fixed by #8
Closed

Issues with zeroth argument going into shell #4

Rutherther opened this issue May 11, 2024 · 11 comments · Fixed by #8

Comments

@Rutherther
Copy link
Contributor

Issue

According to Bash documentation, and I bet it's also somewhere in login documentation, but I did not find it, there are two ways to indicate a login shell. Either the first character of zeroth argument is '-', or with --login flag.
See https://www.gnu.org/software/bash/manual/html_node/Invoking-Bash.html

A login shell is one whose first character of argument zero is ‘-’, or one invoked with the --login option.

For example, when I turn on logging of all of the argument going into noshell, and start it in a TTY, I get only one argument, and it's -noshell. No other argument like -l or --login are supplied.

Noshell currently passes /home/{user}/.config/shell as the zeroth argument to all of the shells. This means it cannot act as a login shell on systems where the first option with prepending - is used.

Additionally, it does not seem to properly work with shells such as zsh, because they try to emulate other shells like sh or bash when the zeroth argument is matched against some patterns. Specifically, zsh looks if the first character of zeroth argument's file name is s, and if it is, it decides to emulate sh.
This can be seen here https://github.com/zsh-users/zsh/blob/efb7a962073988b4212820b02017980f5ec83f38/Src/init.c#L260

Proposed solution

Instead of passing /home/{user}/.config/shell as a first argument, pass in value from readlink of the shell file when the shell file is a link. Additionally, if the first character of zeroth argument is -, pass that through as the first character.

The idea behind this is to act like there is no middle man like noshell - to imagine that it was login calling the program, and not noshell. In that case passwd would contain something like /run/current-system/sw/zsh, and it would be called with -/run/current/system/sw/zsh as first argument.

@viperML
Copy link
Owner

viperML commented May 12, 2024

why not call with argv0 -/home/user/.config/shell ?

@Rutherther
Copy link
Contributor Author

I thought that was explained. Zsh assumes sh emulation when first character of $0 is s

@viperML
Copy link
Owner

viperML commented May 12, 2024

Then we could just passthru argv0 unmodified

@Rutherther
Copy link
Contributor Author

Yes, that's one possibility, but it seems to me to be more of a workaround. I really think the best is to try to make it behave as much as possible like if the symlinked file was inside of passwd file to prevent further issues like other shells assuming emulation of something based on the argv0

I've made a demonstration for you to make the various behaviors clearer, in a VM. There are a couple of users, all with password vm. User new and old are the main ones. new uses the version with changes I made in #5. old uses the current upstream version. Additionally, both versions are patched to show arguments going into noshell, and the new one argument going to the execvp as well. See https://github.com/Rutherther/noshell-vm-argv0-demonstration

Additionally, there are new-bash-emulation and new-sh-emulation that show that if your $0 is something specially handled by zsh, you can get emulation by mistake.

@viperML
Copy link
Owner

viperML commented May 12, 2024

Are there any counterpoints to the argv0 passthru?

@Rutherther
Copy link
Contributor Author

Rutherther commented May 12, 2024

I don't know of a shell that would assume n or noshell means to use different behavior. Zsh uses c, k, s, b (https://github.com/zsh-users/zsh/blob/efb7a962073988b4212820b02017980f5ec83f38/Src/options.c#L538). But maybe there is other shell that uses this and will have issues.

@Rutherther
Copy link
Contributor Author

I think this boils down to what noshell's goal is. I thought it was something like this: emulate /etc/passwd shell behavior, with possibility for users to change their (login) shell, without root rights, without changing /etc/passwd.

If this is the goal, I think it would make sense to make the behavior so that what the shell links points to is treated as if it was in /etc/passwd. Then it seems inappropriate to me to pass through -noshell, as the behavior would be different when the symlinked file would be actually in /etc/passwd.

On the other hand, if this is not the exact goal, then it's probably fine. Worst case scenario the user does not have to use shell file as a symlink, but can make it a script or a program of their own that will just execute their shell with correct argv0. Maybe on that note it could be useful to also provide other script or program in this repository that would do this exactly - change the argv0 to whatever the user deems appropriate and call the shell binary.

@viperML
Copy link
Owner

viperML commented May 15, 2024

I don't know of a shell that would assume n or noshell means to use different behavior. Zsh uses c, k, s, b (https://github.com/zsh-users/zsh/blob/efb7a962073988b4212820b02017980f5ec83f38/Src/options.c#L538). But maybe there is other shell that uses this and will have issues.

after seeing the argv0 hacks in the shells, you have convinced me to not go the -noshell as argv0 route

@viperML
Copy link
Owner

viperML commented May 15, 2024

I think another solution would be:

Stat ~/.config/shell. If it is:

  • Regular file -> set argv0 to shell or -shell
  • Symlink -> do a realpath to unfold all the symlink chains, as use the basename or -basename as the argv0

@viperML
Copy link
Owner

viperML commented May 15, 2024

I believe that is the intent of #5 but I haven't looked into it deeply

@Rutherther
Copy link
Contributor Author

Rutherther commented May 15, 2024

I believe that is the intent of #5 but I haven't looked into it deeply

Yes, that is the intent, with one difference, it uses read link instead of realpath. The reason behind that is to respect other symlinks argv0. Imagine someone has /bin/bash - > /bin/zsh. If /bin/bash is put into passwd, it should be called with bash as argv0. Real path would mean calling with zsh argv0.

(I am omitting full paths in my messages since they dont seem that important at least in zsh. The real solution uses full paths, not just name of file)

viperML added a commit that referenced this issue May 16, 2024
viperML added a commit that referenced this issue May 16, 2024
Fixes #4, #7
Closes #5

Co-authored-by: Rutherther <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants