简体   繁体   中英

Why do files in /proc/self end up being owned by root if a program has its setuid bit set?

I have this small program:

#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <sys/prctl.h>

extern char **environ;

int main()
{
   char * const arglist[] = { "/bin/ls", "-l", "/proc/self/maps", NULL };
   uid_t uid, euid, suid;
   gid_t gid, egid, sgid;

   getresuid(&uid, &euid, &suid);
   printf("Before: uid: %u, euid: %u, suid: %u\n", uid, euid, suid);
   uid = euid;
   setresuid(uid, euid, suid);
   getresuid(&uid, &euid, &suid);
   printf(" After: uid: %u, euid: %u, suid: %u\n", uid, euid, suid);

   getresgid(&gid, &egid, &sgid);
   printf("Before: gid: %u, egid: %u, sgid: %u\n", gid, egid, sgid);
   gid = egid;
   setresuid(gid, egid, sgid);
   getresuid(&gid, &egid, &sgid);
   printf(" After: gid: %u, egid: %u, sgid: %u\n", gid, egid, sgid);

   printf("Get result == %d\n", prctl(PR_GET_DUMPABLE, 0, 0, 0, 0));
   printf("Set result == %d\n", prctl(PR_SET_DUMPABLE, 1, 0, 0, 0));
   printf("Get result == %d\n", prctl(PR_GET_DUMPABLE, 0, 0, 0, 0));

   if (fork())
   {
      return 0;
   }
   execve(arglist[0], arglist, environ);
}

I compile this program into an executable named small-test and change it's ownership to a testing user:

[omnifarious@foohost ~]$ ls -l small-test
-rwxrwxr-x. 1 testing testing 8512 Oct 23 12:55 small-test

Then I run the program:

[omnifarious@foohost ~]$ ./small-test 
Before: uid: 1001, euid: 1001, suid: 1001
 After: uid: 1001, euid: 1001, suid: 1001
Before: gid: 1001, egid: 1001, sgid: 1001
 After: gid: 1001, egid: 1001, sgid: 1001
Get result == 1
Set result == 0
Get result == 1
-r--r--r--. 1 hopper hopper 0 Oct 23 14:50 /proc/self/maps

So far, so good. Then I do this:

[omnifarious@foohost ~]$ sudo chmod ug+s ./small-test
[omnifarious@foohost ~]$ ls -l ./small-test
-rwsrwsr-x. 1 testing testing 8512 Oct 23 12:55 ./small-test
[omnifarious@foohost ~]$ ./small-test 
Before: uid: 1001, euid: 1002, suid: 1002
 After: uid: 1002, euid: 1002, suid: 1002
Before: gid: 1001, egid: 1002, sgid: 1002
 After: gid: 1002, egid: 1002, sgid: 1002
Get result == 0
Set result == 0
Get result == 1
-r--r--r--. 1 root root 0 Oct 23 12:59 /proc/self/maps

Why does /proc/self/maps end up being owned by root instead of by testing or omnifarious ? Note that the result does not change if I remove the fork .

The reason this is vexing me is that I need create a program that puts itself in a namespace as a user other than the one that executed it. This is so that I don't have access to cgroups and other things owned by the user that started the program. But I'm not being allowed to write to the program's uid_map or gid_map and so I can't set up the namespace properly.

Note: I edited this question to include a call to prctl to set (and read) the DUMPABLE flag as an answer (and the manual) indicated that resetting this should fix the owner on /proc/self/* files. It didn't, as you can see by the new program.

Edit: The above program has a bug in which it is calling setresuid instead of setresgid . This is what caused my problem even after adding the call to prctl . The prctl(PR_SET_DUMPABLE, 1); call has no effect if the real and effective group and user ids of the process are not the same.

Any suid process will default to have its /proc/self directory owned by root for security reasons (to prevent users from inducing a core dump and inspecting its memory for valuable info).

You can set the owner after a suid by manually making the process dumpable with the prctl PR_SET_DUMPABLE .


Here's proc(5) , containing a description of what's going on and how to affect it:

   /proc/[pid]
          There is a numerical subdirectory for each running
          process; the subdirectory is named by the  process
          ID.

          Each /proc/[pid] subdirectory contains the pseudo-
          files  and  directories  described  below.   These
          files are normally owned by the effective user and
          effective group ID of the process.  However, as  a
          security  measure, the ownership is made root:root
          if the process's "dumpable" attribute is set to  a
          value other than 1.  This attribute may change for
          the following reasons:

          *  The  attribute  was  explicitly  set  via   the
             prctl(2) PR_SET_DUMPABLE operation.

          *  The  attribute  was  reset  to the value in the
             file   /proc/sys/fs/suid_dumpable    (described
             below), for the reasons described in prctl(2).

          Resetting  the  "dumpable"  attribute to 1 reverts
          the ownership of the /proc/[pid]/*  files  to  the
          process's real UID and real GID.

Below, suid_dumpable has this to say about why the default is what it is:

          1 ("debug")
                 All  processes  dump  core  when  possible.
                 (Reasons  why  a process might nevertheless
                 not dump core are  described  in  core(5).)
                 The  core  dump  is owned by the filesystem
                 user ID of the dumping process and no secu‐
                 rity is applied.  This is intended for sys‐
                 tem debugging situations only: this mode is
                 insecure  because  it  allows  unprivileged
                 users to examine  the  memory  contents  of
                 privileged processes.

And as a bonus, prctl(2) lists non-suid circumstances that affect dumpability:

   PR_SET_DUMPABLE (since Linux 2.3.20)
          (...)
          Normally,  this  flag is set to 1.  However, it is
          reset to the current value contained in  the  file
          /proc/sys/fs/suid_dumpable  (which  by default has
          the value 0), in the following circumstances:

          *  The process's effective user  or  group  ID  is
             changed.

          *  The  process's  filesystem  user or group ID is
             changed (see credentials(7)).

          *  The process executes (execve(2)) a  set-user-ID
             or  set-group-ID program, resulting in a change
             of either the effective user ID or  the  effec‐
             tive group ID.
          (...)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM