This question already has an answer here:

[EDIT: Revisiting this question and seeing it is still wrongly marked as a duplicate] The following question on SE is not a duplicate as it asks about executing bash with the suid bit, which is a special case and does not work at all: Setuid bit seems to have no effect on bash The first difference is that in my example I execute whoami, not bash. The second difference is that it actually works as expected on Ubuntu, but not on SuSE.

Suid bit works fine on my PC running Ubuntu, but not on a SLES test instance. The nosuid flag is not set on the mounted xfs file system on the SLES machine. ls shows that ony my machine and the SLE Server, the same permissions are set for the executable. So why does the executable still run as the current user instead of as the owner?


#include <stdio.h>
#include <stdlib.h>

int main(int argc,char *argv[]) {
    return 0;


gcc -o setuid-test execsudo.c ;
sudo chown nobody ./setuid-test;
sudo chmod +s ./setuid-test;
./setuid-test "whoami" 
# Outputs current user instead of nobody

[EDIT 2] I still have not worked out the problem, but I suppose it might be because the SuSE machine is a VM. A workaround might be to configure this behaviour via /etc/sudoers instead.

marked as duplicate by Gilles, Julie Pelletier, Scott, Anthon, slm bash Aug 21 '16 at 18:00

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • You did the chown after the chmod ? That might cause the setuid bit to be removed... – Stephen Harris Aug 19 '16 at 15:11
  • @StephenHarris: Right, this is not the problem though. Just to be sure, I ran the test again with the same result. Also, I compared the permissions with my PC version, with ls; the bit is set correctly. Thanks for pointing out the mistake, I will correct my post. – phobic Aug 19 '16 at 15:53
  • 2
    What happens if you put a setuid(geteuid()) call before the system()? Or just a printf("%d\n",geteuid()); call? – Stephen Harris Aug 19 '16 at 16:01
  • @StephenHarris: This prints the id of nobody in both cases. But whoami still shows the the current user. – phobic Aug 19 '16 at 16:35
  • So that shows the setuid is working. The problem is occuring afterwards. What happens if you run id instead of whoami ? – Stephen Harris Aug 19 '16 at 16:46

The setuid may "work", but is easily detected and undone later. I compared this with a similarly-intentioned program sue, which I use locally in an alternate account dickey (naming the program dickey).

On my Debian 7 system, I get this output (yours is "foo"):

$ ./foo id;dickey id
uid=1001(tom) gid=100(users) euid=1006(dickey) egid=50(staff) groups=100(users),27(sudo)
uid=1006(dickey) gid=100(users) groups=100(users),27(sudo)

On my OpenSUSE 13, I get something different:

$ ./foo id;dickey id
uid=1000(thomas) gid=100(users) groups=100(users),10(wheel)
uid=1003(dickey) gid=100(users) groups=100(users),10(wheel)

The reason for the difference is that your program does not set its real uid/gid values to match the effective uid/gid values, and a helpful program (perhaps apparmor) is stripping off the unwanted permissions.

This still isn't a perfect solution (I have a to-do item for CentOS 7 where another helpful program interferes with setuid programs). But it should point you in the right direction.

Further reading:

Not the answer you're looking for? Browse other questions tagged or ask your own question.