From 2c542f6c65f858b3dba20f58db4da56572f67a54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20Serv=C3=A9n=20Mar=C3=ADn?= Date: Thu, 29 Apr 2021 14:09:31 +0200 Subject: [PATCH] fix: create relative home path correctly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, supplying a relative path via the --prefix flag to the useradd command triggers a bug in the creation of home directories. The code seems to unintentionally prepend a leading "/" to all paths, quietly transforming a relative prefixed home path into an absolute path. This can be seen in the following strace logs from running "useradd --create-home --prefix tmp/root squat": ``` access("tmp/root//home/squat", F_OK) = -1 ENOENT (No such file or directory) access("/mp", F_OK) = 0 access("/mp/root", F_OK) = 0 access("/mp/root/home", F_OK) = 0 access("/mp/root/home/squat", F_OK) = -1 ENOENT (No such file or directory) mkdir("/mp/root/home/squat", 000) = 0 chown("/mp/root/home/squat", 0, 0) = 0 chmod("/mp/root/home/squat", 0755) = 0 chown("tmp/root//home/squat", 1000, 1000) = -1 ENOENT (No such file or directory) chmod("tmp/root//home/squat", 0700) = -1 ENOENT (No such file or directory) ``` Note that the relative path is correctly probed in the beginning and it is only during the recursive creation that the path is turned into an absolute path. This invocation results in the creation of a "/mp" hierarchy in the root of the filesystem. Similar problems occur when using `--prefix ./tmp/root`. This commit fixes the handling of relative paths by not assuming that the given path is anchored with a "/". Signed-off-by: Lucas Servén Marín --- src/useradd.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/useradd.c b/src/useradd.c index a0369cd8..b8beadd8 100644 --- a/src/useradd.c +++ b/src/useradd.c @@ -2171,7 +2171,6 @@ static void create_home (void) Prog, user_home); fail_exit (E_HOMEDIR); } - ++bhome; #ifdef WITH_SELINUX if (set_selinux_file_context (prefix_user_home) != 0) { @@ -2188,7 +2187,11 @@ static void create_home (void) */ cp = strtok (bhome, "/"); while (cp) { - strcat (path, "/"); + /* Avoid turning a relative path into an absolute path. + */ + if (bhome[0] == '/' || strlen (path) != 0) { + strcat (path, "/"); + } strcat (path, cp); if (access (path, F_OK) != 0) { /* Check if parent directory is BTRFS, fail if requesting