Blame SPECS/pam-1.3.1-namespace-mntopts.patch

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