6

I created a setuid program in C. The executable looks like this:

-r-s-r-s--- 1 root users 13073 Jun 15 21:56 server

I execute the program as userA/users and try to set the uid/gid to userB/otherUsers. setgid() fails with Operation not permitted. userA is not part of otherUsers How can I change the effective gid?


[EDIT] Here is a small summary of what I did. My C program, executed as userA, sets uid and gid to userB and creates a file. Not as expected, the file belongs to the group root, because setgid() fails.

[userA@node uid]$ id
uid=11945(userA) gid=544(users) groups=544(users)
[userA@node uid]$ id userB
uid=11946(userB) gid=10792(otherUsers) groups=10792(otherUsers)
[userA@node uid]$ cat uid.c 
#include <stdio.h>
#include <unistd.h>

int main() {
  setuid(11946);
  setgid(10792);

FILE *f = fopen("userB_file", "w");
fclose(f);

return 0;
}
[userA@node uid]$ ls -l uid
-r-sr-sr-x 1 root root 7130 Jun 17 14:16 uid
[userA@node uid]$ ./uid 
[userA@node uid]$ ls -l userB_file 
-rw-r--r-- 1 userB root 0 Jun 17 14:19 userB_file
multiholle
  • 3,050
  • 8
  • 41
  • 60
  • 2
    Are you sure `setgid()` is running with the permissions of a user in the `users` group? That would cause it to fail with "Operation not permitted" because the read and exec/setuid privs don't extend to world/other. –  Jun 16 '12 at 05:17
  • I don't get that. Do I have to run my program as root? I thought setting the owner to root would be enough to change uid/gid. I won't be able to run the program as root. – multiholle Jun 16 '12 at 05:53
  • Unix permissions are owner / group / {world,other}. You have read and exec+setuid for owner (root) and group (users). You don't have your code posted, but if whatever is calling setgid() isn't either root or in the group users, that would give the error you're reporting. –  Jun 16 '12 at 05:58
  • I'm just calling setuid() and setgid() with the id's for userB/otherUsers. The program itself is executed by userA. Should I add some example code? – multiholle Jun 16 '12 at 06:07

1 Answers1

23

I suspect you're calling setuid before setgid. As soon as you call setuid to change the uid to something other than root, you've forfeited your permission to change the gid to an arbitrary value. You must call setgid first, then setuid.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • 1
    This is as obvious as simple! Damn, you're so right. I changed the order and of course, it works! Thanks. btw: I added my original C program in the question. – multiholle Jun 17 '12 at 21:30
  • It is actually not so obvious. It is not reported in the man page of setgid and neither in the man page of setuid. – Bemipefe Oct 06 '17 at 15:21
  • @Bemipefe: It should be obvious as a consequence of the permission model that you can't change your group id to anything you want when you're a normal unprivileged user. – R.. GitHub STOP HELPING ICE Oct 06 '17 at 15:24
  • @R.. I was referring to the fact that the setgid function must be called before the setuid function. This rule applies also to processes wich run as root user. – Bemipefe Oct 07 '17 at 17:12
  • 1
    @Bemipefe: That "rule" is just a consequence of the fact that only root can change gid to arbitrary groups. After calling `setuid` you're no longer root. – R.. GitHub STOP HELPING ICE Oct 07 '17 at 19:51