Deep understanding of process permissions in Linux

Time:2021-4-29

Analysis of Linux Process permission

In Linux, most people are familiar with file permissions, but they don’t know much about process permissions. This paper summarizes the problem and phenomenon of process permission in Linux system.

It should be emphasized that this article is discussed under Linux system, because there are many differences between Linux and UNIX, and there are many differences between different UNIX systems.

Let’s get to the point and list the objects discussed in this paper: RUID (real user ID), euid (effective user ID), suid (saved user ID), fuid (file system user ID).

In addition to the above four, it also involves a bit set user ID bit, that is, the s flag bit other than RWX.

In addition, this paper mainly discusses that the rules of userid and groupid are basically the same, such as rgid, EGID, sgid, FGID, etc. This paper will not repeat the discussion on group ID.

First, there are two ways to view these UIDs: first, the PS command (PS – ax – O RUID – O euid – O suid – O fuid – O PID – O fname) lists these UIDs; The second is to view the status file (CAT / proc / 2495 / status | grep uid).

This paper creates five test users, test1 ~ test5, to be used in the sample discussion in this paper, representing common users with common permissions.

1: File owner user and program executor user are the same user

int main(int argc, char *argv[])
{
  while(1)sleep(1);
}
  $>g++ main.cpp -o a.out
  
  $>ll
  -rwxr-xr-x. 1 test1 test 6780 Sep 16 15:32 a.out
  The owner of the file is test1. We use the test1 user to execute the a.out program
  $>su test1
  $>./a.out &
  $>ps -ax -o ruid -o euid -o suid -o fuid -o pid -o fname | grep a.out
  502  502  502  502 3192 a.out
   (you can see that the four UIDs are all test1;)
  Now let's use test2 user to execute test1 program to see the result
  $su test2
  503  503  503  503 3234 a.out
  Then it is executed by the root user
  0   0   0   0 3257 a.out

Seeing this result, we can basically conclude that:
In common cases. These four IDs are only affected by the execution user, not by the file owner user. And the four UIDs are all equal to the ID of the executing user;

2、 Transfer authority to other users. Non root users can’t transfer permissions to other users, only root users can.

int main(int argc, char *argv[])
{
  if( setuid(503) < 0) perror ("setuid error");
  while(1)sleep(1);
}
  $>ll
  -rwxr-xr-x. 1 test1 test 6780 Sep 16 15:32 a.out 
  Execute with root
  $>./a.out
  Check the status, and all UIDs become test2 users.
  503  503  503  503 3592 a.out

  Changing setuid to seteuid will change euid and fuid to test2 user
  0  503   0  503 3614 a.out
  
  Changing setuid to setfsuid will change fuid to test2 user
  0   0   0  503 3636 a.out

  When you change the code to look like this
if( seteuid(503) < 0) perror ("seteuid error");
if( setfsuid(504) < 0) perror ("setfsuid error");
while(1)sleep(1);
  perhaps
if( setfsuid(504) < 0) perror ("setfsuid error");
if( setfeuid(503) < 0) perror ("seteuid error");
while(1)sleep(1);
  Execute with root user and get the same result
  0  503   0  503 3614 a.out 
  
Here I'd like to summarize: 1. Setuid is different from seteuid. Setuid gives up the root user's permission permanently and transfers it to a non root user,
You can no longer restore to the root user. Seteuid temporarily gives up the permission of the root user. You can restore to the root permission through seteuid (0).
This should be a well-known feature, this article will not give examples to demonstrate.
2. Seteuid will change both euid and fuid to the set value of euid. 3. The root user can change the permission user by calling setxxuid. Non root users cannot change and transfer permissions.

Let’s continue to look at the effect of s permission bit on process permission

3、 The s flag affects euid, suid, and fuid

int main(int argc, char *argv[])
{
  while(1)sleep(1);
}
  $>g++ main.cpp
  $>ll
   -rwxr-xr-x. 1 test1 test 6780 Sep 16 18:18 a.out
  $>chmod u+s a.out
  $>ll
   -rwsr-xr-x. 1 test1 test 6780 Sep 16 18:18 a.out

  Use the root user to view the user ID as
  0  502  502  502 4133 a.out

The most classic case of using s permission bit is passwd command

Now let’s look at their impact on file permissions, build a RUID, euid, and fuid that are different, and see which uid is the owner of the created file

4、 It is fuid, not euid, that affects the user’s file permissions. The uid is a unique attribute of Linux, and the UNIX system relies on euid to determine the user’s permissions.

int main(int argc, char *argv[])
{
  if( setfsuid(503) < 0) perror ("setfsuid error");
  FILE * fp = fopen("test.log", "a+");
  if(fp == NULL)
  {
    perror ("fopen error");
  }
  else
  {
    fclose(fp);
  }
  while(1)sleep(1);
}
  Using the s permission bit, the file owner is root, the executor is test1, and changing the fuid to test2, three UIDs are constructed, and each part is the same, which is convenient to observe the effect
 $>ll
  -rws---r-x. 1 root root 7397 Sep 16 18:53 a.out
 Run to view the status, RUID is test1, euid is root, fuid is test2
  502   0   0  503 4240 a.out
 $>ll
  -rws---r-x. 1 root root 7397 Sep 16 18:53 a.out
  -rw-rw-r--. 1 test2 test  0 Sep 16 18:54 test.log

5、 When fork child processes are used, all child processes inherit the four UIDs of the parent process, which are the same as the uid of the parent process

When using the exec series functions, suid is set to euid.

Thank you for reading, hope to help you, thank you for your support!