summaryrefslogtreecommitdiffstats
path: root/lib/libjail
diff options
context:
space:
mode:
authorjamie <jamie@FreeBSD.org>2010-07-15 19:21:07 +0000
committerjamie <jamie@FreeBSD.org>2010-07-15 19:21:07 +0000
commit9afbdfdebb2e3504b17903f4a91a22ca22280c25 (patch)
tree42bdec230b62bf721844495b4eaa6d768411e477 /lib/libjail
parente3a946ddadfb17c53f9e7d4c6f30c03276892f96 (diff)
downloadFreeBSD-src-9afbdfdebb2e3504b17903f4a91a22ca22280c25.zip
FreeBSD-src-9afbdfdebb2e3504b17903f4a91a22ca22280c25.tar.gz
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
Diffstat (limited to 'lib/libjail')
-rw-r--r--lib/libjail/jail.c158
1 files changed, 87 insertions, 71 deletions
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
OpenPOWER on IntegriCloud