Printing the value of getuid() and geteuid() from an executable with SUID-bit (chmod +s) turned-on, seems to result with the original caller ID instead of the owner id if the executable is located within the /tmp directory.
When compiling the exact same code to home directory (and executing chmod +s), this seems to work as expected.
I've searched a lot and could not find any reference to such behavior.
Does anybody know why is this happening?
this source is simple as that:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(){
printf("%d\n%d\n", getuid(), geteuid());
return 0;
}
Best Answer
Setuid executables can be disabled in filesystem mount options, the option is called
nosuid
. This is always done for filesystems that can be mounted by untrusted users (theuser
mount option in/etc/fstab
automatically impliesnosuid
) or whose content can be modifed arbitrarily by untrusted users, for example on removable media or over the network from machines that aren't fully trusted. It is sometimes done for other filesystems as well.Many systems use tmpfs for
/tmp
: a filesystem whose content remain in memory and isn't preserved on a reboot. (A tmpfs filesystem can be faster than relying on the disk cache because it doesn't need to care about data consistency.) Some setups mount it with thenosuid
option, because there usually isn't any call for setuid temporary files and this could occasionally be part of an attack vector (setuid files in/tmp
are not a security risk per se, but disabling them can limit the damage caused by a few vulnerabilities).You can check the mount options for a directory by first looking up the mount point that contains it with
df
:Then look up the mount point in the output from
mount
, or on Linux in/proc/mounts
.