2

I've compiled a binary Authorization and here's its permission

-rwsr-sr-x 1 root wheel 18464 10 26 22:07 ./Authorization

I ran it with the root permission

sudo ./Authorization

so in the beginning, the uid(real uid) and euid(effective uid) of my process is

uid:0 euid:0

then my program would invoke seteuid(501) to change the euid, now it's

uid:0 euid:501

At last, my program would invoke setuid(501), I expected the result is

uid:501 euid: 501

According to manual of of setuid()

The setuid() function is permitted if the effective user ID is that of the super user, or if the specified user ID is the same as the effective user ID.

However, setuid(501) return -1 which is not expected, and not the behavior described in the manual, WHY??

Here's my code

#include <stdio.h>
#include <unistd.h>
int main(int argc, const char * argv[]) {
    printf("uid: %d euid: %d\n", getuid(), geteuid());

    if (seteuid(501) == -1) {
        printf("seteuid error\n");
    }
    printf("seteuid(501)> uid: %d euid: %d\n", getuid(), geteuid());

    if (setuid(501) == -1) {
        printf("setuid error\n");
    }
    printf("setuid(501)> uid: %d euid: %d\n", getuid(), geteuid());

    return 0;
}

2 Answers2

1

You can try to figure it out using the classic error explanation. To do that you can add some code to the section:

 if (setuid(501) == -1) {
    printf("setuid error\n");
    printf ("Error while setting uid: %s\n", strerror(errno));
}

Dont forget to add these headers:

#include <string.h>
#include <errno.h>

Good luck!

rfermi
  • 179
  • 11
0

I tried your code on my macOS (10.12.6) and the error is EPERM (Operation not permitted).

Not sure if the macOS's man page is out of date. On my macOS, the setuid's man page is still of June 4, 1993.


On Linux (Debian 8.9), setuid's man page says:

setuid() sets the effective user ID of the calling process. If the effective UID of the caller is root, the real UID and saved set-user-ID are also set.

The APUE (2nd edition) book (8.11 Changing User IDs and Group IDs) says:

Only a superuser process can change the real user ID. Normally, the real user ID is set by the login(1) program when we log in and never changes. Because login is a superuser process, it sets all three user IDs when it calls setuid.

The POSIX.1-2008 (SUSv4) says:

The various behaviors of the setuid() and setgid() functions when called by non-privileged processes reflect the behavior of different historical implementations. For portability, it is recommended that new non-privileged applications use the seteuid() and setegid() functions instead.

pynexj
  • 19,215
  • 5
  • 38
  • 56