svn commit: r210133 - head/lib/libjail

Jamie Gritton jamie at FreeBSD.org
Thu Jul 15 19:21:08 UTC 2010


Author: jamie
Date: Thu Jul 15 19:21:07 2010
New Revision: 210133
URL: http://svn.freebsd.org/changeset/base/210133

Log:
  Don't import parameter values in jail_getv, except for the search key.
  Remove the internal jailparam_vlist, in favor of using variants of its
   logic separately in jail_setv and jail_getv.
  Free the temporary parameter list and exported values in jail_setv
   and jail_getv.
  
  Noted by:	Stanislav Uzunchev
  MFC after:	3 days

Modified:
  head/lib/libjail/jail.c

Modified: head/lib/libjail/jail.c
==============================================================================
--- head/lib/libjail/jail.c	Thu Jul 15 18:44:58 2010	(r210132)
+++ head/lib/libjail/jail.c	Thu Jul 15 19:21:07 2010	(r210133)
@@ -56,7 +56,6 @@ __FBSDID("$FreeBSD$");
 
 static int jailparam_import_enum(const char **values, int nvalues,
     const char *valstr, size_t valsize, int *value);
-static int jailparam_vlist(struct jailparam **jpp, va_list ap);
 static int jailparam_type(struct jailparam *jp);
 static char *noname(const char *name);
 static char *nononame(const char *name);
@@ -74,16 +73,31 @@ static const char *jailsys_values[] = { 
 int
 jail_setv(int flags, ...)
 {
-	va_list ap;
+	va_list ap, tap;
 	struct jailparam *jp;
-	int njp;
+	const char *name, *value;
+	int njp, jid;
 
+	/* Create the parameter list and import the parameters. */
 	va_start(ap, flags);
-	njp = jailparam_vlist(&jp, ap);
+	va_copy(tap, ap);
+	for (njp = 0; va_arg(tap, char *) != NULL; njp++)
+		(void)va_arg(tap, char *);
+	va_end(tap);
+	jp = alloca(njp * sizeof(struct jailparam));
+	for (njp = 0; (name = va_arg(ap, char *)) != NULL; njp++) {
+		value = va_arg(ap, char *);
+		if (jailparam_init(jp + njp, name) < 0 ||
+		    jailparam_import(jp + njp, value) < 0) {
+			jailparam_free(jp, njp);
+			va_end(ap);
+			return (-1);
+		}
+	}
 	va_end(ap);
-	if (njp < 0)
-		return (njp);
-	return (jailparam_set(jp, njp, flags));
+	jid = jailparam_set(jp, njp, flags);
+	jailparam_free(jp, njp);
+	return (jid);
 }
 
 /*
@@ -94,48 +108,85 @@ int
 jail_getv(int flags, ...)
 {
 	va_list ap, tap;
-	struct jailparam *jp;
-	char *valarg;
-	const char *value;
-	int njp, i, jid, namekey, zero;
+	struct jailparam *jp, *jp_lastjid, *jp_jid, *jp_name, *jp_key;
+	char *valarg, *value;
+	const char *name, *key_value, *lastjid_value, *jid_value, *name_value;
+	int njp, i, jid;
 
+	/* Create the parameter list and find the key. */
 	va_start(ap, flags);
 	va_copy(tap, ap);
-	njp = jailparam_vlist(&jp, tap);
+	for (njp = 0; va_arg(tap, char *) != NULL; njp++)
+		(void)va_arg(tap, char *);
 	va_end(tap);
-	if (njp < 0)
-		return (njp);
-	/*
-	 * See if the name is the search key.  If so, we don't want to write
-	 * it back in case it's a read-only string.
-	 */
-	namekey = 1;
-	zero = 0;
-	for (i = 0; i < njp; i++) {
-		if (!strcmp(jp->jp_name, "lastjid") ||
-		    (!strcmp(jp->jp_name, "jid") &&
-		     memcmp(jp->jp_value, &zero, sizeof(zero))))
-			namekey = 0;
+
+	jp = alloca(njp * sizeof(struct jailparam));
+	va_copy(tap, ap);
+	jp_lastjid = jp_jid = jp_name = NULL;
+	lastjid_value = jid_value = name_value = NULL;
+	for (njp = 0; (name = va_arg(tap, char *)) != NULL; njp++) {
+		value = va_arg(tap, char *);
+		if (jailparam_init(jp + njp, name) < 0) {
+			va_end(tap);
+			goto error;
+		}
+		if (!strcmp(jp[njp].jp_name, "lastjid")) {
+			jp_lastjid = jp + njp;
+			lastjid_value = value;
+		} else if (!strcmp(jp[njp].jp_name, "jid")) {
+			jp_jid = jp + njp;
+			jid_value = value;
+		} if (!strcmp(jp[njp].jp_name, "name")) {
+			jp_name = jp + njp;
+			name_value = value;
+		}
 	}
-	jid = jailparam_get(jp, njp, flags);
-	if (jid < 0) {
-		va_end(ap);
-		return (-1);
+	va_end(tap);
+	/* Import the key parameter. */
+	if (jp_lastjid != NULL) {
+		jp_key = jp_lastjid;
+		key_value = lastjid_value;
+	} else if (jp_jid != NULL && strtol(jid_value, NULL, 10) != 0) {
+		jp_key = jp_jid;
+		key_value = jid_value;
+	} else if (jp_name != NULL) {
+		jp_key = jp_name;
+		key_value = name_value;
+	} else {
+		strlcpy(jail_errmsg, "no jail specified", JAIL_ERRMSGLEN);
+		errno = ENOENT;
+		goto error;
 	}
+	if (jailparam_import(jp_key, key_value) < 0)
+		goto error;
+	/* Get the jail and export the parameters. */
+	jid = jailparam_get(jp, njp, flags);
+	if (jid < 0)
+		goto error;
 	for (i = 0; i < njp; i++) {
 		(void)va_arg(ap, char *);
-		value = jailparam_export(jp + i);
-		if (value == NULL) {
-			va_end(ap);
-			return (-1);
-		}
 		valarg = va_arg(ap, char *);
-		if (!namekey || strcmp(jp[i].jp_name, "name"))
+		if (jp + i != jp_key) {
 			/* It's up to the caller to ensure there's room. */
-			strcpy(valarg, value);
+			if ((jp[i].jp_ctltype & CTLTYPE) == CTLTYPE_STRING)
+				strcpy(valarg, jp[i].jp_value);
+			else {
+				value = jailparam_export(jp + i);
+				if (value == NULL)
+					goto error;
+				strcpy(valarg, value);
+				free(value);
+			}
+		}
 	}
+	jailparam_free(jp, njp);
 	va_end(ap);
 	return (jid);
+
+ error:
+	jailparam_free(jp, njp);
+	va_end(ap);
+	return (-1);
 }
 
 /*
@@ -794,41 +845,6 @@ jailparam_free(struct jailparam *jp, uns
 }
 
 /*
- * Create and import an array of jail parameters, given a list of name and
- * value strings, terminated by a null name.
- */
-static int
-jailparam_vlist(struct jailparam **jpp, va_list ap)
-{
-	va_list tap;
-	struct jailparam *jp;
-	char *name, *value;
-	int njp;
-
-	va_copy(tap, ap);
-	for (njp = 0; va_arg(tap, char *) != NULL; njp++)
-		(void)va_arg(tap, char *);
-	va_end(tap);
-	jp = calloc(njp, sizeof(struct jailparam));
-	if (jp == NULL) {
-		strerror_r(errno, jail_errmsg, JAIL_ERRMSGLEN);
-		return (-1);
-	}
-
-	for (njp = 0; (name = va_arg(ap, char *)) != NULL; njp++) {
-		value = va_arg(ap, char *);
-		if (jailparam_init(jp + njp, name) < 0 ||
-		    jailparam_import(jp + njp, value) < 0) {
-			jailparam_free(jp, njp);
-			free(jp);
-			return (-1);
-		}
-	}
-	*jpp = jp;
-	return (njp);
-}
-
-/*
  * Find a parameter's type and size from its MIB.
  */
 static int


More information about the svn-src-head mailing list