Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F146670201
D15802.id43750.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D15802.id43750.diff
View Options
Index: kern/kern_environment.c
===================================================================
--- kern/kern_environment.c
+++ kern/kern_environment.c
@@ -517,6 +517,131 @@
}
/*
+ * Return an array of integers at the given type and size
+ */
+int
+getenv_array(const char *name, void *pdata, int size, int *psize,
+ int type_size)
+{
+ char buf[KENV_MNAMELEN + 1 + KENV_MVALLEN + 1];
+ bool allow_signed;
+ char *ptr;
+ int n;
+
+ if (getenv_string(name, buf, sizeof(buf)) == 0)
+ return (0);
+
+ /* check for signed type */
+ if (type_size < 0) {
+ allow_signed = 1;
+ type_size = -type_size;
+ } else {
+ allow_signed = 0;
+ }
+
+ /* get maximum number of elements */
+ size /= type_size;
+
+ /* reset counter */
+ n = 0;
+
+ for (ptr = buf; *ptr != 0; ) {
+ char *end;
+ int64_t value;
+ int64_t old;
+ uint8_t shift;
+
+ /* convert to value from string */
+ value = strtoq(ptr, &end, 0);
+
+ /* check if signed numbers are allowed */
+ if (value < 0 && !allow_signed)
+ goto error;
+
+ /* check for invalid value */
+ if (ptr == end)
+ goto error;
+
+ /* check for valid suffix */
+ switch (*end) {
+ case 't':
+ case 'T':
+ shift = 40;
+ end++;
+ break;
+ case 'g':
+ case 'G':
+ shift = 30;
+ end++;
+ break;
+ case 'm':
+ case 'M':
+ shift = 20;
+ end++;
+ break;
+ case 'k':
+ case 'K':
+ shift = 10;
+ end++;
+ break;
+ default:
+ shift = 0;
+ break;
+ }
+
+ /* skip till next value, if any */
+ while (*end == '\t' || *end == ',' || *end == ' ')
+ end++;
+
+ /* update pointer */
+ ptr = end;
+
+ /* apply shift */
+ old = value;
+ value <<= shift;
+
+ /* overflow check */
+ if ((value >> shift) != old)
+ goto error;
+
+ /* check for buffer overflow */
+ if (n >= size)
+ goto error;
+
+ /* store value according to type size */
+ switch (type_size) {
+ case 1:
+ if (value < -255 || value > 255)
+ goto error;
+ ((uint8_t *)pdata)[n] = (uint8_t)value;
+ break;
+ case 2:
+ if (value < -65535 || value > 65535)
+ goto error;
+ ((uint16_t *)pdata)[n] = (uint16_t)value;
+ break;
+ case 4:
+ if (value < -0xffffffffLL || value > 0xffffffffLL)
+ goto error;
+ ((uint32_t *)pdata)[n] = (uint32_t)value;
+ break;
+ case 8:
+ ((uint64_t *)pdata)[n] = (uint64_t)value;
+ break;
+ default:
+ goto error;
+ }
+ n++;
+ }
+ *psize = n * type_size;
+
+ if (n != 0)
+ return (1); /* success */
+error:
+ return (0); /* failure */
+}
+
+/*
* Return an integer value from an environment variable.
*/
int
Index: kern/kern_sysctl.c
===================================================================
--- kern/kern_sysctl.c
+++ kern/kern_sysctl.c
@@ -192,13 +192,8 @@
char path[96];
ssize_t rem = sizeof(path);
ssize_t len;
- uint8_t val_8;
- uint16_t val_16;
- uint32_t val_32;
- int val_int;
- long val_long;
- int64_t val_64;
- quad_t val_quad;
+ uint64_t data[64];
+ int size;
int error;
path[--rem] = 0;
@@ -226,85 +221,76 @@
switch (oidp->oid_kind & CTLTYPE) {
case CTLTYPE_INT:
- if (getenv_int(path + rem, &val_int) == 0)
+ if (getenv_array(path + rem, data, sizeof(data), &size, -(int)sizeof(int)) == 0)
return;
- req.newlen = sizeof(val_int);
- req.newptr = &val_int;
+ req.newlen = size;
+ req.newptr = data;
break;
case CTLTYPE_UINT:
- if (getenv_uint(path + rem, (unsigned int *)&val_int) == 0)
+ if (getenv_array(path + rem, data, sizeof(data), &size, sizeof(int)) == 0)
return;
- req.newlen = sizeof(val_int);
- req.newptr = &val_int;
+ req.newlen = size;
+ req.newptr = data;
break;
case CTLTYPE_LONG:
- if (getenv_long(path + rem, &val_long) == 0)
+ if (getenv_array(path + rem, data, sizeof(data), &size, -(int)sizeof(long)) == 0)
return;
- req.newlen = sizeof(val_long);
- req.newptr = &val_long;
+ req.newlen = size;
+ req.newptr = data;
break;
case CTLTYPE_ULONG:
- if (getenv_ulong(path + rem, (unsigned long *)&val_long) == 0)
+ if (getenv_array(path + rem, data, sizeof(data), &size, sizeof(long)) == 0)
return;
- req.newlen = sizeof(val_long);
- req.newptr = &val_long;
+ req.newlen = size;
+ req.newptr = data;
break;
case CTLTYPE_S8:
- if (getenv_int(path + rem, &val_int) == 0)
+ if (getenv_array(path + rem, data, sizeof(data), &size, -1) == 0)
return;
- val_8 = val_int;
- req.newlen = sizeof(val_8);
- req.newptr = &val_8;
+ req.newlen = size;
+ req.newptr = data;
break;
case CTLTYPE_S16:
- if (getenv_int(path + rem, &val_int) == 0)
+ if (getenv_array(path + rem, data, sizeof(data), &size, -2) == 0)
return;
- val_16 = val_int;
- req.newlen = sizeof(val_16);
- req.newptr = &val_16;
+ req.newlen = size;
+ req.newptr = data;
break;
case CTLTYPE_S32:
- if (getenv_long(path + rem, &val_long) == 0)
+ if (getenv_array(path + rem, data, sizeof(data), &size, -4) == 0)
return;
- val_32 = val_long;
- req.newlen = sizeof(val_32);
- req.newptr = &val_32;
+ req.newlen = size;
+ req.newptr = data;
break;
case CTLTYPE_S64:
- if (getenv_quad(path + rem, &val_quad) == 0)
+ if (getenv_array(path + rem, data, sizeof(data), &size, -8) == 0)
return;
- val_64 = val_quad;
- req.newlen = sizeof(val_64);
- req.newptr = &val_64;
+ req.newlen = size;
+ req.newptr = data;
break;
case CTLTYPE_U8:
- if (getenv_uint(path + rem, (unsigned int *)&val_int) == 0)
+ if (getenv_array(path + rem, data, sizeof(data), &size, 1) == 0)
return;
- val_8 = val_int;
- req.newlen = sizeof(val_8);
- req.newptr = &val_8;
+ req.newlen = size;
+ req.newptr = data;
break;
case CTLTYPE_U16:
- if (getenv_uint(path + rem, (unsigned int *)&val_int) == 0)
+ if (getenv_array(path + rem, data, sizeof(data), &size, 2) == 0)
return;
- val_16 = val_int;
- req.newlen = sizeof(val_16);
- req.newptr = &val_16;
+ req.newlen = size;
+ req.newptr = data;
break;
case CTLTYPE_U32:
- if (getenv_ulong(path + rem, (unsigned long *)&val_long) == 0)
+ if (getenv_array(path + rem, data, sizeof(data), &size, 4) == 0)
return;
- val_32 = val_long;
- req.newlen = sizeof(val_32);
- req.newptr = &val_32;
+ req.newlen = size;
+ req.newptr = data;
break;
case CTLTYPE_U64:
- /* XXX there is no getenv_uquad() */
- if (getenv_quad(path + rem, &val_quad) == 0)
+ if (getenv_array(path + rem, data, sizeof(data), &size, 8) == 0)
return;
- val_64 = val_quad;
- req.newlen = sizeof(val_64);
- req.newptr = &val_64;
+ req.newlen = size;
+ req.newptr = data;
break;
case CTLTYPE_STRING:
penv = kern_getenv(path + rem);
Index: sys/systm.h
===================================================================
--- sys/systm.h
+++ sys/systm.h
@@ -346,6 +346,7 @@
int getenv_long(const char *name, long *data);
int getenv_ulong(const char *name, unsigned long *data);
int getenv_string(const char *name, char *data, int size);
+int getenv_array(const char *name, void *data, int size, int *psize, int type_size);
int getenv_int64(const char *name, int64_t *data);
int getenv_uint64(const char *name, uint64_t *data);
int getenv_quad(const char *name, quad_t *data);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Mar 5, 2:20 PM (22 m, 19 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29288072
Default Alt Text
D15802.id43750.diff (6 KB)
Attached To
Mode
D15802: Permit the kernel environment to set an array of numeric values for a single sysctl(9) node.
Attached
Detach File
Event Timeline
Log In to Comment