detect the shared / and make the polydir mounts private based on that
fix memory leak and other small errors in pam_namespace
This commit is contained in:
parent
6a48d1491e
commit
d31d5587d4
@ -1,44 +1,44 @@
|
|||||||
diff --git a/modules/pam_namespace/pam_namespace.8.xml b/modules/pam_namespace/pam_namespace.8.xml
|
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
|
||||||
index 0433f0f..f0ebe2c 100644
|
--- Linux-PAM-1.1.3/modules/pam_namespace/pam_namespace.c.private 2010-10-22 09:41:09.000000000 +0200
|
||||||
--- a/modules/pam_namespace/pam_namespace.8.xml
|
+++ Linux-PAM-1.1.3/modules/pam_namespace/pam_namespace.c 2011-06-07 17:28:04.000000000 +0200
|
||||||
+++ b/modules/pam_namespace/pam_namespace.8.xml
|
@@ -61,9 +61,11 @@ static void add_polydir_entry(struct ins
|
||||||
@@ -52,6 +52,9 @@
|
|
||||||
<arg choice="opt">
|
|
||||||
use_default_context
|
|
||||||
</arg>
|
|
||||||
+ <arg choice="opt">
|
|
||||||
+ mount_private
|
|
||||||
+ </arg>
|
|
||||||
</cmdsynopsis>
|
|
||||||
</refsynopsisdiv>
|
|
||||||
|
|
||||||
@@ -234,6 +237,21 @@
|
static void del_polydir(struct polydir_s *poly)
|
||||||
</listitem>
|
{
|
||||||
</varlistentry>
|
- free(poly->uid);
|
||||||
|
- free(poly->init_script);
|
||||||
|
- free(poly);
|
||||||
|
+ if (poly) {
|
||||||
|
+ free(poly->uid);
|
||||||
|
+ free(poly->init_script);
|
||||||
|
+ free(poly);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
+ <varlistentry>
|
/*
|
||||||
+ <term>
|
@@ -307,10 +309,6 @@ static int process_line(char *line, cons
|
||||||
+ <option>mount_private</option>
|
const char *rvar_values[] = {rhome, idata->ruser};
|
||||||
+ </term>
|
int len;
|
||||||
+ <listitem>
|
|
||||||
+ <para>
|
- poly = calloc(1, sizeof(*poly));
|
||||||
+ This option should be used on systems where the / mount point and
|
- if (poly == NULL)
|
||||||
+ its submounts are made shared (for example with a
|
- goto erralloc;
|
||||||
+ <command>mount --make-rshared /</command> command).
|
-
|
||||||
+ The module will make the polyinstantiated directory mount points
|
/*
|
||||||
+ private.
|
* skip the leading white space
|
||||||
+ </para>
|
*/
|
||||||
+ </listitem>
|
@@ -337,6 +335,10 @@ static int process_line(char *line, cons
|
||||||
+ </varlistentry>
|
if (line[0] == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
+ poly = calloc(1, sizeof(*poly));
|
||||||
|
+ if (poly == NULL)
|
||||||
|
+ goto erralloc;
|
||||||
+
|
+
|
||||||
</variablelist>
|
/*
|
||||||
</refsect1>
|
* Initialize and scan the five strings from the line from the
|
||||||
|
* namespace configuration file.
|
||||||
diff --git a/modules/pam_namespace/pam_namespace.c b/modules/pam_namespace/pam_namespace.c
|
@@ -1001,7 +1003,7 @@ static int protect_mount(int dfd, const
|
||||||
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ index c47599e..d5a2d78 100644
|
|||||||
struct instance_data *idata)
|
struct instance_data *idata)
|
||||||
{
|
{
|
||||||
char *p = strdup(path);
|
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 */
|
/* we are inside user-owned dir - protect */
|
||||||
if (protect_mount(rv, p, idata) == -1) {
|
if (protect_mount(rv, p, idata) == -1) {
|
||||||
save_errno = errno;
|
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)
|
if (trailing_slash)
|
||||||
*trailing_slash = '\0';
|
*trailing_slash = '\0';
|
||||||
|
|
||||||
@ -65,7 +74,7 @@ index c47599e..d5a2d78 100644
|
|||||||
|
|
||||||
if (dfd == -1 || fstat(dfd, &instpbuf) < 0) {
|
if (dfd == -1 || fstat(dfd, &instpbuf) < 0) {
|
||||||
pam_syslog(idata->pamh, LOG_ERR,
|
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
|
#endif
|
||||||
|
|
||||||
@ -74,7 +83,7 @@ index c47599e..d5a2d78 100644
|
|||||||
if (rc == -1) {
|
if (rc == -1) {
|
||||||
pam_syslog(idata->pamh, LOG_ERR,
|
pam_syslog(idata->pamh, LOG_ERR,
|
||||||
"Error creating directory %s: %m", dir);
|
"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,
|
pam_syslog(idata->pamh, LOG_DEBUG,
|
||||||
"Set namespace for directory %s", polyptr->dir);
|
"Set namespace for directory %s", polyptr->dir);
|
||||||
|
|
||||||
@ -83,7 +92,19 @@ index c47599e..d5a2d78 100644
|
|||||||
|
|
||||||
if (retval < 0 && errno != ENOENT) {
|
if (retval < 0 && errno != ENOENT) {
|
||||||
pam_syslog(idata->pamh, LOG_ERR, "Polydir %s access error: %m",
|
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;
|
goto error_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,7 +127,61 @@ index c47599e..d5a2d78 100644
|
|||||||
/*
|
/*
|
||||||
* Bind mount instance directory on top of the polyinstantiated
|
* Bind mount instance directory on top of the polyinstantiated
|
||||||
* directory to provide an instance of polyinstantiated directory
|
* 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_USE_DEFAULT_CONTEXT;
|
||||||
idata.flags |= PAMNS_CTXT_BASED_INST;
|
idata.flags |= PAMNS_CTXT_BASED_INST;
|
||||||
}
|
}
|
||||||
@ -116,11 +191,43 @@ index c47599e..d5a2d78 100644
|
|||||||
if (strcmp(argv[i], "unmnt_remnt") == 0)
|
if (strcmp(argv[i], "unmnt_remnt") == 0)
|
||||||
unmnt = UNMNT_REMNT;
|
unmnt = UNMNT_REMNT;
|
||||||
if (strcmp(argv[i], "unmnt_only") == 0)
|
if (strcmp(argv[i], "unmnt_only") == 0)
|
||||||
diff --git a/modules/pam_namespace/pam_namespace.h b/modules/pam_namespace/pam_namespace.h
|
unmnt = UNMNT_ONLY;
|
||||||
index da21bd7..7b39068 100644
|
if (strcmp(argv[i], "require_selinux") == 0) {
|
||||||
--- a/modules/pam_namespace/pam_namespace.h
|
- if (~(idata.flags & PAMNS_SELINUX_ENABLED)) {
|
||||||
+++ b/modules/pam_namespace/pam_namespace.h
|
+ if (!(idata.flags & PAMNS_SELINUX_ENABLED)) {
|
||||||
@@ -96,6 +96,7 @@
|
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_NO_UNMOUNT_ON_CLOSE 0x00010000 /* no unmount at session close */
|
||||||
#define PAMNS_USE_CURRENT_CONTEXT 0x00020000 /* use getcon instead of getexeccon */
|
#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_USE_DEFAULT_CONTEXT 0x00040000 /* use get_default_context instead of getexeccon */
|
||||||
@ -128,3 +235,41 @@ index da21bd7..7b39068 100644
|
|||||||
|
|
||||||
/* polydir flags */
|
/* polydir flags */
|
||||||
#define POLYDIR_EXCLUSIVE 0x00000001 /* polyinstatiate exclusively for override uids */
|
#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>
|
||||||
|
|
||||||
|
6
pam.spec
6
pam.spec
@ -3,7 +3,7 @@
|
|||||||
Summary: An extensible library which provides authentication for applications
|
Summary: An extensible library which provides authentication for applications
|
||||||
Name: pam
|
Name: pam
|
||||||
Version: 1.1.3
|
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
|
# 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+,
|
# as the BSD license allows that anyway. pam_timestamp and pam_console modules are GPLv2+,
|
||||||
License: BSD and GPLv2+
|
License: BSD and GPLv2+
|
||||||
@ -369,6 +369,10 @@ fi
|
|||||||
%doc doc/adg/*.txt doc/adg/html
|
%doc doc/adg/*.txt doc/adg/html
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Jun 7 2011 Tomas Mraz <tmraz@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@redhat.com> 1.1.3-9
|
* Thu Jun 2 2011 Tomas Mraz <tmraz@redhat.com> 1.1.3-9
|
||||||
- add support for explicit marking of the polydir mount private (#623522)
|
- add support for explicit marking of the polydir mount private (#623522)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user