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
This commit is contained in:
parent
e3a946ddad
commit
9afbdfdebb
@ -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;
|
||||
}
|
||||
}
|
||||
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) {
|
||||
va_end(ap);
|
||||
return (-1);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -793,41 +844,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.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user