From 47819f004cec3cc3e911ba69003b8b52bacbebef Mon Sep 17 00:00:00 2001 From: Johannes Heimansberg Date: Sun, 6 Sep 2020 09:22:50 +0200 Subject: start-stop-daemon, supervise-daemon: fix parsing of usernames passed via --user that start with a number start-stop-daemon and supervise-daemon parse usernames and group names passed via the --user argument as numeric UID/GID if they start with a number (e.g. user "4foo" will be treated as UID 4). This results in the process that is being started to run under a totally unexpected user if that UID exists. Even though the result of the sscanf calls are tested for a result of exactly 1, which means exactly one value was extracted, because sscanf's format string only contains only one placeholder, it will never return a value greater than 1, even if there are still characters left to be parsed. This causes start-stop-daemon and supervise-daemon to assume that usernames starting with a number are just that number. Adding a second placeholder "%1s" to the format string, which matches a string of length 1, makes sure that sscanf can distinguish between pure numbers (in which case it will return 1) and strings either starting with a number (in which case it will return 2) and any other string (in which case it will return 0). This fixes #379. This fixes #380. --- src/rc/start-stop-daemon.c | 5 +++-- src/rc/supervise-daemon.c | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/rc/start-stop-daemon.c b/src/rc/start-stop-daemon.c index aafada88..99e5b6a0 100644 --- a/src/rc/start-stop-daemon.c +++ b/src/rc/start-stop-daemon.c @@ -389,10 +389,11 @@ int main(int argc, char **argv) /* falls through */ case 'u': /* --user | */ { + char dummy[2]; p = optarg; tmp = strsep(&p, ":"); changeuser = xstrdup(tmp); - if (sscanf(tmp, "%d", &tid) != 1) + if (sscanf(tmp, "%d%1s", &tid, dummy) != 1) pw = getpwnam(tmp); else pw = getpwuid((uid_t)tid); @@ -413,7 +414,7 @@ int main(int argc, char **argv) if (p) { tmp = strsep (&p, ":"); - if (sscanf(tmp, "%d", &tid) != 1) + if (sscanf(tmp, "%d%1s", &tid, dummy) != 1) gr = getgrnam(tmp); else gr = getgrgid((gid_t) tid); diff --git a/src/rc/supervise-daemon.c b/src/rc/supervise-daemon.c index b3d63589..ea9e5333 100644 --- a/src/rc/supervise-daemon.c +++ b/src/rc/supervise-daemon.c @@ -855,10 +855,11 @@ int main(int argc, char **argv) case 'u': /* --user | */ { + char dummy[2]; p = optarg; tmp = strsep(&p, ":"); changeuser = xstrdup(tmp); - if (sscanf(tmp, "%d", &tid) != 1) + if (sscanf(tmp, "%d%1s", &tid, dummy) != 1) pw = getpwnam(tmp); else pw = getpwuid((uid_t)tid); @@ -879,7 +880,7 @@ int main(int argc, char **argv) if (p) { tmp = strsep (&p, ":"); - if (sscanf(tmp, "%d", &tid) != 1) + if (sscanf(tmp, "%d%1s", &tid, dummy) != 1) gr = getgrnam(tmp); else gr = getgrgid((gid_t) tid); -- cgit v1.2.3