Bug 888

Summary: Sudoers has different behaviour depending on the token type in a User_List if the command specified in Cmd_List does not exist
Product: Sudo Reporter: Riccardo Paolo Bestetti <riccardo.kyogre>
Component: SudoersAssignee: Todd C. Miller <Todd.Miller>
Status: RESOLVED FIXED    
Severity: security    
Priority: low    
Version: 1.8.19   
Hardware: PC   
OS: Linux   

Description Riccardo Paolo Bestetti 2019-07-12 09:06:02 MDT
Hello,

I'm on Debian 9 and I'm running sudo and sudoers 1.8.19p1.

Consider the following sudoers file:
Defaults	env_reset
Defaults	mail_badpass
Defaults	secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
root	ALL=(ALL:ALL) ALL
%sudo	ALL=(ALL:ALL) ALL
r       ALL= NOPASSWD: /usr/bin/systemctl poweroff

Note that /usr/bin/systemctl does not exist (the correct path is /bin/systemctl).

If I type as user r
$ sudo /usr/bin/systemctl poweroff
I'm prompted for the password. (This means the rule is not matched or ignored).

If instead I use the following sudoers file:
Defaults	env_reset
Defaults	mail_badpass
Defaults	secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
root	ALL=(ALL:ALL) ALL
%sudo	ALL=(ALL:ALL) ALL
ALL     ALL= NOPASSWD: /usr/bin/systemctl poweroff

And I type as user r
$ sudo /usr/bin/systemctl poweroff
I'm not prompted for the password (as expected) and I receive a "command not found" error.

To confirm the first version of sudoers really should match, I then repeat the experiment with the correct systemctl path:
Defaults	env_reset
Defaults	mail_badpass
Defaults	secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
root	ALL=(ALL:ALL) ALL
%sudo	ALL=(ALL:ALL) ALL
r       ALL= NOPASSWD: /bin/systemctl poweroff

Now, typing as user r
$ sudo /bin/systemctl poweroff
does indeed work as expected.

I don't think the type of User_List token should change the behaviour of sudo when the executable file for the matched command does not exist. I'm not sure whether this has security implications, but just to be safe I marked it as "security".
Comment 1 Riccardo Paolo Bestetti 2019-07-12 09:19:46 MDT
Let me rectify: it seems the behaviour is the same in both cases, and it's the first one (I'm prompted for the password, i.e. the rule is not matched). I probably got it mixed up because of credentials caching.
Comment 2 Todd C. Miller 2019-07-19 13:52:03 MDT
This is because sudo actually matches commands by their device and inode number.  This prevents someone from avoiding negated commands simply by using a link to a different name.

Falling back to name-based matching should be safe since sudo won't try to run a command that doesn't exist.

This is fixed by the following commit: https://www.sudo.ws/repos/sudo/rev/0879054870be
Comment 3 Todd C. Miller 2019-10-14 10:36:33 MDT
Fixed in sudo 1.8.28