An apparently little known fact about dpkg is that it clears suid bits when upgrading packages. This defeats the hardlink-a-suid-binary-and-wait-for-exploit attack that used to be a worry, and which apparently still is to some.

joey@gnu:~>ln /usr/bin/sudo
joey@gnu:~>dir sudo
-rwsr-xr-x 3 root root 112K Jul  6  2008 sudo*
joey@gnu:~>sudo apt-get --reinstall install sudo
Reading package lists... Done
[...]
Get:1 http://ftp.egr.msu.edu unstable/main sudo 1.6.9p17-1 [177kB]
Fetched 177kB in 1s (91.0kB/s)    
Created commit e5523fe: saving uncommitted changes in /etc prior to apt run
 1 files changed, 14 insertions(+), 0 deletions(-)
(Reading database ... 167780 files and directories currently installed.)
Preparing to replace sudo 1.6.9p17-1 (using .../sudo_1.6.9p17-1_i386.deb) ...
Unpacking replacement sudo ...
Processing triggers for man-db ...
Setting up sudo (1.6.9p17-1) ...
joey@gnu:~>dir sudo 
-rw------- 1 root root 112K Jul  6  2008 sudo

dpkg has done this since version 1.10.18.1, released in 2004.

PS, Can any rpm users tell me if rpm does this?

PPS, If you find yourself making statements like "While noexec is only a weak defense, it gives a little bit more protection", you are probably not really talking about security, but instead about a warm fuzzy feeling.

PPS, If shellcode can create a suid root executable, it can create it in /root or some other directory that is not mounted nosuid.

Huh, really?

On my sid box:

% ls -l /usr/bin/sudo -rwsr-xr-x 2 root root 127080 2008-07-06 00:37 /usr/bin/sudo % sudo apt-get --reinstall install sudo Reading package lists... Done Building dependency tree
Reading state information... Done 0 upgraded, 0 newly installed, 1 reinstalled, 0 to remove and 0 not upgraded. Need to get 0B/187kB of archives. After this operation, 0B of additional disk space will be used. Do you want to continue [Y/n]? (Reading database ... 128253 files and directories currently installed.) Preparing to replace sudo 1.6.9p17-1 (using .../sudo_1.6.9p17-1_amd64.deb) ... Unpacking replacement sudo ... Processing triggers for man-db ... Setting up sudo (1.6.9p17-1) ... % ls -l /usr/bin/sudo -rwsr-xr-x 2 root root 127080 2008-07-06 00:37 /usr/bin/sudo

What am I missing?

Comment by triplehelix.org
Re: Huh, really?

You're missing that Joey's performing an ls on ~/sudo -- initially a hardlink to /usr/bin/sudo. Reinstalling the sudo package replaces /usr/bin/sudo in such a way that the hardlinked copy loses its suid bits:

[jamessan@habanero] ~  :: $ ls -li sudo /usr/bin/sudo
9290453 -rwsr-xr-x 3 root root 115136 2008-09-01 09:17 sudo
9290453 -rwsr-xr-x 3 root root 115136 2008-09-01 09:17 /usr/bin/sudo
[jamessan@habanero] ~  :: $ ls -li sudo /usr/bin/sudo
9290453 -rw------- 1 root root 115136 2008-09-01 09:17 sudo
9290443 -rwsr-xr-x 2 root root 115136 2008-09-01 09:17 /usr/bin/sudo
Comment by jamessan [myopenid.com]
comment 4

AFAIK, dpkg-statoverride does not prevent the suid bit clearing from being done by dpkg. If it does, we've got a problem.

triplehelix: Of course /usr/bin/sudo remains suid over upgrade as you show. A hard link to that file, however, will not.

Comment by joey [kitenet.net]
comment 5
And as per my reply to triplehelix, I now see that dpkg-statoverride isn't directly relevant to the point of the discussion. The reinstallation removes the suid bits before unpacking the new package which means the user's copy of the file doesn't have them anymore. The newly unpacked file then has the suid bits reinstated via dpkg-statoverride but that's now taking place on a new inode, which leaves the user's copy useless (for their malicious purposes).
Comment by jamessan [myopenid.com]
comment 6

Doesn't look like rpm does it:

[chrisb@db2:~]$ ln /usr/bin/sudo .
[chrisb@db2:~]$ ls -il sudo /usr/bin/sudo
2206100 ---s--x--x 3 root root 159752 May 25  2008 sudo
2206100 ---s--x--x 3 root root 159752 May 25  2008 /usr/bin/sudo
[chrisb@db2:~]$ sudo apt-get install --reinstall sudo
Reading Package Lists... Done
Building Dependency Tree... Done
0 upgraded, 0 newly installed, 1 reinstalled, 0 removed and 146 not upgraded.
Need to get 0B/228kB of archives.
After unpacking 0B of additional disk space will be used.
Do you want to continue? [Y/n] 
Checking GPG signatures...  ########################################### [100%]
Committing changes...
Preparing...                ########################################### [100%]
   1:sudo                   ########################################### [100%]
Done.
[chrisb@db2:~]$ ls -il sudo /usr/bin/sudo
2206100 ---s--x--x 1 root root 159752 May 25  2008 sudo
2206099 ---s--x--x 2 root root 159752 May 25  2008 /usr/bin/sudo

This is CentOS 5, so possibly not the latest version of rpm. Still should be fairly up-to-date though.

Comment by crispygoth [livejournal.com]