sudo-project/sudo

sudo is not executing the right calling path when using symlinks

radosroka opened this issue · 8 comments

When there are multiple symlinks with the same target in sudoers sudo will always execute the last one.

Sudo version:

sudo-1.9.8-5.p2.fc36.x86_64

Here is the reproducer:

[root@bbb ~]# mkdir dir1 dir2 common
[root@bbb ~]# printf '#! /bin/bash\necho $0\n' > common/script
[root@bbb ~]# chmod 700 common/script
[root@bbb ~]# ln -s ../common/script dir1/script
[root@bbb ~]# ln -s ../common/script dir2/script
[root@bbb ~]# echo 'ALL ALL = (root) NOPASSWD: /root/dir1/script,/root/dir2/script' >> /etc/sudoers
[root@bbb ~]#
[root@bbb ~]# /root/dir1/script
/root/dir1/script
[root@bbb ~]# /root/dir2/script
/root/dir2/script
[root@bbb ~]# sudo /root/dir1/script
/root/dir2/script
[root@bbb ~]# sudo /root/dir2/script
/root/dir2/script

Sudo matches files by basename + inode and executes the path listed in the sudoers file, not the user-specified path. Since the last match wins, that is what gets executed. Changing this behavior is non-trivial and has the potential to introduce other, more serious, bugs.

sopos commented

However, there are scripts / binaries which change their behavior based on the $0. That may be broken by this sudo behavior.

If this is not fixed, could this unusual behaviour be documented? As far as I know, it is not documented anywhere (officially).

I believe this can be fixed by canonicalizing the command's parent directory (both the user-supplied command and the command in the sudoers file) and using that to distinguish between commands with the same basename and the same device/inode combination. This is something I will investigate for sudo 1.9.14.

That's great news, thanks @millert :)

This is fixed by 0ef5373 and b52631e.

That is awesome. Thanks a lot!

Sudo 1.9.14 is out now and canonicalizes patch names before matching.