diff options
author | Jo-Philipp Wich <jow@openwrt.org> | 2015-05-05 11:08:24 +0200 |
---|---|---|
committer | Jo-Philipp Wich <jow@openwrt.org> | 2015-05-05 11:08:24 +0200 |
commit | a6afa72f192f6efe8374d0f0c77fb2a545225a92 (patch) | |
tree | b35722d10ad39cc396c2adc1d5da8a68bb71de34 /service | |
parent | 312d0fc22d32171b5b2f6cf5272b11784888dfbe (diff) | |
download | unitd-a6afa72f192f6efe8374d0f0c77fb2a545225a92.tar unitd-a6afa72f192f6efe8374d0f0c77fb2a545225a92.zip |
instance: handle setgid() before setuid()
When attempting to run a service with an unprivileged user and group
id procd, the following error might occur:
procd: failed to set uid:1000, gid:1000
This is due to the fact that procd first performs the setuid(), then
the setgid() call.
Usually there no sufficient permissions after a setuid() anymore to
change the effective group id of the process.
Refactor the code to:
* Swap the invocations (first gid, then uid)
* Don't set user or group id if it is 0
* Handle errors independently and make them more verbose
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
Diffstat (limited to 'service')
-rw-r--r-- | service/instance.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/service/instance.c b/service/instance.c index 1fb65fa..3367885 100644 --- a/service/instance.c +++ b/service/instance.c @@ -282,12 +282,15 @@ instance_run(struct service_instance *in, int _stdout, int _stderr) closefd(_stderr); } - if (in->uid || in->gid) { - if (setuid(in->uid) || setgid(in->gid)) { - ERROR("failed to set uid:%d, gid:%d\n", in->uid, in->gid); - exit(127); - } + if (in->gid && setgid(in->gid)) { + ERROR("failed to set group id %d: %d (%s)\n", in->gid, errno, strerror(errno)); + exit(127); + } + if (in->uid && setuid(in->uid)) { + ERROR("failed to set user id %d: %d (%s)\n", in->uid, errno, strerror(errno)); + exit(127); } + execvp(argv[0], argv); exit(127); } |