1

From APUE

The saved set-user-ID is copied from the effective user ID by exec functions. If the file’s set-user-ID bit is set, this copy is saved after exec stores the effective user ID from the file’s user ID.

Does it mean that

  • first the process's EUID is changed to the file's user ID,

  • then the process's saved set-user-ID is changed to the process's EUID?

So both the process's EUID and saved set-user-ID are changed to the file's user ID?

  • From the text, I would say the saved set-user-ID is set to the true uid of the user that invoked the binary. – Rui F Ribeiro Apr 25 '18 at 19:26
4

The documentation in credentials(7) clarifies this a bit for Linux systems:

User and group identifiers

Each process has various associated user and group IDs. These IDs are integers, respectively represented using the types uid_t and gid_t (defined in <sys/types.h>).

On Linux, each process has the following user and group identifiers:

  • Real user ID and real group ID. These IDs determine who owns the process. A process can obtain its real user (group) ID using getuid(2).

  • Effective user ID and effective group ID. These IDs are used by the kernel to determine the permissions that the process will have when accessing shared resources such as message queues, shared memory, and semaphores. On most UNIX systems, these IDs also determine the permissions when accessing files. However, Linux uses the filesystem IDs described below for this task. A process can obtain its effective user (group) ID using geteuid(2).

  • Saved set-user-ID and saved set-group-ID. These IDs are used in set-user-ID and set-group-ID programs to save a copy of the corresponding effective IDs that were set when the program was executed (see execve(2)). A set-user-ID program can assume and drop privileges by switching its effective user ID back and forth between the values in its real user ID and saved set-user-ID. This switching is done via calls to seteuid(2), setreuid(2), or setresuid(2). A set-group-ID program performs the analogous tasks using setegid(2), setregid(2), or setresgid(2). A process can obtain its saved set-user-ID (set-group-ID) using getresuid(2).

[...]

I made a test program to take a look at what happens:

#define _GNU_SOURCE

#include <stdio.h>
#include <unistd.h>

int getuids(uid_t *uids) {
  if(getresuid(&uids[0], &uids[1], &uids[2]) == -1) {
    perror("Unable to get UIDs\n");
    return 0;
  }
  return 1;
}

int getgids(gid_t *gids) {
  if(getresgid(&gids[0], &gids[1], &gids[2]) == -1) {
    perror("Unable to get GIDs\n");
    return 0;
  }
  return 1;
}

int main(void) {
  uid_t uids[3];
  gid_t gids[3];

  if(getuids(uids) && getgids(gids)) {
    printf("Real ID: user %d, group %d\n", (int)uids[0], (int)gids[0]);
    printf("Effective ID: user %d, group %d\n", (int)uids[1], (int)gids[1]);
    printf("Set-ID: user %d, group %d\n", (int)uids[2], (int)gids[2]);

    seteuid(uids[0]);
    getuids(uids);
    getgids(gids);
    printf("Effective ID: user %d, group %d\n", (int)uids[1], (int)gids[1]);
  }

  return 0;
}

Here's the file:

server /home/erik # ls -l perms
-r-sr-sr-x 1 nobody nobody 8280 Apr 26 00:36 perms

Running as root:

server-calgary /home/erik # ./perms
Real ID: user 0, group 0
Effective ID: user 65534, group 65534
Set-ID: user 65534, group 65534
Effective ID: user 0, group 65534

Running as erik:

erik@server ~ $ ./perms
Real ID: user 1000, group 1000
Effective ID: user 65534, group 65534
Set-ID: user 65534, group 65534
Effective ID: user 1000, group 65534

As my test program shows, if a file is set-ID, the EUID/EGID starts with whatever the owner/group is on the file (only set-UID and set-UID+GID permissions work!), but it can be changed between that and the caller's real ID if the program wants.

  • Thanks. Just to make sure if I understand your reply. Does it mean that If the executable file’s set-user-ID bit is set, exec functions will first change the process's EUID to the file's user ID, and then change the process's saved set-user-ID to the process's EUID? So both the process's EUID and saved set-user-ID are changed to the file's user ID? – Tim Apr 26 '18 at 13:09
  • @Tim That's probably the startup process works internally (although since the kernel's doing it, both could be set at the same time, and you wouldn't be able to tell the difference!) – ErikF Apr 26 '18 at 17:29
  • What is the purpose of having both the process's EUID and saved set-user-ID set to the file's user ID? For what purpose will the value in saved set-user-ID be used? – Tim Apr 26 '18 at 17:39
  • As the documentation indicates (and my program does), the program can switch between the set-ID and real-ID at any time; they have to be saved so that the program (and the kernel) knows what those IDs are. – ErikF Apr 26 '18 at 18:06
  • "they have to be saved so that the program (and the kernel) knows what those IDs are", do you mean the file's owner user ID by "they"? The file is always there for query for its owner user ID, so why is its owner user id have to be saved? – Tim Apr 26 '18 at 18:09

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.