Bugzilla – Bug 506
sudoers parsing error around hardlinked binaries with the same basename
Last modified: 2011-08-22 15:44:45 MDT
There appears to be an issue in parsing sudoers files under the following scenario. A user has an existing sudo rule granting access to a binary i.e. /path/to/mybinary The original binary has a hard link to the same filename in a different directory i.e /new/path/to/mybinary. A sudo command alias is added to reference /new/path/to/mybinary. The directories will be different but the binary must be the same name. The new hard link can be anywhere, it doesn't have to be referenced on the path. The new sudo alias doesn't have to be granted to anyone, it just has to exist in the /etc/sudoers file. Under the above scenario, if a user runs "sudo /path/to/mybinary", sudo will actually run /new/path/to/mybinary. An example real-world case is on Solaris 10 where /usr/bin/ps and /usr/ucb/ps are hard links. If a user has an existing rule enabling /usr/ucb/ps, adding a new alias for /usr/bin/ps will silently make sudo run the incorrect command. How to recreate: # mkdir -p /opt/good/ /opt/bad # echo ' echo "I am $0"' > /opt/good/testme # chmod a+rx /opt/good/testme # ln /opt/good/testme /opt/bad/testme # cat /etc/sudoers Cmnd_Alias TEST_CMDS=/opt/good/testme Cmnd_Alias BOGUS=/opt/bad/testme testuser ALL=(root) NOPASSWD:TEST_CMDS The problem is recreatable on Linux and Solaris from versions 1.6.6 through to 1.6.9p23. The issue appears to be fixed in 1.7.0: bash-2.03# /usr/bin/sudo -V | egrep version ; su - testuser -c '/usr/bin/sudo /opt/good/testme' Sudo version 1.6.6 I am /opt/bad/testme bash-2.03# /opt/sudo-1.6.9p23/bin/sudo -V | egrep version ; su - testuser -c '/opt/sudo-1.6.9p23/bin/sudo /opt/good/testme' Sudo version 1.6.9p23 I am /opt/bad/testme bash-2.03# /opt/sudo-1.7.0/bin/sudo -V | egrep version ; su - testuser -c '/opt/sudo-1.7.0/bin/sudo /opt/good/testme' Sudo version 1.7.0 I am /opt/good/testme
This is a known artifact due to the way that sudoers is parsed in versions 1.3.x - 1.6.x. Sudo validates commands based on their inode number (along with device id). For sudo < 1.7.0, commands are matched at the same time sudoers is parsed, so it is possible to end up with a match as long as the basename matches and the inode/device match the command being run. Sudo runs the command as it appears in sudoers to avoid a race condition that could otherwise allow a user to run arbitrary commands. The guts of the sudoers parser was rewritten for sudo 1.7.0 so that it parses sudoers in one step and does the command matching in another, which is why you don't have the problem there. Sudo 1.6.x is obsolete and no longer supported. Please update to either a 1.7.x version or. better still, 1.8.x. You can find binary packages of sudo 1.7.7 and 1.8.2 for many systems at http://www.sudo.ws/sudo/download.html#binary