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.
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 :)
That is awesome. Thanks a lot!
Sudo 1.9.14 is out now and canonicalizes patch names before matching.