Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 20 Mar 2018 23:08:42 +0000 (UTC)
From:      Jamie Gritton <jamie@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r331278 - head/sys/kern
Message-ID:  <201803202308.w2KN8gYe019890@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jamie
Date: Tue Mar 20 23:08:42 2018
New Revision: 331278
URL: https://svnweb.freebsd.org/changeset/base/331278

Log:
  Represent boolean jail options as an array of structures containing the
  flag and both the regular and "no" names, instead of two different string
  arrays whose indices need to match the flag's bit position.  This makes
  them similar to the say "jailsys" options are represented.
  
  Loop through either kind of option array with a structure pointer rather
  then an integer index.

Modified:
  head/sys/kern/kern_jail.c

Modified: head/sys/kern/kern_jail.c
==============================================================================
--- head/sys/kern/kern_jail.c	Tue Mar 20 23:08:04 2018	(r331277)
+++ head/sys/kern/kern_jail.c	Tue Mar 20 23:08:42 2018	(r331278)
@@ -115,6 +115,17 @@ struct prison prison0 = {
 };
 MTX_SYSINIT(prison0, &prison0.pr_mtx, "jail mutex", MTX_DEF);
 
+struct bool_flags {
+	const char	*name;
+	const char	*noname;
+	unsigned	 flag;
+};
+struct jailsys_flags {
+	const char	*name;
+	unsigned	 disable;
+	unsigned	 new;
+};
+
 /* allprison, allprison_racct and lastprid are protected by allprison_lock. */
 struct	sx allprison_lock;
 SX_SYSINIT(allprison_lock, &allprison_lock, "allprison");
@@ -145,86 +156,55 @@ static void prison_racct_detach(struct prison *pr);
  * as we cannot figure out the size of a sparse array, or an array without a
  * terminating entry.
  */
-static char *pr_flag_names[] = {
-	[0] = "persist",
+static struct bool_flags pr_flag_bool[] = {
+	{"persist", "nopersist", PR_PERSIST},
 #ifdef INET
-	[7] = "ip4.saddrsel",
+	{"ip4.saddrsel", "ip4.nosaddrsel", PR_IP4_SADDRSEL},
 #endif
 #ifdef INET6
-	[8] = "ip6.saddrsel",
+	{"ip6.saddrsel", "ip6.nosaddrsel", PR_IP6_SADDRSEL},
 #endif
 };
-const size_t pr_flag_names_size = sizeof(pr_flag_names);
+const size_t pr_flag_bool_size = sizeof(pr_flag_bool);
 
-static char *pr_flag_nonames[] = {
-	[0] = "nopersist",
-#ifdef INET
-	[7] = "ip4.nosaddrsel",
-#endif
-#ifdef INET6
-	[8] = "ip6.nosaddrsel",
-#endif
-};
-const size_t pr_flag_nonames_size = sizeof(pr_flag_nonames);
-
-struct jailsys_flags {
-	const char	*name;
-	unsigned	 disable;
-	unsigned	 new;
-} pr_flag_jailsys[] = {
-	{ "host", 0, PR_HOST },
+static struct jailsys_flags pr_flag_jailsys[] = {
+	{"host", 0, PR_HOST},
 #ifdef VIMAGE
-	{ "vnet", 0, PR_VNET },
+	{"vnet", 0, PR_VNET},
 #endif
 #ifdef INET
-	{ "ip4", PR_IP4_USER, PR_IP4_USER },
+	{"ip4", PR_IP4_USER, PR_IP4_USER},
 #endif
 #ifdef INET6
-	{ "ip6", PR_IP6_USER, PR_IP6_USER },
+	{"ip6", PR_IP6_USER, PR_IP6_USER},
 #endif
 };
 const size_t pr_flag_jailsys_size = sizeof(pr_flag_jailsys);
 
-static char *pr_allow_names[] = {
-	"allow.set_hostname",
-	"allow.sysvipc",
-	"allow.raw_sockets",
-	"allow.chflags",
-	"allow.mount",
-	"allow.quotas",
-	"allow.socket_af",
-	"allow.mount.devfs",
-	"allow.mount.nullfs",
-	"allow.mount.zfs",
-	"allow.mount.procfs",
-	"allow.mount.tmpfs",
-	"allow.mount.fdescfs",
-	"allow.mount.linprocfs",
-	"allow.mount.linsysfs",
-	"allow.reserved_ports",
+static struct bool_flags pr_flag_allow[] = {
+	{"allow.set_hostname", "allow.noset_hostname", PR_ALLOW_SET_HOSTNAME},
+	{"allow.sysvipc", "allow.nosysvipc", PR_ALLOW_SYSVIPC},
+	{"allow.raw_sockets", "allow.noraw_sockets", PR_ALLOW_RAW_SOCKETS},
+	{"allow.chflags", "allow.nochflags", PR_ALLOW_CHFLAGS},
+	{"allow.mount", "allow.nomount", PR_ALLOW_MOUNT},
+	{"allow.quotas", "allow.noquotas", PR_ALLOW_QUOTAS},
+	{"allow.socket_af", "allow.nosocket_af", PR_ALLOW_SOCKET_AF},
+	{"allow.mount.devfs", "allow.mount.nodevfs", PR_ALLOW_MOUNT_DEVFS},
+	{"allow.mount.nullfs", "allow.mount.nonullfs", PR_ALLOW_MOUNT_NULLFS},
+	{"allow.mount.zfs", "allow.mount.nozfs", PR_ALLOW_MOUNT_ZFS},
+	{"allow.mount.procfs", "allow.mount.noprocfs", PR_ALLOW_MOUNT_PROCFS},
+	{"allow.mount.tmpfs", "allow.mount.notmpfs", PR_ALLOW_MOUNT_TMPFS},
+	{"allow.mount.fdescfs", "allow.mount.nofdescfs",
+	 PR_ALLOW_MOUNT_FDESCFS},
+	{"allow.mount.linprocfs", "allow.mount.nolinprocfs",
+	 PR_ALLOW_MOUNT_LINPROCFS},
+	{"allow.mount.linsysfs", "allow.mount.nolinsysfs",
+	 PR_ALLOW_MOUNT_LINSYSFS},
+	{"allow.reserved_ports", "allow.noreserved_ports",
+	 PR_ALLOW_RESERVED_PORTS},
 };
-const size_t pr_allow_names_size = sizeof(pr_allow_names);
+const size_t pr_flag_allow_size = sizeof(pr_flag_allow);
 
-static char *pr_allow_nonames[] = {
-	"allow.noset_hostname",
-	"allow.nosysvipc",
-	"allow.noraw_sockets",
-	"allow.nochflags",
-	"allow.nomount",
-	"allow.noquotas",
-	"allow.nosocket_af",
-	"allow.mount.nodevfs",
-	"allow.mount.nonullfs",
-	"allow.mount.nozfs",
-	"allow.mount.noprocfs",
-	"allow.mount.notmpfs",
-	"allow.mount.nofdescfs",
-	"allow.mount.nolinprocfs",
-	"allow.mount.nolinsysfs",
-	"allow.noreserved_ports",
-};
-const size_t pr_allow_nonames_size = sizeof(pr_allow_nonames);
-
 #define	JAIL_DEFAULT_ALLOW		(PR_ALLOW_SET_HOSTNAME | PR_ALLOW_RESERVED_PORTS)
 #define	JAIL_DEFAULT_ENFORCE_STATFS	2
 #define	JAIL_DEFAULT_DEVFS_RSNUM	0
@@ -305,7 +285,7 @@ sys_jail(struct thread *td, struct jail_args *uap)
 int
 kern_jail(struct thread *td, struct jail *j)
 {
-	struct iovec optiov[2 * (4 + nitems(pr_allow_names)
+	struct iovec optiov[2 * (4 + nitems(pr_flag_allow)
 #ifdef INET
 			    + 1
 #endif
@@ -315,6 +295,7 @@ kern_jail(struct thread *td, struct jail *j)
 			    )];
 	struct uio opt;
 	char *u_path, *u_hostname, *u_name;
+	struct bool_flags *bf;
 #ifdef INET
 	uint32_t ip4s;
 	struct in_addr *u_ip4;
@@ -323,7 +304,7 @@ kern_jail(struct thread *td, struct jail *j)
 	struct in6_addr *u_ip6;
 #endif
 	size_t tmplen;
-	int error, enforce_statfs, fi;
+	int error, enforce_statfs;
 
 	bzero(&optiov, sizeof(optiov));
 	opt.uio_iov = optiov;
@@ -336,10 +317,12 @@ kern_jail(struct thread *td, struct jail *j)
 
 	/* Set permissions for top-level jails from sysctls. */
 	if (!jailed(td->td_ucred)) {
-		for (fi = 0; fi < nitems(pr_allow_names); fi++) {
-			optiov[opt.uio_iovcnt].iov_base =
-			    (jail_default_allow & (1 << fi))
-			    ? pr_allow_names[fi] : pr_allow_nonames[fi];
+		for (bf = pr_flag_allow;
+		     bf < pr_flag_allow + nitems(pr_flag_allow);
+		     bf++) {
+			optiov[opt.uio_iovcnt].iov_base = __DECONST(char *,
+			    (jail_default_allow & bf->flag)
+			    ? bf->name : bf->noname);
 			optiov[opt.uio_iovcnt].iov_len =
 			    strlen(optiov[opt.uio_iovcnt].iov_base) + 1;
 			opt.uio_iovcnt += 2;
@@ -498,6 +481,8 @@ kern_jail_set(struct thread *td, struct uio *optuio, i
 	struct vnode *root;
 	char *domain, *errmsg, *host, *name, *namelc, *p, *path, *uuid;
 	char *g_path, *osrelstr;
+	struct bool_flags *bf;
+	struct jailsys_flags *jsf;
 #if defined(INET) || defined(INET6)
 	struct prison *tppr;
 	void *op;
@@ -507,7 +492,7 @@ kern_jail_set(struct thread *td, struct uio *optuio, i
 	int born, created, cuflags, descend, enforce;
 	int error, errmsg_len, errmsg_pos;
 	int gotchildmax, gotenforce, gothid, gotrsnum, gotslevel;
-	int fi, jid, jsys, len, level;
+	int jid, jsys, len, level;
 	int childmax, osreldt, rsnum, slevel;
 	int fullpath_disabled;
 #if defined(INET) || defined(INET6)
@@ -605,30 +590,31 @@ kern_jail_set(struct thread *td, struct uio *optuio, i
 		gotrsnum = 1;
 
 	pr_flags = ch_flags = 0;
-	for (fi = 0; fi < nitems(pr_flag_names); fi++) {
-		if (pr_flag_names[fi] == NULL)
-			continue;
-		vfs_flagopt(opts, pr_flag_names[fi], &pr_flags, 1 << fi);
-		vfs_flagopt(opts, pr_flag_nonames[fi], &ch_flags, 1 << fi);
+	for (bf = pr_flag_bool;
+	     bf < pr_flag_bool + nitems(pr_flag_bool);
+	     bf++) {
+		vfs_flagopt(opts, bf->name, &pr_flags, bf->flag);
+		vfs_flagopt(opts, bf->noname, &ch_flags, bf->flag);
 	}
 	ch_flags |= pr_flags;
-	for (fi = 0; fi < nitems(pr_flag_jailsys); fi++) {
-		error = vfs_copyopt(opts, pr_flag_jailsys[fi].name, &jsys,
-		    sizeof(jsys));
+	for (jsf = pr_flag_jailsys;
+	     jsf < pr_flag_jailsys + nitems(pr_flag_jailsys);
+	     jsf++) {
+		error = vfs_copyopt(opts, jsf->name, &jsys, sizeof(jsys));
 		if (error == ENOENT)
 			continue;
 		if (error != 0)
 			goto done_free;
 		switch (jsys) {
 		case JAIL_SYS_DISABLE:
-			if (!pr_flag_jailsys[fi].disable) {
+			if (!jsf->disable) {
 				error = EINVAL;
 				goto done_free;
 			}
-			pr_flags |= pr_flag_jailsys[fi].disable;
+			pr_flags |= jsf->disable;
 			break;
 		case JAIL_SYS_NEW:
-			pr_flags |= pr_flag_jailsys[fi].new;
+			pr_flags |= jsf->new;
 			break;
 		case JAIL_SYS_INHERIT:
 			break;
@@ -636,8 +622,7 @@ kern_jail_set(struct thread *td, struct uio *optuio, i
 			error = EINVAL;
 			goto done_free;
 		}
-		ch_flags |=
-		    pr_flag_jailsys[fi].new | pr_flag_jailsys[fi].disable;
+		ch_flags |= jsf->new | jsf->disable;
 	}
 	if ((flags & (JAIL_CREATE | JAIL_UPDATE | JAIL_ATTACH)) == JAIL_CREATE
 	    && !(pr_flags & PR_PERSIST)) {
@@ -668,9 +653,11 @@ kern_jail_set(struct thread *td, struct uio *optuio, i
 #endif
 
 	pr_allow = ch_allow = 0;
-	for (fi = 0; fi < nitems(pr_allow_names); fi++) {
-		vfs_flagopt(opts, pr_allow_names[fi], &pr_allow, 1 << fi);
-		vfs_flagopt(opts, pr_allow_nonames[fi], &ch_allow, 1 << fi);
+	for (bf = pr_flag_allow;
+	     bf < pr_flag_allow + nitems(pr_flag_allow);
+	     bf++) {
+		vfs_flagopt(opts, bf->name, &pr_allow, bf->flag);
+		vfs_flagopt(opts, bf->noname, &ch_allow, bf->flag);
 	}
 	ch_allow |= pr_allow;
 
@@ -1940,11 +1927,14 @@ sys_jail_get(struct thread *td, struct jail_get_args *
 int
 kern_jail_get(struct thread *td, struct uio *optuio, int flags)
 {
+	struct bool_flags *bf;
+	struct jailsys_flags *jsf;
 	struct prison *pr, *mypr;
 	struct vfsopt *opt;
 	struct vfsoptlist *opts;
 	char *errmsg, *name;
-	int error, errmsg_len, errmsg_pos, fi, i, jid, len, locked, pos;
+	int error, errmsg_len, errmsg_pos, i, jid, len, locked, pos;
+	unsigned f;
 
 	if (flags & ~JAIL_GET_MASK)
 		return (EINVAL);
@@ -2101,39 +2091,38 @@ kern_jail_get(struct thread *td, struct uio *optuio, i
 	    sizeof(pr->pr_devfs_rsnum));
 	if (error != 0 && error != ENOENT)
 		goto done_deref;
-	for (fi = 0; fi < nitems(pr_flag_names); fi++) {
-		if (pr_flag_names[fi] == NULL)
-			continue;
-		i = (pr->pr_flags & (1 << fi)) ? 1 : 0;
-		error = vfs_setopt(opts, pr_flag_names[fi], &i, sizeof(i));
+	for (bf = pr_flag_bool;
+	     bf < pr_flag_bool + nitems(pr_flag_bool);
+	     bf++) {
+		i = (pr->pr_flags & bf->flag) ? 1 : 0;
+		error = vfs_setopt(opts, bf->name, &i, sizeof(i));
 		if (error != 0 && error != ENOENT)
 			goto done_deref;
 		i = !i;
-		error = vfs_setopt(opts, pr_flag_nonames[fi], &i, sizeof(i));
+		error = vfs_setopt(opts, bf->noname, &i, sizeof(i));
 		if (error != 0 && error != ENOENT)
 			goto done_deref;
 	}
-	for (fi = 0; fi < nitems(pr_flag_jailsys); fi++) {
-		i = pr->pr_flags &
-		    (pr_flag_jailsys[fi].disable | pr_flag_jailsys[fi].new);
-		i = pr_flag_jailsys[fi].disable &&
-		      (i == pr_flag_jailsys[fi].disable) ? JAIL_SYS_DISABLE
-		    : (i == pr_flag_jailsys[fi].new) ? JAIL_SYS_NEW
+	for (jsf = pr_flag_jailsys;
+	     jsf < pr_flag_jailsys + nitems(pr_flag_jailsys);
+	     jsf++) {
+		f = pr->pr_flags & (jsf->disable | jsf->new);
+		i = (f != 0 && f == jsf->disable) ? JAIL_SYS_DISABLE
+		    : (f == jsf->new) ? JAIL_SYS_NEW
 		    : JAIL_SYS_INHERIT;
-		error =
-		    vfs_setopt(opts, pr_flag_jailsys[fi].name, &i, sizeof(i));
+		error = vfs_setopt(opts, jsf->name, &i, sizeof(i));
 		if (error != 0 && error != ENOENT)
 			goto done_deref;
 	}
-	for (fi = 0; fi < nitems(pr_allow_names); fi++) {
-		if (pr_allow_names[fi] == NULL)
-			continue;
-		i = (pr->pr_allow & (1 << fi)) ? 1 : 0;
-		error = vfs_setopt(opts, pr_allow_names[fi], &i, sizeof(i));
+	for (bf = pr_flag_allow;
+	     bf < pr_flag_allow + nitems(pr_flag_allow);
+	     bf++) {
+		i = (pr->pr_allow & bf->flag) ? 1 : 0;
+		error = vfs_setopt(opts, bf->name, &i, sizeof(i));
 		if (error != 0 && error != ENOENT)
 			goto done_deref;
 		i = !i;
-		error = vfs_setopt(opts, pr_allow_nonames[fi], &i, sizeof(i));
+		error = vfs_setopt(opts, bf->noname, &i, sizeof(i));
 		if (error != 0 && error != ENOENT)
 			goto done_deref;
 	}
@@ -4007,11 +3996,12 @@ prison_racct_detach(struct prison *pr)
 static void
 db_show_prison(struct prison *pr)
 {
-	int fi;
+	struct bool_flags *bf;
+	struct jailsys_flags *jsf;
 #if defined(INET) || defined(INET6)
 	int ii;
 #endif
-	unsigned jsf;
+	unsigned f;
 #ifdef INET
 	char ip4buf[INET_ADDRSTRLEN];
 #endif
@@ -4039,22 +4029,24 @@ db_show_prison(struct prison *pr)
 	db_printf(" child           = %p\n", LIST_FIRST(&pr->pr_children));
 	db_printf(" sibling         = %p\n", LIST_NEXT(pr, pr_sibling));
 	db_printf(" flags           = 0x%x", pr->pr_flags);
-	for (fi = 0; fi < nitems(pr_flag_names); fi++)
-		if (pr_flag_names[fi] != NULL && (pr->pr_flags & (1 << fi)))
-			db_printf(" %s", pr_flag_names[fi]);
-	for (fi = 0; fi < nitems(pr_flag_jailsys); fi++) {
-		jsf = pr->pr_flags &
-		    (pr_flag_jailsys[fi].disable | pr_flag_jailsys[fi].new);
-		db_printf(" %-16s= %s\n", pr_flag_jailsys[fi].name,
-		    pr_flag_jailsys[fi].disable && 
-		      (jsf == pr_flag_jailsys[fi].disable) ? "disable"
-		    : (jsf == pr_flag_jailsys[fi].new) ? "new"
+	for (bf = pr_flag_bool; bf < pr_flag_bool + nitems(pr_flag_bool); bf++)
+		if (pr->pr_flags & bf->flag)
+			db_printf(" %s", bf->name);
+	for (jsf = pr_flag_jailsys;
+	     jsf < pr_flag_jailsys + nitems(pr_flag_jailsys);
+	     jsf++) {
+		f = pr->pr_flags & (jsf->disable | jsf->new);
+		db_printf(" %-16s= %s\n", jsf->name,
+		    (f != 0 && f == jsf->disable) ? "disable"
+		    : (f == jsf->new) ? "new"
 		    : "inherit");
 	}
 	db_printf(" allow           = 0x%x", pr->pr_allow);
-	for (fi = 0; fi < nitems(pr_allow_names); fi++)
-		if (pr_allow_names[fi] != NULL && (pr->pr_allow & (1 << fi)))
-			db_printf(" %s", pr_allow_names[fi]);
+	for (bf = pr_flag_allow;
+	     bf < pr_flag_allow + nitems(pr_flag_allow);
+	     bf++)
+		if (pr->pr_allow & bf->flag)
+			db_printf(" %s", bf->name);
 	db_printf("\n");
 	db_printf(" enforce_statfs  = %d\n", pr->pr_enforce_statfs);
 	db_printf(" host.hostname   = %s\n", pr->pr_hostname);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201803202308.w2KN8gYe019890>