Hmpf, great, I just noticed I forgot to actually attach the
patch. :(

Here it is.

Sorry about the confusion,
Christian

Description: logind: handle runtime dir without CAP_SYS_ADMIN
 In (e.g. LXC) containers without CAP_SYS_ADMIN, logind fails to mount
 a tmpfs over /run/user/$UID (lacking mount permissions).
 .
 Now, logind will resort to chown+chmod of the directory instead. This
 allows logind to still 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.
Author: Christian Seiler <christ...@iwakd.de>
Origin: backport
Applied-Upstream: 4d858e7d9f39038713f760d7acc64acf7bba2aa7, 11c6476a08af7a8a9ae6a2d0f8370587f7b31663
Last-Update: 2015-02-17
---
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -340,8 +340,21 @@ static int user_mkdir_runtime_path(User
 
                 r = mount("tmpfs", p, "tmpfs", MS_NODEV|MS_NOSUID, t);
                 if (r < 0) {
-                        log_error("Failed to mount per-user tmpfs directory %s: %s", p, strerror(-r));
-                        goto fail;
+                        r = -errno;
+                        if (r != -EPERM) {
+                                log_error("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 director. */
+
+                        r = chmod_and_chown(p, 0700, u->uid, u->gid);
+                        if (r < 0) {
+                                log_error("Failed to change runtime directory ownership and mode: %s", strerror(-r));
+                                goto fail;
+                        }
                 }
         }
 
@@ -349,7 +362,11 @@ static int user_mkdir_runtime_path(User
         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;
 }

Reply via email to