Assume I have a process with PID 1234 running in the background under user A.
If I run the following program as user A, it succeeds. If I run it as user B, it fails with open: Permission denied.
This makes sense, as the environ file is owned by user A and has read permission only for A.
But if I make the program set-user-ID for user A and run it as user B, it fails with read: Permission denied. This doesn’t seem to happen with a regular file having the same permissions. It also doesn’t happen if A is root.
Any ideas why? Is there any other way to get the environment of another process that works around this issue?
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, const char *argv[])
{
unsigned char ch = 0;
int fd = -1;
int read_result = -1;
setresuid(geteuid(), geteuid(), geteuid());
fd = open("/proc/1234/environ", O_RDONLY);
if (-1 == fd) {
perror("open");
return EXIT_FAILURE;
}
read_result = read(fd, &ch, 1);
if (-1 == read_result) {
perror("read");
return EXIT_FAILURE;
}
close(fd);
return EXIT_SUCCESS;
}
As you can see, if your program run without SETUID, open(2) gives you
Permission denied, whereas if you run the program with SETUID, open(2) works ok, but read(2) causes the same error. This happens because of additional permission check during each file operation on/proc/*inodes. Looks like this additional permission check uses something other than EUID of the running process. If you run GNU/Linux, for more details see NOTE at the beginning of the code in<kernel_source>/fs/proc/base.cand environ_read() function in the same file.One of the possible quick solutions:
rootsetuid(getuid())to drop priveleges as soon as possible, i.e. right after readingenvironfileIn this case any user from the given group could read
/proc/*/environof any other user.If you want to reduce the permissions of your program to allow only read
environfiles of the specific user (user A), you probably should think of some other tricks. For example config file, containing the user(s) whoseenvironfile(s) could be read.Always be careful with extra permissions. Especially with root permissions. Do necessary privileged operations and drop permissions as soon as possible.