1
0

setxid.c 1.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. #include <unistd.h>
  2. #include <errno.h>
  3. #include <sys/resource.h>
  4. #include "syscall.h"
  5. #include "libc.h"
  6. struct ctx {
  7. int id, eid, sid;
  8. int nr, rlim, err;
  9. };
  10. /* We jump through hoops to eliminate the possibility of partial failures. */
  11. int __setrlimit(int, const struct rlimit *);
  12. static void do_setxid(void *p)
  13. {
  14. struct ctx *c = p;
  15. if (c->err) return;
  16. if (c->rlim && c->id >= 0 && c->id != getuid()) {
  17. struct rlimit inf = { RLIM_INFINITY, RLIM_INFINITY }, old;
  18. getrlimit(RLIMIT_NPROC, &old);
  19. if ((c->err = -__setrlimit(RLIMIT_NPROC, &inf)) && libc.threads_minus_1)
  20. return;
  21. c->err = -__syscall(c->nr, c->id, c->eid, c->sid);
  22. __setrlimit(RLIMIT_NPROC, &old);
  23. return;
  24. }
  25. c->err = -__syscall(c->nr, c->id, c->eid, c->sid);
  26. }
  27. int __setxid(int nr, int id, int eid, int sid)
  28. {
  29. struct ctx c = { .nr = nr, .id = id, .eid = eid, .sid = sid };
  30. switch (nr) {
  31. case SYS_setuid:
  32. case SYS_setreuid:
  33. case SYS_setresuid:
  34. c.rlim = 1;
  35. }
  36. __synccall(do_setxid, &c);
  37. if (c.err) {
  38. errno = c.err;
  39. return -1;
  40. }
  41. return 0;
  42. }