|
|
a46dbe |
diff --git a/modules/pam_namespace/namespace.conf.5.xml b/modules/pam_namespace/namespace.conf.5.xml
|
|
|
a46dbe |
index c7698cb..a94b49e 100644
|
|
|
a46dbe |
--- a/modules/pam_namespace/namespace.conf.5.xml
|
|
|
a46dbe |
+++ b/modules/pam_namespace/namespace.conf.5.xml
|
|
|
a46dbe |
@@ -122,9 +122,14 @@
|
|
|
a46dbe |
<para><emphasis>mntopts</emphasis>=<replaceable>value</replaceable>
|
|
|
a46dbe |
- value of this flag is passed to the mount call when the tmpfs mount is
|
|
|
a46dbe |
done. It allows for example the specification of the maximum size of the
|
|
|
a46dbe |
- tmpfs instance that is created by the mount call. See <citerefentry>
|
|
|
a46dbe |
- <refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum>
|
|
|
a46dbe |
- </citerefentry> for details.
|
|
|
a46dbe |
+ tmpfs instance that is created by the mount call. In addition to
|
|
|
a46dbe |
+ options specified in the <citerefentry>
|
|
|
a46dbe |
+ <refentrytitle>tmpfs</refentrytitle><manvolnum>5</manvolnum>
|
|
|
a46dbe |
+ </citerefentry> manual the <emphasis>nosuid</emphasis>,
|
|
|
a46dbe |
+ <emphasis>noexec</emphasis>, and <emphasis>nodev</emphasis> flags
|
|
|
a46dbe |
+ can be used to respectively disable setuid bit effect, disable running
|
|
|
a46dbe |
+ executables, and disable devices to be interpreted on the mounted
|
|
|
a46dbe |
+ tmpfs filesystem.
|
|
|
a46dbe |
</para>
|
|
|
a46dbe |
|
|
|
a46dbe |
<para>
|
|
|
a46dbe |
diff --git a/modules/pam_namespace/pam_namespace.c b/modules/pam_namespace/pam_namespace.c
|
|
|
a46dbe |
index f541f89..660c7a1 100644
|
|
|
a46dbe |
--- a/modules/pam_namespace/pam_namespace.c
|
|
|
a46dbe |
+++ b/modules/pam_namespace/pam_namespace.c
|
|
|
a46dbe |
@@ -230,6 +230,73 @@ static int parse_iscript_params(char *params, struct polydir_s *poly)
|
|
|
a46dbe |
return 0;
|
|
|
a46dbe |
}
|
|
|
a46dbe |
|
|
|
a46dbe |
+struct mntflag {
|
|
|
a46dbe |
+ const char *name;
|
|
|
a46dbe |
+ size_t len;
|
|
|
a46dbe |
+ unsigned long flag;
|
|
|
a46dbe |
+};
|
|
|
a46dbe |
+
|
|
|
a46dbe |
+#define LITERAL_AND_LEN(x) x, sizeof(x) - 1
|
|
|
a46dbe |
+
|
|
|
a46dbe |
+static const struct mntflag mntflags[] = {
|
|
|
a46dbe |
+ { LITERAL_AND_LEN("noexec"), MS_NOEXEC },
|
|
|
a46dbe |
+ { LITERAL_AND_LEN("nosuid"), MS_NOSUID },
|
|
|
a46dbe |
+ { LITERAL_AND_LEN("nodev"), MS_NODEV }
|
|
|
a46dbe |
+ };
|
|
|
a46dbe |
+
|
|
|
a46dbe |
+static int filter_mntopts(const char *opts, char **filtered,
|
|
|
a46dbe |
+ unsigned long *mountflags)
|
|
|
a46dbe |
+{
|
|
|
a46dbe |
+ size_t origlen = strlen(opts);
|
|
|
a46dbe |
+ const char *end;
|
|
|
a46dbe |
+ char *dest;
|
|
|
a46dbe |
+
|
|
|
a46dbe |
+ dest = *filtered = NULL;
|
|
|
a46dbe |
+ *mountflags = 0;
|
|
|
a46dbe |
+
|
|
|
a46dbe |
+ if (origlen == 0)
|
|
|
a46dbe |
+ return 0;
|
|
|
a46dbe |
+
|
|
|
a46dbe |
+ do {
|
|
|
a46dbe |
+ size_t len;
|
|
|
a46dbe |
+ int i;
|
|
|
a46dbe |
+
|
|
|
a46dbe |
+ end = strchr(opts, ',');
|
|
|
a46dbe |
+ if (end == NULL) {
|
|
|
a46dbe |
+ len = strlen(opts);
|
|
|
a46dbe |
+ } else {
|
|
|
a46dbe |
+ len = end - opts;
|
|
|
a46dbe |
+ }
|
|
|
a46dbe |
+
|
|
|
a46dbe |
+ for (i = 0; i < (int)(sizeof(mntflags)/sizeof(mntflags[0])); i++) {
|
|
|
a46dbe |
+ if (mntflags[i].len != len)
|
|
|
a46dbe |
+ continue;
|
|
|
a46dbe |
+ if (memcmp(mntflags[i].name, opts, len) == 0) {
|
|
|
a46dbe |
+ *mountflags |= mntflags[i].flag;
|
|
|
a46dbe |
+ opts = end;
|
|
|
a46dbe |
+ break;
|
|
|
a46dbe |
+ }
|
|
|
a46dbe |
+ }
|
|
|
a46dbe |
+
|
|
|
a46dbe |
+ if (opts != end) {
|
|
|
a46dbe |
+ if (dest != NULL) {
|
|
|
a46dbe |
+ *dest = ',';
|
|
|
a46dbe |
+ ++dest;
|
|
|
a46dbe |
+ } else {
|
|
|
a46dbe |
+ dest = *filtered = calloc(1, origlen + 1);
|
|
|
a46dbe |
+ if (dest == NULL)
|
|
|
a46dbe |
+ return -1;
|
|
|
a46dbe |
+ }
|
|
|
a46dbe |
+ memcpy(dest, opts, len);
|
|
|
a46dbe |
+ dest += len;
|
|
|
a46dbe |
+ }
|
|
|
a46dbe |
+
|
|
|
a46dbe |
+ opts = end + 1;
|
|
|
a46dbe |
+ } while (end != NULL);
|
|
|
a46dbe |
+
|
|
|
a46dbe |
+ return 0;
|
|
|
a46dbe |
+}
|
|
|
a46dbe |
+
|
|
|
a46dbe |
static int parse_method(char *method, struct polydir_s *poly,
|
|
|
a46dbe |
struct instance_data *idata)
|
|
|
a46dbe |
{
|
|
|
a46dbe |
@@ -289,7 +356,8 @@ static int parse_method(char *method, struct polydir_s *poly,
|
|
|
a46dbe |
break;
|
|
|
a46dbe |
}
|
|
|
a46dbe |
free(poly->mount_opts); /* if duplicate mntopts specified */
|
|
|
a46dbe |
- if ((poly->mount_opts = strdup(flag+namelen+1)) == NULL) {
|
|
|
a46dbe |
+ poly->mount_opts = NULL;
|
|
|
a46dbe |
+ if (filter_mntopts(flag+namelen+1, &poly->mount_opts, &poly->mount_flags) != 0) {
|
|
|
a46dbe |
pam_syslog(idata->pamh, LOG_CRIT, "Memory allocation error");
|
|
|
a46dbe |
return -1;
|
|
|
a46dbe |
}
|
|
|
a46dbe |
@@ -1484,7 +1552,7 @@ static int ns_setup(struct polydir_s *polyptr,
|
|
|
a46dbe |
}
|
|
|
a46dbe |
|
|
|
a46dbe |
if (polyptr->method == TMPFS) {
|
|
|
a46dbe |
- if (mount("tmpfs", polyptr->dir, "tmpfs", 0, polyptr->mount_opts) < 0) {
|
|
|
a46dbe |
+ if (mount("tmpfs", polyptr->dir, "tmpfs", polyptr->mount_flags, polyptr->mount_opts) < 0) {
|
|
|
a46dbe |
pam_syslog(idata->pamh, LOG_ERR, "Error mounting tmpfs on %s, %m",
|
|
|
a46dbe |
polyptr->dir);
|
|
|
a46dbe |
return PAM_SESSION_ERR;
|
|
|
a46dbe |
diff --git a/modules/pam_namespace/pam_namespace.h b/modules/pam_namespace/pam_namespace.h
|
|
|
a46dbe |
index 47ebcc3..1522386 100644
|
|
|
a46dbe |
--- a/modules/pam_namespace/pam_namespace.h
|
|
|
a46dbe |
+++ b/modules/pam_namespace/pam_namespace.h
|
|
|
a46dbe |
@@ -166,6 +166,7 @@ struct polydir_s {
|
|
|
a46dbe |
unsigned int flags; /* polydir flags */
|
|
|
a46dbe |
char *init_script; /* path to init script */
|
|
|
a46dbe |
char *mount_opts; /* mount options for tmpfs mount */
|
|
|
a46dbe |
+ unsigned long mount_flags; /* mount flags for tmpfs mount */
|
|
|
a46dbe |
uid_t owner; /* user which should own the polydir */
|
|
|
a46dbe |
gid_t group; /* group which should own the polydir */
|
|
|
a46dbe |
mode_t mode; /* mode of the polydir */
|