instance: handle setgid() before setuid()
authorJo-Philipp Wich <jow@openwrt.org>
Tue, 5 May 2015 09:08:24 +0000 (11:08 +0200)
committerJo-Philipp Wich <jow@openwrt.org>
Tue, 5 May 2015 09:08:24 +0000 (11:08 +0200)
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>
service/instance.c

index 1fb65fa..3367885 100644 (file)
@@ -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);
 }