0

From Command not found when using sudo

it's in fact possible to have sudo use the current PATH (with the env command) and/or the rest of the environment (with the -E option) just by invoking it right:

sudo -E env "PATH=$PATH" <command> [arguments]

In fact, one can make an alias out of it:

alias mysudo='sudo -E env "PATH=$PATH"'

(It's also possible to name the alias itself sudo, replacing the original sudo.)

Why is it to have sudo use the current PATH with the env command, instead of the -E option?

Why is it to have sudo use the rest of the environment with the -E option, instead of the env command?

Is it correct that PATH is part of the environment?

What is special about PATH with respect to the rest of the environment?

Thanks.


From sudo manpage

sudo tries to be safe when executing external commands. To prevent command spoofing, sudo checks "." and "" (both denoting current directory) last when searching for a command in the user's PATH (if one or both are in the PATH). Note, however, that the actual PATH environment variable is not modified and is passed unchanged to the program that sudo executes.

Does it mean that the user's PATH is passed unchanged to the command which sudo executes, by "the actual PATH environment variable is not modified and is passed unchanged to the program that sudo executes"?

  • sudo handles PATH specially because otherwise you could trick sudo into running your version of some command with elevated privileges. So PATH is special in sudo, but not otherwise. – wurtel Jan 26 '18 at 14:00
2

If env_reset is enabled (which it is, by default), sudo clears out the environment, and in particular provides its own PATH (see secure_path in /etc/sudoers). If env_reset is disabled, env_check and env_delete still apply, and PATH is still likely to be cleared. You can see this in action by comparing the output of

echo $PATH

and

sudo printenv PATH

If you have a customised PATH, you won’t see it in the output of sudo printenv.

The env trick works around the environment clean-up:

sudo env "PATH=$PATH" command

asks sudo to run env "PATH=$PATH" command, with $PATH expanded by your shell to contain your current PATH; env, running as root, then stores the given value of PATH in its environment and runs command with that environment.

So PATH isn’t special, except in the context of sudo, depending on your configuration. Any variable can be made “special” in the same way by configuring sudo appropriately, and PATH can be made “unspecial” too. See the sudo and sudoers manpages for details.

  • Thanks. Does the manpage of sudo mean that the user's PATH is passed unchanged to the command which sudo executes, by "the actual PATH environment variable is not modified and is passed unchanged to the program that sudo executes"? See my update. – Tim Jan 26 '18 at 14:30
  • Right, that part’s a bit confusing. sudo applies the settings from sudoers, including PATH processing if env_reset is enabled (and in various other cases), as described in the sudoers documentation; then it processes PATH in the way described in the sudo documentation. The part about passing PATH unchanged only applies to the last part of the processing: if PATH survives sudoers with . or an empty entry, sudo will process those last, but it won’t change PATH at that point to reflect that new order. – Stephen Kitt Jan 26 '18 at 14:37
  • Thanks. From your comment, it seems to me that the environment list is set up before sudo forks a child process to execute a command, and then the child process inherits and then passes the environment list without change to the command. From the manpage of sudo, "When sudo runs a command, it calls fork(2), sets up the execution environment as described above, and calls the execve system call in the child process", does it mean that environment list is set up in the child process, instead of the process which runs sudo? – Tim Apr 21 '18 at 16:14
  • What practical difference does it make? The environment is just an array of strings which is given as one of execve’s parameters. sudo doesn’t change its own environment, it builds a new array of strings to use when calling execve. It doesn’t matter whether that happens before or after fork. – Stephen Kitt Apr 21 '18 at 17:48
  • Thanks. Why "If env_reset is disabled, env_check and env_delete still apply, and PATH is still likely to be cleared"? – Tim Jun 3 '18 at 1:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.