Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F145666627
D53959.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D53959.diff
View Options
diff --git a/lib/libjail/jail.c b/lib/libjail/jail.c
--- a/lib/libjail/jail.c
+++ b/lib/libjail/jail.c
@@ -35,6 +35,7 @@
#include <arpa/inet.h>
#include <netinet/in.h>
+#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <stdio.h>
@@ -46,12 +47,45 @@
#define SJPARAM "security.jail.param"
-#define JPS_IN_ADDR 1
-#define JPS_IN6_ADDR 2
+#define JPSDEF_OF(jp) \
+ ((jp)->jp_structtype >= 0 ? &jp_structdefs[(jp)->jp_structtype] : NULL)
+
+typedef int (jps_import_t)(const struct jailparam *, int, const char *);
+typedef char *(jps_export_t)(const struct jailparam *, int);
+
+static jps_import_t jps_import_in_addr;
+static jps_import_t jps_import_in6_addr;
+
+static jps_export_t jps_export_in_addr;
+static jps_export_t jps_export_in6_addr;
+
+static const struct jp_structdef {
+ const char *jps_type; /* sysctl type */
+ size_t jps_valuelen; /* value size */
+ jps_import_t *jps_import; /* jailparam_import() */
+ jps_export_t *jps_export; /* jailparam_export() */
+} jp_structdefs[] = {
+ {
+ .jps_type = "S,in_addr",
+ .jps_valuelen = sizeof(struct in_addr),
+ .jps_import = jps_import_in_addr,
+ .jps_export = jps_export_in_addr,
+ },
+ {
+ .jps_type = "S,in6_addr",
+ .jps_valuelen = sizeof(struct in6_addr),
+ .jps_import = jps_import_in6_addr,
+ .jps_export = jps_export_in6_addr,
+ },
+};
+
+_Static_assert(nitems(jp_structdefs) <= INT_MAX,
+ "Too many struct definitions requires an ABI break in struct jailparam");
#define ARRAY_SANITY 5
#define ARRAY_SLOP 5
+static const struct jp_structdef *jp_structinfo(const char *type, int *);
static int jailparam_import_enum(const char **values, int nvalues,
const char *valstr, size_t valsize, int *value);
@@ -66,6 +100,23 @@
static const char *bool_values[] = { "false", "true" };
static const char *jailsys_values[] = { "disable", "new", "inherit" };
+static const struct jp_structdef *
+jp_structinfo(const char *type, int *oidx)
+{
+ const struct jp_structdef *jpsdef;
+
+ for (size_t idx = 0; idx < nitems(jp_structdefs); idx++) {
+ jpsdef = &jp_structdefs[idx];
+
+ if (strcmp(jpsdef->jps_type, type) == 0) {
+ *oidx = (int)idx;
+ return (jpsdef);
+ }
+ }
+
+ *oidx = -1;
+ return (NULL);
+}
/*
* Import a null-terminated parameter list and set a jail with the flags
@@ -325,6 +376,7 @@
{
char *p, *ep, *tvalue;
const char *avalue;
+ const struct jp_structdef *jpsdef;
int i, nval, fw;
if (value == NULL)
@@ -426,34 +478,13 @@
case CTLTYPE_STRUCT:
tvalue = alloca(fw + 1);
strlcpy(tvalue, avalue, fw + 1);
- switch (jp->jp_structtype) {
- case JPS_IN_ADDR:
- if (inet_pton(AF_INET, tvalue,
- &((struct in_addr *)jp->jp_value)[i]) != 1)
- {
- snprintf(jail_errmsg,
- JAIL_ERRMSGLEN,
- "%s: not an IPv4 address: %s",
- jp->jp_name, tvalue);
- errno = EINVAL;
- goto error;
- }
- break;
- case JPS_IN6_ADDR:
- if (inet_pton(AF_INET6, tvalue,
- &((struct in6_addr *)jp->jp_value)[i]) != 1)
- {
- snprintf(jail_errmsg,
- JAIL_ERRMSGLEN,
- "%s: not an IPv6 address: %s",
- jp->jp_name, tvalue);
- errno = EINVAL;
- goto error;
- }
- break;
- default:
+
+ if (jp->jp_structtype == -1)
goto unknown_type;
- }
+
+ jpsdef = &jp_structdefs[jp->jp_structtype];
+ if ((*jpsdef->jps_import)(jp, i, tvalue) != 0)
+ goto error;
break;
default:
unknown_type:
@@ -773,6 +804,7 @@
{
size_t *valuelens;
char *value, *tvalue, **values;
+ const struct jp_structdef *jpsdef;
size_t valuelen;
int i, nval, ival;
char valbuf[INET6_ADDRSTRLEN];
@@ -839,29 +871,25 @@
(uintmax_t)((uint64_t *)jp->jp_value)[i]);
break;
case CTLTYPE_STRUCT:
- switch (jp->jp_structtype) {
- case JPS_IN_ADDR:
- if (inet_ntop(AF_INET,
- &((struct in_addr *)jp->jp_value)[i],
- valbuf, sizeof(valbuf)) == NULL) {
- strerror_r(errno, jail_errmsg,
- JAIL_ERRMSGLEN);
- return (NULL);
- }
- break;
- case JPS_IN6_ADDR:
- if (inet_ntop(AF_INET6,
- &((struct in6_addr *)jp->jp_value)[i],
- valbuf, sizeof(valbuf)) == NULL) {
- strerror_r(errno, jail_errmsg,
- JAIL_ERRMSGLEN);
- return (NULL);
- }
- break;
- default:
+ if (jp->jp_structtype == -1)
goto unknown_type;
+
+ jpsdef = &jp_structdefs[jp->jp_structtype];
+ value = (*jpsdef->jps_export)(jp, i);
+ if (value == NULL) {
+ strerror_r(errno, jail_errmsg,
+ JAIL_ERRMSGLEN);
+ return (NULL);
}
- break;
+
+ valuelens[i] = strlen(value) + 1;
+ valuelen += valuelens[i];
+ values[i] = alloca(valuelens[i]);
+ strcpy(values[i], value);
+
+ free(value);
+ value = NULL;
+ continue; /* Value already added to values[] */
default:
unknown_type:
snprintf(jail_errmsg, JAIL_ERRMSGLEN,
@@ -1055,14 +1083,17 @@
}
jp->jp_valuelen = strtoul(desc.s, NULL, 10);
break;
- case CTLTYPE_STRUCT:
- if (!strcmp(desc.s, "S,in_addr")) {
- jp->jp_structtype = JPS_IN_ADDR;
- jp->jp_valuelen = sizeof(struct in_addr);
- } else if (!strcmp(desc.s, "S,in6_addr")) {
- jp->jp_structtype = JPS_IN6_ADDR;
- jp->jp_valuelen = sizeof(struct in6_addr);
+ case CTLTYPE_STRUCT: {
+ const struct jp_structdef *jpsdef;
+
+ jpsdef = jp_structinfo(desc.s, &jp->jp_structtype);
+ if (jpsdef != NULL) {
+ assert(jp->jp_structtype >= 0);
+
+ jp->jp_valuelen = jpsdef->jps_valuelen;
} else {
+ assert(jp->jp_structtype == -1);
+
desclen = 0;
if (sysctl(mib + 2, miblen / sizeof(int),
NULL, &jp->jp_valuelen, NULL, 0) < 0) {
@@ -1073,6 +1104,7 @@
}
}
break;
+ }
case CTLTYPE_NODE:
/*
* A node might be described by an empty-named child,
@@ -1215,3 +1247,63 @@
return (kvname);
}
+
+static int
+jps_import_in_addr(const struct jailparam *jp, int i, const char *value)
+{
+ struct in_addr *addr;
+
+ addr = &((struct in_addr *)jp->jp_value)[i];
+ if (inet_pton(AF_INET, value, addr) != 1) {
+ snprintf(jail_errmsg, JAIL_ERRMSGLEN,
+ "%s: not an IPv4 address: %s", jp->jp_name, value);
+ errno = EINVAL;
+ return (-1);
+ }
+
+ return (0);
+}
+
+static int
+jps_import_in6_addr(const struct jailparam *jp, int i, const char *value)
+{
+ struct in6_addr *addr6;
+
+ addr6 = &((struct in6_addr *)jp->jp_value)[i];
+ if (inet_pton(AF_INET6, value, addr6) != 1) {
+ snprintf(jail_errmsg, JAIL_ERRMSGLEN,
+ "%s: not an IPv6 address: %s", jp->jp_name, value);
+ errno = EINVAL;
+ return (-1);
+ }
+
+ return (0);
+}
+
+static char *
+jps_export_in_addr(const struct jailparam *jp, int i)
+{
+ struct in_addr *addr;
+ char valbuf[INET_ADDRSTRLEN];
+
+ addr = &((struct in_addr *)jp->jp_value)[i];
+ if (inet_ntop(AF_INET, addr, valbuf, sizeof(valbuf)) == NULL)
+ return (NULL);
+
+ /* Error checked by caller. */
+ return (strdup(valbuf));
+}
+
+static char *
+jps_export_in6_addr(const struct jailparam *jp, int i)
+{
+ struct in6_addr *addr6;
+ char valbuf[INET6_ADDRSTRLEN];
+
+ addr6 = &((struct in6_addr *)jp->jp_value)[i];
+ if (inet_ntop(AF_INET6, addr6, valbuf, sizeof(valbuf)) == NULL)
+ return (NULL);
+
+ /* Error checked by caller. */
+ return (strdup(valbuf));
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Feb 23, 9:01 PM (15 h, 33 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26295219
Default Alt Text
D53959.diff (7 KB)
Attached To
Mode
D53959: libjail: start refactoring struct ioctl support
Attached
Detach File
Event Timeline
Log In to Comment