diff mbox series

[LEDE-DEV,v2,procd,2/2] service: initialize supplementary group ids

Message ID 1518404425-50957-2-git-send-email-yszhou4tech@gmail.com
State Accepted
Delegated to: John Crispin
Headers show
Series [LEDE-DEV,v2,procd,1/2] service: add func for string config change check | expand

Commit Message

Yousong Zhou Feb. 12, 2018, 3 a.m. UTC
We currently only call setgid() with user's primary group id for service
instance processes.  In the case of a user belong to multiple groups,
it's natural to also explicitly initialize their supplementary group ids

Fixes FS#988

Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
---
 service/instance.c | 13 ++++++++++++-
 service/instance.h |  1 +
 2 files changed, 13 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/service/instance.c b/service/instance.c
index c3f8b56..76573f7 100644
--- a/service/instance.c
+++ b/service/instance.c
@@ -17,6 +17,7 @@ 
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
+#include <grp.h>
 #include <net/if.h>
 #include <unistd.h>
 #include <stdint.h>
@@ -348,6 +349,10 @@  instance_run(struct service_instance *in, int _stdout, int _stderr)
 		closefd(_stderr);
 	}
 
+	if (in->user && in->gid && initgroups(in->user, in->gid)) {
+		ERROR("failed to initgroups() for user %s: %m\n", in->user);
+		exit(127);
+	}
 	if (in->gid && setgid(in->gid)) {
 		ERROR("failed to set group id %d: %m\n", in->gid);
 		exit(127);
@@ -614,6 +619,9 @@  instance_config_changed(struct service_instance *in, struct service_instance *in
 	if (in->nice != in_new->nice)
 		return true;
 
+	if (string_changed(in->user, in_new->user))
+		return true;
+
 	if (in->uid != in_new->uid)
 		return true;
 
@@ -863,8 +871,10 @@  instance_config_parse(struct service_instance *in)
 	}
 
 	if (tb[INSTANCE_ATTR_USER]) {
-		struct passwd *p = getpwnam(blobmsg_get_string(tb[INSTANCE_ATTR_USER]));
+		const char *user = blobmsg_get_string(tb[INSTANCE_ATTR_USER]);
+		struct passwd *p = getpwnam(user);
 		if (p) {
+			in->user = strdup(user);
 			in->uid = p->pw_uid;
 			in->gid = p->pw_gid;
 		}
@@ -983,6 +993,7 @@  instance_free(struct service_instance *in)
 	watch_del(in);
 	instance_config_cleanup(in);
 	free(in->config);
+	free(in->user);
 	free(in);
 }
 
diff --git a/service/instance.h b/service/instance.h
index bdd14de..771406c 100644
--- a/service/instance.h
+++ b/service/instance.h
@@ -42,6 +42,7 @@  struct service_instance {
 	int8_t nice;
 	bool valid;
 
+	char *user;
 	uid_t uid;
 	gid_t gid;