]> granicus.if.org Git - linux-pam/commitdiff
Make / mount as rslave instead of bind mounting polydirs.
authorTomas Mraz <tmraz@fedoraproject.org>
Tue, 24 Jan 2012 19:03:28 +0000 (20:03 +0100)
committerTomas Mraz <tmraz@fedoraproject.org>
Tue, 24 Jan 2012 19:03:28 +0000 (20:03 +0100)
* modules/pam_namespace/pam_namespace.c (protect_dir): Drop the always argument.
(check_inst_parent): Drop the always argument from protect_dir().
(create_polydir): Likewise.
(ns_setup): Likewise and do not mark the polydir with MS_PRIVATE.
(setup_namespace): Mark the / with MS_SLAVE|MS_REC.
* modules/pam_namespace/pam_namespace.8.xml: Reflect the change in docs.

modules/pam_namespace/pam_namespace.8.xml
modules/pam_namespace/pam_namespace.c

index 48021c80e186fc00ae1b943ac1042fb60e69d93b..6ec3ad23402e40a744fc789813e077ef1bdb5c49 100644 (file)
            This option can be used on systems where the / mount point or
            its submounts are made shared (for example with a
            <command>mount --make-rshared /</command> command).
-           The module will make the polyinstantiated directory mount points
-           private. Normally the pam_namespace will try to detect the
+           The module will mark the whole directory tree so any mount and
+           unmount operations in the polyinstantiation namespace are private.
+           Normally the pam_namespace will try to detect the
            shared / mount point and make the polyinstantiated directories
            private automatically. This option has to be used just when
            only a subtree is shared and / is not.
           </para>
+          <para>
+           Note that mounts and unmounts done in the private namespace will not
+           affect the parent namespace if this option is used or when the
+           shared / mount point is autodetected.
+          </para>
         </listitem>
       </varlistentry>
 
index f0bffa1515a7a66669f4f8b4cbe456899468f9f0..470f493bd9bedc5b4b42055bab3a9dc11c867c27 100644 (file)
@@ -1003,7 +1003,7 @@ static int protect_mount(int dfd, const char *path, struct instance_data *idata)
        return 0;
 }
 
-static int protect_dir(const char *path, mode_t mode, int do_mkdir, int always,
+static int protect_dir(const char *path, mode_t mode, int do_mkdir,
        struct instance_data *idata)
 {
        char *p = strdup(path);
@@ -1082,7 +1082,7 @@ static int protect_dir(const char *path, mode_t mode, int do_mkdir, int always,
                }
        }
 
-       if ((flags & O_NOFOLLOW) || always) {
+       if (flags & O_NOFOLLOW) {
                /* we are inside user-owned dir - protect */
                if (protect_mount(rv, p, idata) == -1) {
                        save_errno = errno;
@@ -1124,7 +1124,7 @@ static int check_inst_parent(char *ipath, struct instance_data *idata)
        if (trailing_slash)
                *trailing_slash = '\0';
 
-       dfd = protect_dir(inst_parent, 0, 1, 0, idata);
+       dfd = protect_dir(inst_parent, 0, 1, idata);
 
        if (dfd == -1 || fstat(dfd, &instpbuf) < 0) {
                pam_syslog(idata->pamh, LOG_ERR,
@@ -1259,7 +1259,7 @@ static int create_polydir(struct polydir_s *polyptr,
     }
 #endif
 
-    rc = protect_dir(dir, mode, 1, idata->flags & PAMNS_MOUNT_PRIVATE, idata);
+    rc = protect_dir(dir, mode, 1, idata);
     if (rc == -1) {
             pam_syslog(idata->pamh, LOG_ERR,
                        "Error creating directory %s: %m", dir);
@@ -1447,7 +1447,7 @@ static int ns_setup(struct polydir_s *polyptr,
         pam_syslog(idata->pamh, LOG_DEBUG,
                "Set namespace for directory %s", polyptr->dir);
 
-    retval = protect_dir(polyptr->dir, 0, 0, idata->flags & PAMNS_MOUNT_PRIVATE, idata);
+    retval = protect_dir(polyptr->dir, 0, 0, idata);
 
     if (retval < 0 && errno != ENOENT) {
        pam_syslog(idata->pamh, LOG_ERR, "Polydir %s access error: %m",
@@ -1534,22 +1534,6 @@ static int ns_setup(struct polydir_s *polyptr,
         goto error_out;
     }
 
-    if (idata->flags & PAMNS_MOUNT_PRIVATE) {
-        /*
-         * Make the polyinstantiated dir private mount. This depends
-         * on making the dir a mount point in the protect_dir call.
-         */
-        if (mount(polyptr->dir, polyptr->dir, NULL, MS_PRIVATE|MS_REC, NULL) < 0) {
-            pam_syslog(idata->pamh, LOG_ERR, "Error making %s a private mount, %m",
-                       polyptr->dir);
-            goto error_out;
-        }
-        if (idata->flags & PAMNS_DEBUG)
-            pam_syslog(idata->pamh, LOG_DEBUG,
-                      "Polyinstantiated directory %s made as private mount", polyptr->dir);
-
-    }
-
     /*
      * Bind mount instance directory on top of the polyinstantiated
      * directory to provide an instance of polyinstantiated directory
@@ -1720,6 +1704,20 @@ static int setup_namespace(struct instance_data *idata, enum unmnt_op unmnt)
                "Unable to unshare from parent namespace, %m");
             return PAM_SESSION_ERR;
         }
+       if (idata->flags & PAMNS_MOUNT_PRIVATE) {
+           /*
+            * Remount / as SLAVE so that nothing mounted in the namespace
+            * shows up in the parent
+            */
+           if (mount("/", "/", NULL, MS_SLAVE | MS_REC , NULL) < 0) {
+               pam_syslog(idata->pamh, LOG_ERR,
+                       "Failed to mark / as a slave mount point, %m");
+               return PAM_SESSION_ERR;
+           }
+           if (idata->flags & PAMNS_DEBUG)
+               pam_syslog(idata->pamh, LOG_DEBUG,
+                       "The / mount point was marked as slave");
+       }
     } else {
        del_polydir_list(idata->polydirs_ptr);
         return PAM_SUCCESS;