[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