[pam] detect the shared / and make the polydir mounts private based on that fix memory leak and other smal

Tomáš Mráz tmraz at fedoraproject.org
Tue Jun 7 15:31:28 UTC 2011


commit d31d5587d430eb293dcde62a135f14a005157b78
Author: Tomas Mraz <tmraz at fedoraproject.org>
Date:   Tue Jun 7 17:31:12 2011 +0200

    detect the shared / and make the polydir mounts private based on that
    fix memory leak and other small errors in pam_namespace

 pam-1.1.3-namespace-private.patch |  243 +++++++++++++++++++++++++++++--------
 pam.spec                          |    6 +-
 2 files changed, 199 insertions(+), 50 deletions(-)
---
diff --git a/pam-1.1.3-namespace-private.patch b/pam-1.1.3-namespace-private.patch
index 892a2a4..9ed1678 100644
--- a/pam-1.1.3-namespace-private.patch
+++ b/pam-1.1.3-namespace-private.patch
@@ -1,44 +1,44 @@
-diff --git a/modules/pam_namespace/pam_namespace.8.xml b/modules/pam_namespace/pam_namespace.8.xml
-index 0433f0f..f0ebe2c 100644
---- a/modules/pam_namespace/pam_namespace.8.xml
-+++ b/modules/pam_namespace/pam_namespace.8.xml
-@@ -52,6 +52,9 @@
-       <arg choice="opt">
-         use_default_context
-       </arg>
-+      <arg choice="opt">
-+        mount_private
-+      </arg>
-     </cmdsynopsis>
-   </refsynopsisdiv>
+diff -up Linux-PAM-1.1.3/modules/pam_namespace/pam_namespace.c.private Linux-PAM-1.1.3/modules/pam_namespace/pam_namespace.c
+--- Linux-PAM-1.1.3/modules/pam_namespace/pam_namespace.c.private	2010-10-22 09:41:09.000000000 +0200
++++ Linux-PAM-1.1.3/modules/pam_namespace/pam_namespace.c	2011-06-07 17:28:04.000000000 +0200
+@@ -61,9 +61,11 @@ static void add_polydir_entry(struct ins
  
-@@ -234,6 +237,21 @@
-         </listitem>
-       </varlistentry>
+ static void del_polydir(struct polydir_s *poly)
+ {
+-	free(poly->uid);
+-	free(poly->init_script);
+-	free(poly);
++	if (poly) {
++		free(poly->uid);
++		free(poly->init_script);
++		free(poly);
++	}
+ }
  
-+      <varlistentry>
-+        <term>
-+          <option>mount_private</option>
-+        </term>
-+        <listitem>
-+          <para>
-+	    This option should be used on systems where the / mount point and
-+	    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.
-+          </para>
-+        </listitem>
-+      </varlistentry>
-+
-     </variablelist>
-   </refsect1>
+ /*
+@@ -307,10 +309,6 @@ static int process_line(char *line, cons
+     const char *rvar_values[] = {rhome, idata->ruser};
+     int len;
  
-diff --git a/modules/pam_namespace/pam_namespace.c b/modules/pam_namespace/pam_namespace.c
-index c47599e..d5a2d78 100644
---- a/modules/pam_namespace/pam_namespace.c
-+++ b/modules/pam_namespace/pam_namespace.c
-@@ -1003,7 +1003,7 @@ static int protect_mount(int dfd, const char *path, struct instance_data *idata)
+-    poly = calloc(1, sizeof(*poly));
+-    if (poly == NULL)
+-    	goto erralloc;
+-
+     /*
+      * skip the leading white space
+      */
+@@ -337,6 +335,10 @@ static int process_line(char *line, cons
+     if (line[0] == 0)
+         return 0;
+ 
++    poly = calloc(1, sizeof(*poly));
++    if (poly == NULL)
++    	goto erralloc;
++
+     /*
+      * Initialize and scan the five strings from the line from the
+      * namespace configuration file.
+@@ -1001,7 +1003,7 @@ static int protect_mount(int dfd, const 
  	return 0;
  }
  
@@ -47,7 +47,7 @@ index c47599e..d5a2d78 100644
  	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,
+@@ -1080,7 +1082,7 @@ static int protect_dir(const char *path,
  		}
  	}
  
@@ -56,7 +56,16 @@ index c47599e..d5a2d78 100644
  		/* 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)
+@@ -1093,7 +1095,7 @@ static int protect_dir(const char *path,
+ error:
+ 	save_errno = errno;
+ 	free(p);
+-	if (dfd != AT_FDCWD)
++	if (dfd != AT_FDCWD && dfd >= 0)
+ 		close(dfd);
+ 	errno = save_errno;
+ 
+@@ -1122,7 +1124,7 @@ static int check_inst_parent(char *ipath
  	if (trailing_slash)
  		*trailing_slash = '\0';
  
@@ -65,7 +74,7 @@ index c47599e..d5a2d78 100644
  
  	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,
+@@ -1257,7 +1259,7 @@ static int create_polydir(struct polydir
      }
  #endif
  
@@ -74,7 +83,7 @@ index c47599e..d5a2d78 100644
      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,
+@@ -1445,7 +1447,7 @@ static int ns_setup(struct polydir_s *po
          pam_syslog(idata->pamh, LOG_DEBUG,
                 "Set namespace for directory %s", polyptr->dir);
  
@@ -83,7 +92,19 @@ index c47599e..d5a2d78 100644
  
      if (retval < 0 && errno != ENOENT) {
  	pam_syslog(idata->pamh, LOG_ERR, "Polydir %s access error: %m",
-@@ -1534,6 +1534,22 @@ static int ns_setup(struct polydir_s *polyptr,
+@@ -1453,8 +1455,9 @@ static int ns_setup(struct polydir_s *po
+ 	return PAM_SESSION_ERR;    
+     }
+ 
+-    if (retval < 0 && (polyptr->flags & POLYDIR_CREATE)) {
+-	if (create_polydir(polyptr, idata) != PAM_SUCCESS)
++    if (retval < 0) {
++ 	if ((polyptr->flags & POLYDIR_CREATE) &&
++		create_polydir(polyptr, idata) != PAM_SUCCESS)
+ 		return PAM_SESSION_ERR;
+     } else {
+     	close(retval);
+@@ -1531,6 +1534,22 @@ static int ns_setup(struct polydir_s *po
          goto error_out;
      }
  
@@ -106,7 +127,61 @@ index c47599e..d5a2d78 100644
      /*
       * Bind mount instance directory on top of the polyinstantiated
       * directory to provide an instance of polyinstantiated directory
-@@ -1964,6 +1980,9 @@ PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags UNUSED,
+@@ -1871,6 +1890,53 @@ static int ctxt_based_inst_needed(void)
+ }
+ #endif
+ 
++static int root_shared(void)
++{
++    FILE *f;
++    char *line = NULL;
++    size_t n = 0;
++    int rv = 0;
++
++    f = fopen("/proc/self/mountinfo", "r");
++
++    if (f == NULL)
++        return 0;
++
++    while(getline(&line, &n, f) != -1) {
++        char *l;
++        char *sptr;
++        int i;
++
++        l = line;
++        sptr = NULL;
++        for (i = 0; i < 7; i++) {
++             char *tok;
++
++             tok = strtok_r(l, " ", &sptr);
++             l = NULL;
++             if (tok == NULL)
++                 /* next mountinfo line */
++                 break;
++
++             if (i == 4 && strcmp(tok, "/") != 0)
++                 /* next mountinfo line */
++                 break;
++
++             if (i == 6) {
++                if (strncmp(tok, "shared:", 7) == 0)
++                 /* there might be more / mounts, the last one counts */
++                    rv = 1;
++                else
++                    rv = 0;
++             }
++        }
++    }
++
++    free(line);
++    fclose(f);
++
++    return rv;
++}
+ 
+ static int get_user_data(struct instance_data *idata)
+ {
+@@ -1961,12 +2027,15 @@ PAM_EXTERN int pam_sm_open_session(pam_h
              idata.flags |= PAMNS_USE_DEFAULT_CONTEXT;
              idata.flags |= PAMNS_CTXT_BASED_INST;
          }
@@ -116,11 +191,43 @@ index c47599e..d5a2d78 100644
          if (strcmp(argv[i], "unmnt_remnt") == 0)
              unmnt = UNMNT_REMNT;
          if (strcmp(argv[i], "unmnt_only") == 0)
-diff --git a/modules/pam_namespace/pam_namespace.h b/modules/pam_namespace/pam_namespace.h
-index da21bd7..7b39068 100644
---- a/modules/pam_namespace/pam_namespace.h
-+++ b/modules/pam_namespace/pam_namespace.h
-@@ -96,6 +96,7 @@
+             unmnt = UNMNT_ONLY;
+ 	if (strcmp(argv[i], "require_selinux") == 0) {
+-		if (~(idata.flags & PAMNS_SELINUX_ENABLED)) {
++		if (!(idata.flags & PAMNS_SELINUX_ENABLED)) {
+         		pam_syslog(idata.pamh, LOG_ERR,
+ 		    "selinux_required option given and selinux is disabled");
+ 			return PAM_SESSION_ERR;
+@@ -1980,6 +2049,10 @@ PAM_EXTERN int pam_sm_open_session(pam_h
+     if (retval != PAM_SUCCESS)
+     	return retval;
+ 
++    if (root_shared()) {
++	idata.flags |= PAMNS_MOUNT_PRIVATE;
++    }
++
+     /*
+      * Parse namespace configuration file which lists directories to
+      * polyinstantiate, directory where instance directories are to
+diff -up Linux-PAM-1.1.3/modules/pam_namespace/pam_namespace.h.private Linux-PAM-1.1.3/modules/pam_namespace/pam_namespace.h
+--- Linux-PAM-1.1.3/modules/pam_namespace/pam_namespace.h.private	2008-04-18 14:53:38.000000000 +0200
++++ Linux-PAM-1.1.3/modules/pam_namespace/pam_namespace.h	2011-06-07 17:26:25.000000000 +0200
+@@ -74,6 +74,14 @@
+ #define CLONE_NEWNS 0x00020000 /* Flag to create new namespace */
+ #endif
+ 
++/* mount flags for mount_private */
++#ifndef MS_REC
++#define MS_REC (1<<14)
++#endif
++#ifndef MS_PRIVATE
++#define MS_PRIVATE (1<<18)
++#endif
++
+ /*
+  * Module defines
+  */
+@@ -96,6 +104,7 @@
  #define PAMNS_NO_UNMOUNT_ON_CLOSE  0x00010000 /* no unmount at session close */
  #define PAMNS_USE_CURRENT_CONTEXT  0x00020000 /* use getcon instead of getexeccon */
  #define PAMNS_USE_DEFAULT_CONTEXT  0x00040000 /* use get_default_context instead of getexeccon */
@@ -128,3 +235,41 @@ index da21bd7..7b39068 100644
  
  /* polydir flags */
  #define POLYDIR_EXCLUSIVE     0x00000001 /* polyinstatiate exclusively for override uids */
+diff -up Linux-PAM-1.1.3/modules/pam_namespace/pam_namespace.8.xml.private Linux-PAM-1.1.3/modules/pam_namespace/pam_namespace.8.xml
+--- Linux-PAM-1.1.3/modules/pam_namespace/pam_namespace.8.xml.private	2009-06-01 09:03:20.000000000 +0200
++++ Linux-PAM-1.1.3/modules/pam_namespace/pam_namespace.8.xml	2011-06-07 17:26:12.000000000 +0200
+@@ -52,6 +52,9 @@
+       <arg choice="opt">
+         use_default_context
+       </arg>
++      <arg choice="opt">
++        mount_private
++      </arg>
+     </cmdsynopsis>
+   </refsynopsisdiv>
+ 
+@@ -234,6 +237,24 @@
+         </listitem>
+       </varlistentry>
+ 
++      <varlistentry>
++        <term>
++          <option>mount_private</option>
++        </term>
++        <listitem>
++          <para>
++	    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
++	    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>
++        </listitem>
++      </varlistentry>
++
+     </variablelist>
+   </refsect1>
+ 
diff --git a/pam.spec b/pam.spec
index 5213d49..2ed2203 100644
--- a/pam.spec
+++ b/pam.spec
@@ -3,7 +3,7 @@
 Summary: An extensible library which provides authentication for applications
 Name: pam
 Version: 1.1.3
-Release: 9%{?dist}
+Release: 10%{?dist}
 # The library is BSD licensed with option to relicense as GPLv2+ - this option is redundant
 # as the BSD license allows that anyway. pam_timestamp and pam_console modules are GPLv2+,
 License: BSD and GPLv2+
@@ -369,6 +369,10 @@ fi
 %doc doc/adg/*.txt doc/adg/html
 
 %changelog
+* Tue Jun  7 2011 Tomas Mraz <tmraz at redhat.com> 1.1.3-10
+- detect the shared / and make the polydir mounts private based on that
+- fix memory leak and other small errors in pam_namespace
+
 * Thu Jun  2 2011 Tomas Mraz <tmraz at redhat.com> 1.1.3-9
 - add support for explicit marking of the polydir mount private (#623522)
 


More information about the scm-commits mailing list