From: Lennart Poettering Date: Thu, 24 Oct 2024 08:50:16 +0000 (+0200) Subject: user-util: tighten shell validation a tiny bit X-Git-Tag: v257-rc1~146 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4167e9e210818d79eca0de2cf992623abed7073c;p=thirdparty%2Fsystemd.git user-util: tighten shell validation a tiny bit --- diff --git a/src/basic/user-util.c b/src/basic/user-util.c index 6de5e4705eb..9dcf16d7a43 100644 --- a/src/basic/user-util.c +++ b/src/basic/user-util.c @@ -884,6 +884,17 @@ bool valid_home(const char *p) { return true; } +bool valid_shell(const char *p) { + /* We have the same requirements, so just piggy-back on the home check. + * + * Let's ignore /etc/shells because this is only applicable to real and not system users. It is also + * incompatible with the idea of empty /etc/. */ + if (!valid_home(p)) + return false; + + return !endswith(p, "/"); /* one additional restriction: shells may not be dirs */ +} + int maybe_setgroups(size_t size, const gid_t *list) { int r; diff --git a/src/basic/user-util.h b/src/basic/user-util.h index 9d07ef31d22..777451b8c88 100644 --- a/src/basic/user-util.h +++ b/src/basic/user-util.h @@ -108,15 +108,7 @@ bool valid_user_group_name(const char *u, ValidUserFlags flags); bool valid_gecos(const char *d); char* mangle_gecos(const char *d); bool valid_home(const char *p); - -static inline bool valid_shell(const char *p) { - /* We have the same requirements, so just piggy-back on the home check. - * - * Let's ignore /etc/shells because this is only applicable to real and - * not system users. It is also incompatible with the idea of empty /etc. - */ - return valid_home(p); -} +bool valid_shell(const char *p); int maybe_setgroups(size_t size, const gid_t *list); diff --git a/src/test/test-user-util.c b/src/test/test-user-util.c index e21d8da478a..af06161bad3 100644 --- a/src/test/test-user-util.c +++ b/src/test/test-user-util.c @@ -318,6 +318,24 @@ TEST(valid_home) { assert_se(valid_home("/")); assert_se(valid_home("/home")); assert_se(valid_home("/home/foo")); + assert_se(valid_home("/home/foo/")); +} + +TEST(valid_shell) { + assert_se(!valid_shell(NULL)); + assert_se(!valid_shell("")); + assert_se(!valid_shell(".")); + assert_se(!valid_shell("/shell/..")); + assert_se(!valid_shell("/shell/../")); + assert_se(!valid_shell("/shell\n/foo")); + assert_se(!valid_shell("./piep")); + assert_se(!valid_shell("piep")); + assert_se(!valid_shell("/shell/user:lennart")); + assert_se(!valid_shell("/")); + assert_se(!valid_shell("/bin/sh/")); + assert_se(valid_shell("/shell")); + assert_se(valid_shell("/shell/foo")); + assert_se(valid_shell("/bin/sh")); } static void test_get_user_creds_one(const char *id, const char *name, uid_t uid, gid_t gid, const char *home, const char *shell) {