sudo-project / sudo

Utility to execute a command as another user
https://www.sudo.ws
Other
1.2k stars 224 forks source link

sudo consumes stdin even when not prompting for password #344

Closed printfn closed 11 months ago

printfn commented 11 months ago

Create the following shell script:

sleep 1
sudo true

Run it, and immediately type some input in the terminal while the script is sleeping for one second. Make sure sudo is configured to not prompt for a password, or run the script as root. I expected the script to ignore what I typed, causing it to appear on the prompt after the script finished executing, but instead the sudo true command consumed stdin.

On recent versions of sudo (checked on 1.9.9 and 1.9.14 on Ubuntu 22.04 and 23.10), the sudo command will swallow standard input, whereas on version 1.8.31 (Ubuntu 20.04) it ignores the input like I expected. Changing the second line to echo | sudo true works around the issue, but adding -S or -n or changing the use_pty setting had no effect.

millert commented 11 months ago

This is a side-effect of running a command in a pseudo-terminal. There is no way for sudo to tell whether or not the command actually wants the input, it can only tell that the pty's buffer can accept input. There are two possible workarounds.

1) Explicitly disable the _usepty option. E.g.

`Defaults !use_pty`

This will prevent sudo from setting /dev/tty to raw mode and reading from it.  Note that simply removing or commenting out the existing `Defaults use_pty` line is not sufficient, you need to explicitly disable it.  Also, this will have no effect if _log_input_ or _log_output_ is enabled but it doesn't sound like that is the case here.

2) Enable the execbg option. E.g.

`Defaults exec_background`

This will execute commands in the background instead of the foreground.  If a background process needs to read from the terminal, it will receive SIGTTIN, which sudo will notice, grant the command access to the terminal and start reading from the user's /dev/tty.  Not all programs behave properly when run in the background, though.

I just verified that both of those fix the issue on Ubuntu 22.04 with sudo 1.9.9 and 1.9.15p5.