Hi, chmod is vulnerable to a TOCTTOU (time of check to time of use) race condition. Tested this on an OpenBSD system. For people unfamiliar with OpenBSD, /etc/master.passwd basically equals /etc/shadow:
# chmod --version | head -n 1 chmod (GNU coreutils) 8.23 # ls -l /etc/master.passwd -rw------- 1 root wheel 4244 Jul 23 21:14 /etc/master.passwd # chmod -R g+w /usr/src <second console interferes here> # ls -l /etc/master.passwd -rw-rw-r-- 1 root wheel 4244 Jul 23 21:14 /etc/master.passwd $ rm /usr/src/Makefile $ ln -s /etc/master.passwd /usr/src/Makefile For the second console, the user belonged to the same group as /usr/src (wsrc in this example). The second console is able to modify Makefile because the directory /usr/src was already made group-writable. The race happens in src/chmod.c, around function process_file. Before it gets called, fts_read() retrieved information about the _file_ Makefile, i.e. before the second console removed it. Then the file gets replaced by a symlink, pointing to a file we want to get modified. Now chmodat() resolves the path again and actually evaluates the _symlink_. The destination file /etc/master.passwd can be happily parsed by the attacker now. I won't supply a patch now, as I remember that GNU is a bit picky about accepting patches from everyone. But I will recommend to look into the use of fchmodat() instead, supplying the argument AT_SYMLINK_NOFOLLOW. We discuss this solution at OpenBSD currently. Tobias
