[systemd-commits] 2 commits - src/login

Lennart Poettering lennart at kemper.freedesktop.org
Tue Jan 27 10:02:53 PST 2015


 src/login/logind-user.c |   30 +++++++++++++++++++++++++-----
 1 file changed, 25 insertions(+), 5 deletions(-)

New commits:
commit 11c6476a08af7a8a9ae6a2d0f8370587f7b31663
Author: Christian Seiler <christian at iwakd.de>
Date:   Tue Jan 27 18:58:40 2015 +0100

    logind: chown+chmod /run/user/$UID if mount(tmpfs) fails with EPERM
    
    In containers without CAP_SYS_ADMIN, it is not possible to mount tmpfs
    (or any filesystem for that matter) on top of /run/user/$UID.
    Previously, logind just failed in such a situation.
    
    Now, logind will resort to chown+chmod of the directory instead. This
    allows logind still to work in those environments, although without the
    guarantees it provides (i.e. users not being able to DOS /run or other
    users' /run/user/$UID space) when CAP_SYS_ADMIN is available.

diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index d1f91d6..928afd3 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -335,8 +335,20 @@ static int user_mkdir_runtime_path(User *u) {
 
                 r = mount("tmpfs", p, "tmpfs", MS_NODEV|MS_NOSUID, t);
                 if (r < 0) {
-                        r = log_error_errno(errno, "Failed to mount per-user tmpfs directory %s: %m", p);
-                        goto fail;
+                        if (errno != EPERM) {
+                                r = log_error_errno(errno, "Failed to mount per-user tmpfs directory %s: %m", p);
+                                goto fail;
+                        }
+
+                        /* Lacking permissions, maybe
+                         * CAP_SYS_ADMIN-less container? In this case,
+                         * just use a normal directory. */
+
+                        r = chmod_and_chown(p, 0700, u->uid, u->gid);
+                        if (r < 0) {
+                                log_error_errno(r, "Failed to change runtime directory ownership and mode: %m");
+                                goto fail;
+                        }
                 }
         }
 
@@ -514,7 +526,11 @@ static int user_remove_runtime_path(User *u) {
         if (r < 0)
                 log_error_errno(r, "Failed to remove runtime directory %s: %m", u->runtime_path);
 
-        if (umount2(u->runtime_path, MNT_DETACH) < 0)
+        /* Ignore cases where the directory isn't mounted, as that's
+         * quite possible, if we lacked the permissions to mount
+         * something */
+        r = umount2(u->runtime_path, MNT_DETACH);
+        if (r < 0 && errno != EINVAL && errno != ENOENT)
                 log_error_errno(errno, "Failed to unmount user runtime directory %s: %m", u->runtime_path);
 
         r = rm_rf(u->runtime_path, false, true, false);

commit 4d858e7d9f39038713f760d7acc64acf7bba2aa7
Author: Christian Seiler <christian at iwakd.de>
Date:   Fri Jan 23 15:26:18 2015 +0100

    logind: remove per-user runtime dir again if setup fails
    
    If setup of per-user runtime dir fails, clean up afterwards by removing
    the directory before returning from the function, so we don't leave the
    directory behind.
    
    If this is not done, the second time the user logs in logind would
    assume that the directory is already set up, even though it isn't.

diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index 49c373b..d1f91d6 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -328,7 +328,6 @@ static int user_mkdir_runtime_path(User *u) {
                         r = asprintf(&t, "mode=0700,smackfsroot=*,uid=" UID_FMT ",gid=" GID_FMT ",size=%zu", u->uid, u->gid, u->manager->runtime_dir_size);
                 else
                         r = asprintf(&t, "mode=0700,uid=" UID_FMT ",gid=" GID_FMT ",size=%zu", u->uid, u->gid, u->manager->runtime_dir_size);
-
                 if (r < 0) {
                         r = log_oom();
                         goto fail;
@@ -336,7 +335,7 @@ static int user_mkdir_runtime_path(User *u) {
 
                 r = mount("tmpfs", p, "tmpfs", MS_NODEV|MS_NOSUID, t);
                 if (r < 0) {
-                        log_error_errno(r, "Failed to mount per-user tmpfs directory %s: %m", p);
+                        r = log_error_errno(errno, "Failed to mount per-user tmpfs directory %s: %m", p);
                         goto fail;
                 }
         }
@@ -345,7 +344,12 @@ static int user_mkdir_runtime_path(User *u) {
         return 0;
 
 fail:
-        free(p);
+        if (p) {
+                /* Try to clean up, but ignore errors */
+                (void) rmdir(p);
+                free(p);
+        }
+
         u->runtime_path = NULL;
         return r;
 }



More information about the systemd-commits mailing list