diff --git a/pam-1.1.3-namespace-private.patch b/pam-1.1.3-namespace-private.patch new file mode 100644 index 0000000..892a2a4 --- /dev/null +++ b/pam-1.1.3-namespace-private.patch @@ -0,0 +1,130 @@ +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 ++ + + + +@@ -234,6 +237,21 @@ + + + ++ ++ ++ ++ ++ ++ ++ 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. ++ ++ ++ ++ + + + +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) + return 0; + } + +-static int protect_dir(const char *path, mode_t mode, int do_mkdir, ++static int protect_dir(const char *path, mode_t mode, int do_mkdir, int always, + 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, + } + } + +- if (flags & O_NOFOLLOW) { ++ if ((flags & O_NOFOLLOW) || always) { + /* 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, idata); ++ dfd = protect_dir(inst_parent, 0, 1, 0, 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); ++ rc = protect_dir(dir, mode, 1, idata->flags & PAMNS_MOUNT_PRIVATE, 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); ++ retval = protect_dir(polyptr->dir, 0, 0, idata->flags & PAMNS_MOUNT_PRIVATE, idata); + + 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, + 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 +@@ -1964,6 +1980,9 @@ PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags UNUSED, + idata.flags |= PAMNS_USE_DEFAULT_CONTEXT; + idata.flags |= PAMNS_CTXT_BASED_INST; + } ++ if (strcmp(argv[i], "mount_private") == 0) { ++ idata.flags |= PAMNS_MOUNT_PRIVATE; ++ } + 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 @@ + #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 */ ++#define PAMNS_MOUNT_PRIVATE 0x00080000 /* Make the polydir mounts private */ + + /* polydir flags */ + #define POLYDIR_EXCLUSIVE 0x00000001 /* polyinstatiate exclusively for override uids */ diff --git a/pam.spec b/pam.spec index 233be15..5213d49 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: 8%{?dist} +Release: 9%{?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+ @@ -39,6 +39,7 @@ Patch30: pam-1.1.3-securetty-console.patch Patch31: pam-1.1.3-limits-nosetreuid.patch Patch32: pam-1.1.3-limits-range.patch Patch33: pam-1.1.3-pwhistory-incomplete.patch +Patch34: pam-1.1.3-namespace-private.patch %define _sbindir /sbin %define _moduledir /%{_lib}/security @@ -113,6 +114,7 @@ mv pam-redhat-%{pam_redhat_version}/* modules %patch31 -p1 -b .nosetreuid %patch32 -p0 -b .range %patch33 -p1 -b .incomplete +%patch34 -p1 -b .private libtoolize -f autoreconf @@ -367,6 +369,9 @@ fi %doc doc/adg/*.txt doc/adg/html %changelog +* Thu Jun 2 2011 Tomas Mraz 1.1.3-9 +- add support for explicit marking of the polydir mount private (#623522) + * Tue Feb 08 2011 Fedora Release Engineering - 1.1.3-8 - Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild