From 9afbdfdebb2e3504b17903f4a91a22ca22280c25 Mon Sep 17 00:00:00 2001 From: jamie Date: Thu, 15 Jul 2010 19:21:07 +0000 Subject: 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 --- lib/libjail/jail.c | 158 +++++++++++++++++++++++++++++------------------------ 1 file changed, 87 insertions(+), 71 deletions(-) (limited to 'lib/libjail') diff --git a/lib/libjail/jail.c b/lib/libjail/jail.c index c82cb11..a374563 100644 --- a/lib/libjail/jail.c +++ b/lib/libjail/jail.c @@ -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[] = { "disable", "new", "inherit" }; 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, unsigned njp) } /* - * 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 -- cgit v1.1