From afade2356ea148e715307be8f7334b790282341e Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 29 Jul 2011 23:10:07 -0400 Subject: [PATCH] add setxid.c for new set*id() framework. missed in last commit. --- src/unistd/setxid.c | 49 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/unistd/setxid.c diff --git a/src/unistd/setxid.c b/src/unistd/setxid.c new file mode 100644 index 00000000..d3bfaf62 --- /dev/null +++ b/src/unistd/setxid.c @@ -0,0 +1,49 @@ +#include +#include +#include +#include "syscall.h" +#include "libc.h" + +struct ctx { + int id, eid, sid; + int nr, rlim, err; +}; + +/* We jump through hoops to eliminate the possibility of partial failures. */ + +static void do_setxid(void *p) +{ + struct ctx *c = p; + if (c->err) return; + if (c->rlim && c->id >= 0 && c->id != getuid()) { + struct rlimit inf = { RLIM_INFINITY, RLIM_INFINITY }, old; + getrlimit(RLIMIT_NPROC, &old); + if (setrlimit(RLIMIT_NPROC, &inf) && libc.threads_minus_1) { + c->err = errno; + return; + } + if (__syscall(c->nr, c->id, c->eid, c->sid)) + c->err = errno; + setrlimit(RLIMIT_NPROC, &old); + return; + } + if (__syscall(c->nr, c->id, c->eid, c->sid)) + c->err = errno; +} + +int __setxid(int nr, int id, int eid, int sid) +{ + struct ctx c = { .nr = nr, .id = id, .eid = eid, .sid = sid }; + switch (nr) { + case SYS_setuid: + case SYS_setreuid: + case SYS_setresuid: + c.rlim = 1; + } + __synccall(do_setxid, &c); + if (c.err) { + errno = c.err; + return -1; + } + return 0; +} -- 2.20.1