Why suid bit is unset after file modification

permissionssetuid

I have an (s|g)uid file world-writable:

ls -lh suid_bin.sh
-rwsr-srwx 1 root root 168 mai   23 16:46 suid_bin.sh

logged with a non-root user account. I use vi (or another editor) to modify "suid_bin.sh". After saving the new content, (s|g)uid bits are unset:

ls -lh suid_bin.sh 
-rwxr-xrwx 1 root root 168 mai   23 16:46 suid_bin.sh

Why? Is there a way to keep (s|g)uid bits after modification?

Best Answer

Unix permissions allow writing to file if accidentally someone will set group or world writable bit on setuid file, but disallow changing owner and group ids on such files by strangers.

So after modification kernel drops setuid/setgid bits from file to ensure there is no malicious code was written to file.

root user of course can restore setuid bit, but ordinary user, if he, by someone's mistake gained write access to privileged executable will not be able to exploit it.

And, knowing parts of kernel in that area I am not sure you can disable that without editing source code of kernel and recompiling.

Note that setuid scripts in Linux do not gain setuid status after execution because actually kernel starts the script interpreter, without setuid status, with the full path to script as it's last parsed argument, and then interpreter reads the script as an ordinary file. But this can vary on other Unix systems.

Related Question