Alan Mills Alan Mills - 1 year ago 128
C Question

Linux dropping root permissions - C script

I have the following C script running in linux (Ubuntu 12.0.4) as a set root UID script (chmod 4755)

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

void main()
{ int fd;
/* Assume that /etc/zzz is an important system file,
* and it is owned by root with permission 0644.
* Before running this program, you should create
* the file /etc/zzz first. */
fd = open("/etc/zzz", O_RDWR | O_APPEND);
if (fd == -1) {
printf("Cannot open /etc/zzz\n");
exit(0);
}

/* Simulate the tasks conducted by the program */
sleep(1);
/* After the task, the root privileges are no longer needed, it’s time to relinquish the root privileges
permanently. */

setgroups(0, NULL);
setregid(getgid());
setreuid(getuid()); /* getuid() returns the real uid */

if(setregid(getgid()) == 0){
printf("Still root GID!\n");
exit(0);
} if(setreuid(getuid()) ==0){
printf("Still root UID\n");
exit(0);

if (fork()) { /* In the parent process */
close (fd);
exit(0);
} else { /* in the child process */
/* Now, assume that the child process is compromised,
malicious attackers have injected the following
statements into this process */

write (fd, "Malicious Data\n", 15);
close (fd);
}
}


As far as I can see, it should be setting the permissions back to the real user (ID 1000) but I am getting the "Still root" errors.

I have tried inserting
setuid(1000)
and
setuid(0)
just about the setgroups to remove any saved UID issues, but that just allows it to bypass the if statements, but still allows the "Malicious Data" to be written.

I have also tried closing the file
close(fd)
before dropping permissions, as I was unsure if you'd be unable to edit permissions whilst a file opened as root was still open. But I was still having the same issue

Any ideas as to what I am doing wrong here? And why it isn't working?

Answer Source

I assume you run the program with sudo. In that case, getuid will return 0. You'd have to explicitly call set the uid to the desired (e.g. 1000) uid.

Also, "Malicious Data\n" will be written because the fd was already opened when the process had elevated permissions, and you can still write there even if your process lost permissions. The process now cannot open the file again.

Everything is according to spec: if you want to disallow the process from writing to the file, make sure to close it before dropping permissions.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download