As per my understanding,

  • RUID: uid of the caller of the process is called real uid.
  • EUID: effective uid means allowed privilege for that process.
// setuid_file.c
int main(void)
        int uid;
        printf("RUID : getuid() : %d\n",uid);
        printf("EUID : geteuid() : %d\n",uid);

        system("cat /etc/sudoers"); //only root user can access. here we can write any command which only root user can execute.
gcc setuid_file.c -o euid_zero
chmod ug+s euid_zero

So, on root terminal, I have set suid and guid for the euid_zero executable. Now, ff I try to run the executable using normal user, then below is the output.

ll euid_zero
-rwsr-sr-x 1 root root 16768 Dec 30 00:59 euid_zero


uid=1000(kali) gid=1000(kali) groups=1000(kali)


RUID : getuid() : 1000
EUID : geteuid() : 0
cat: /etc/sudoers: Permission denied

So, here EUID is zero then also we can not gain root privilege. So, that means we have access privilege according to RUID, then what is the meaning of EUID if there is no use of EUID?

2 Answers 2


It allows the process to temporarily raise and lower privileges as it needs.

For example, a file-server daemon (smbd, ftpd) starts as root, but then seteuid()'s to the logged-in user's EUID. Now it can run most of the time with the logged-in user's EUID, letting the kernel apply file access checks, but still be able to raise its privileges back to EUID 0 for certain operations.

But note that when you use system(), this invokes the command through /bin/sh, and the Bash shell deliberately drops privileges whenever it detects an UID/EUID mismatch. Your own setuid process could in fact open /etc/shadow just fine – it's only tools launched through system() that won't be able to.

If you replace all system() calls with fork+exec, or even a simple open("/etc/shadow", O_RDONLY), you will see that having RUID=1000 but EUID=0 allows you to access the file. (Additionally, you will also see id reporting both sets of UID/GID.)

  • True, except the OP's sh is likely dash, not bash. Interestingly, dash used to behave differently and man 3 system still describes the old behavior. See the links in my answer. Nowadays there is no difference in this matter and your answer may as well say "Dash". Jan 1 at 19:25

In general EUID itself works as you expect, the "problem" here is with system(3) and sh it uses. See the manual (man 3 system):

system() will not, in fact, work properly from programs with set-user-ID or set-group-ID privileges on systems on which /bin/sh is bash version 2: as a security measure, bash 2 drops privileges on startup. (Debian uses a different shell, dash(1), which does not do this when invoked as sh.)

It turns out the manual is not up-to-date. Nowadays dash behaves like bash. Frankly, I don't know what shell your OS uses as sh (you tagged , Ubuntu uses dash; but kali in your question may suggest Kali, I'm not sure what Kali uses). Check with ls -l /bin/sh, it's probably dash. Regardless what it is, it most likely drops privileges and this is the reason of Permission denied you observed.

Even if your sh didn't drop privileges, system() wouldn't be a good idea. The already linked manual explicitly disadvises it:

Do not use system() from a privileged program (a set-user-ID or set-group-ID program, or a program with capabilities) because strange values for some environment variables might be used to subvert system integrity.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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