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 @@ - - use_default_context - -+ -+ mount_private -+ - - +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 @@ - - + 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); ++ } + } -+ -+ -+ -+ -+ -+ -+ This option should be used on systems where the / mount point and -+ its submounts are made shared (for example with a -+ mount --make-rshared / command). -+ The module will make the polyinstantiated directory mount points -+ private. -+ -+ -+ + /* +@@ -307,10 +309,6 @@ static int process_line(char *line, cons + const char *rvar_values[] = {rhome, idata->ruser}; + int len; + +- 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; + - - - -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) + /* + * 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 @@ + + use_default_context + ++ ++ mount_private ++ + + + +@@ -234,6 +237,24 @@ + + + ++ ++ ++ ++ ++ ++ ++ This option can be used on systems where the / mount point or ++ its submounts are made shared (for example with a ++ mount --make-rshared / 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. ++ ++ ++ ++ + + + 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 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 1.1.3-9 - add support for explicit marking of the polydir mount private (#623522)