Ok, so I'm trying to wrap my head around what the s flag does in linux.

I've got the following code:

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>

int main(int argc, char **argv, char **envp)
  gid_t gid;
  uid_t uid;
  gid = getegid();
  uid = geteuid();

  printf("gid %d\n",gid);
  printf("uid %d\n",uid);

  setresgid(gid, gid, gid);
  setresuid(uid, uid, uid);


and the s flag is set for user.

-rwsr-xr-x 1 root root 7358 2017-08-24 17:45 a.out

so to my understanding, since the s flag is set, the effective gid, and uid should be the user.

However when I run this file as another user I get the following.

nebula@nebula:/tmp$ ./a.out 
gid 1000
uid 1000
uid=1000(nebula) gid=1000(nebula) groups=1000(nebula),4(adm),20(dialout),24(cdrom),46(plugdev),108(lpadmin),109(sambashare),110(admin)

I believe that this shows that the effective uid and gid were not set the way I would have thought.

Any help?? Thanks!

  • 1
    Since geteuid() does not return correct root value, try setreuid(-1, 0). (Or use getresuid() to access the save uid instead of the effective one.)
    – eckes
    Aug 25, 2017 at 2:15

2 Answers 2


Filesystems can be mounted with setuid disabled. This is normally done on removable devices (because the administrator has no control over what the removable device contains) and on network filesystems (unless the filesystem is mounted from a trusted server). It is good practice to do it for all filesystems that aren't supposed to allow privilege escalation, such as a filesystem for temporary files.

Check the mount point where your setuid executable is located:

df /tmp

Chances are that on your machine, /tmp is a separate filesystem — you'll see /tmp in the “Mounted on” column. Check the mount options for /tmp; on Linux you can look them up in /proc/mounts:

grep /tmp /proc/mounts

If you see nosuid as one of the options in the fourth column, the filesystem is mounted with setuid and setgid disabled: ls still lists the bits and chmod still changes them, but they have no effect.

Do your experiments on another filesystem. /var/tmp is usually mounted on the same filesystem as / and that one needs setuid enabled for programs like (/usr)/bin/su and (/usr)/bin/sudo.

The setuid/setgid bits can also be disabled via a security framework such as SELinux. See this thread on ServerFault for how to investigate this.

  1. There seems to be a minor bug in your program.

You have the s bit set only for owner, not group, but you're using the gid when for all params in setresuid & setresgid (lines 17 & 18). [edit:] Because of this, the gid will belong to the user who runs the program, not the owner of a.out.

If you change the params on those lines to uid, you should get the expected result. Subject to #2 below.

  1. The output for the geteuid seems anomalous. It should be 0. I would investigate it if I were you. I'm unable to replicate it though.

If you're only concerned about why setresuid and setresgid aren't working properly, set them to 0 (or any valid uid/gid numbers) and see what happens.

BTW, you should check for their return values.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .