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);
}
}
setuid(1000)
setuid(0)
close(fd)
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.