37 #include <sys/cdefs.h>
40 #include <sys/types.h>
41 #include <sys/param.h>
43 #include <sys/queue.h>
45 #include <sys/malloc.h>
46 #include <sys/mutex.h>
48 #include <sys/kernel.h>
49 #include <sys/systm.h>
50 #include <sys/sysent.h>
51 #include <sys/sysproto.h>
52 #include <sys/libkern.h>
55 #include <security/mac/mac_framework.h>
76 #define KENV_CHECK if (!dynamic_kenv) \
77 panic("%s: called before SI_SUB_KMEM", __func__)
90 size_t len, done, needed, buflen;
96 if (uap->what == KENV_DUMP) {
98 error = mac_kenv_check_dump(td->td_ucred);
104 if (buflen >
KENV_SIZE * (KENV_MNAMELEN + KENV_MVALLEN + 2))
107 if (uap->len > 0 && uap->value != NULL)
108 buffer =
malloc(buflen, M_TEMP, M_WAITOK|M_ZERO);
110 for (i = 0;
kenvp[i] != NULL; i++) {
111 len = strlen(
kenvp[i]) + 1;
113 len = min(len, buflen - done);
118 if (uap->value != NULL && buffer != NULL && len > 0) {
119 bcopy(
kenvp[i], buffer + done, len);
124 if (buffer != NULL) {
125 error = copyout(buffer, uap->value, done);
126 free(buffer, M_TEMP);
128 td->td_retval[0] = ((done == needed) ? 0 : needed);
146 name =
malloc(KENV_MNAMELEN + 1, M_TEMP, M_WAITOK);
148 error = copyinstr(uap->name, name, KENV_MNAMELEN + 1, NULL);
155 error = mac_kenv_check_get(td->td_ucred, name);
164 len = strlen(value) + 1;
167 error = copyout(value, uap->value, len);
171 td->td_retval[0] = len;
179 if (len > KENV_MVALLEN + 1)
180 len = KENV_MVALLEN + 1;
181 value =
malloc(len, M_TEMP, M_WAITOK);
182 error = copyinstr(uap->value, value, len, NULL);
188 error = mac_kenv_check_set(td->td_ucred, name, value);
196 error = mac_kenv_check_unset(td->td_ucred, name);
235 len = strlen(cp) + 1;
236 if (len > KENV_MNAMELEN + 1 + KENV_MVALLEN + 1) {
237 printf(
"WARNING: too long kenv string, ignoring %s\n",
243 strcpy(
kenvp[i++], cp);
246 "WARNING: too many kenv strings, ignoring %s\n",
275 for (cp =
kenvp[0], i = 0; cp != NULL; cp =
kenvp[++i]) {
276 if ((strncmp(cp, name, len) == 0) &&
280 return (cp + len + 1);
293 for (ep = cp; (*ep !=
'=') && (*ep != 0); ep++)
299 if (!strncmp(name, cp, len) && name[len] == 0)
314 char buf[KENV_MNAMELEN + 1 + KENV_MVALLEN + 1];
324 len = strlen(buf) + 1;
325 ret =
malloc(len, M_KENV, M_WAITOK);
330 WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
366 len = strlen(name) + strlen(value);
383 char *
buf, *cp, *oldenv;
384 int namelen, vallen, i;
391 namelen = strlen(name) + 1;
392 if (namelen > KENV_MNAMELEN + 1)
394 vallen = strlen(value) + 1;
395 if (vallen > KENV_MVALLEN + 1)
397 buf =
malloc(namelen + vallen, M_KENV, M_WAITOK);
398 sprintf(buf,
"%s=%s", name, value);
406 free(oldenv, M_KENV);
409 for (i = 0; (cp =
kenvp[i]) != NULL; i++)
441 for (j = i + 1;
kenvp[j] != NULL; j++)
445 free(oldenv, M_KENV);
462 strlcpy(data, tmp, size);
495 *data = (
unsigned int) tmp;
525 *data = (
unsigned long) tmp;
542 iv = strtoq(value, &vtp, 0);
543 if (vtp == value || (vtp[0] !=
'\0' && vtp[1] !=
'\0')) {
588 struct tunable_int *d = (
struct tunable_int *)data;
590 TUNABLE_INT_FETCH(d->path, d->var);
596 struct tunable_long *d = (
struct tunable_long *)data;
598 TUNABLE_LONG_FETCH(d->path, d->var);
604 struct tunable_ulong *d = (
struct tunable_ulong *)data;
606 TUNABLE_ULONG_FETCH(d->path, d->var);
612 struct tunable_quad *d = (
struct tunable_quad *)data;
614 TUNABLE_QUAD_FETCH(d->path, d->var);
620 struct tunable_str *d = (
struct tunable_str *)data;
622 TUNABLE_STR_FETCH(d->path, d->var, d->size);
int getenv_int(const char *name, int *data)
int getenv_string(const char *name, char *data, int size)
static char * _getenv_dynamic(const char *name, int *idx)
static char * kernenv_next(char *)
int sprintf(char *buf, const char *cfmt,...)
void * malloc(unsigned long size, struct malloc_type *mtp, int flags)
int unsetenv(const char *name)
int getenv_ulong(const char *name, unsigned long *data)
SYSINIT(kenv, SI_SUB_KMEM, SI_ORDER_ANY, init_dynamic_kenv, NULL)
int priv_check(struct thread *td, int priv)
int sys_kenv(struct thread *td, struct kenv_args *uap)
void tunable_int_init(void *data)
static int setenv_static(const char *name, const char *value)
int getenv_long(const char *name, long *data)
void init_static_kenv(char *buf, size_t len)
void tunable_ulong_init(void *data)
static char * _getenv_static(const char *name)
char * getenv(const char *name)
int setenv(const char *name, const char *value)
static void init_dynamic_kenv(void *data __unused)
void free(void *addr, struct malloc_type *mtp)
int printf(const char *fmt,...)
void tunable_str_init(void *data)
void tunable_long_init(void *data)
static MALLOC_DEFINE(M_KENV,"kenv","kernel environment")
void mtx_init(struct mtx *m, const char *name, const char *type, int opts)
int getenv_uint(const char *name, unsigned int *data)
int testenv(const char *name)
int getenv_quad(const char *name, quad_t *data)
void tunable_quad_init(void *data)