Why the setuid program does not have the privilege to execute system()

56 Views Asked by At

I have the following program:

$ cat cat.c
#include <err.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
  char buf[32];

  if(argc == 1) {
    errx(1, "please specify an argument.");
  }

  sprintf(buf, "cat %s", argv[1]);
  system(buf);
  return 0;
}
$ gcc cat.c -o mycat
$ chmod +s mycat; sudo chown root mycat
$ ls -lth mycat
-rwsr-sr-x 1 root ... 11:12 mycat
$ ls -lth secret
-rw------- 1 root ... 11:10 secret

I thought ./mycat secret should be able to read the secret file because mycat is a setuid program, and its owner is root. However, here is what I get:

$ ./mycat secret
cat: secret: Permission denied
$ sudo chown user1 secret
$ ./mycat secret
4ea6f17dd6818

Anything I misunderstood?

1

There are 1 best solutions below

1
Philippe On BEST ANSWER

This program demonstrates what's working and what doesn't :

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
  char buf[64];
  if (fork() == 0){
    char *newargv[] = { "cat", argv[1], NULL };
    execve("/usr/bin/cat", newargv, NULL); // This call directly `cat` without spawning a `shell`, so works as expected.
    return 0;
  }
  sprintf(buf, "cat %s", argv[1]);
  system(buf); // `system` spawns a shell which then calls `cat`, as the `shell` lost setuid privilaege, `cat` fails with `Permission denied`.
  return 0;
}