DF-2895 / kenv_set.c
/* DF-2895: sys_kenv KENV_SET ignores ksetenv() failure. * A KENV name of exactly KENV_MNAMELEN(128) chars passes the syscall * copyinstr (129 cap) but is rejected inside ksetenv -> syscall returns * success while nothing was stored. * * expect (vulnerable): set rv=0, get ENOENT (silent drop) * expect (patched): set rv=-1 EINVAL */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> int kenv(int action, const char *name, char *value, int len); #ifndef KENV_GET #define KENV_GET 0 #define KENV_SET 1 #define KENV_UNSET 2 #endif #ifndef KENV_MNAMELEN #define KENV_MNAMELEN 128 #endif int main(void) { char name[KENV_MNAMELEN + 1]; char small[256]; int rv, err; memset(name, 'D', KENV_MNAMELEN); name[KENV_MNAMELEN] = 0; errno = 0; rv = kenv(KENV_SET, name, "df2895value", 12); err = errno; printf("DF2895 KENV_SET(128-char name) rv=%d errno=%d (%s)\n", rv, err, strerror(err)); errno = 0; rv = kenv(KENV_GET, name, small, sizeof(small)); err = errno; printf("DF2895 KENV_GET(same name) rv=%d errno=%d (%s)\n", rv, err, strerror(err)); /* boundary control: 127-char name must work */ name[KENV_MNAMELEN - 1] = 0; errno = 0; rv = kenv(KENV_SET, name, "df2895ok", 9); err = errno; printf("DF2895 KENV_SET(127-char name) rv=%d errno=%d (control: works)\n", rv, err); errno = 0; rv = kenv(KENV_GET, name, small, sizeof(small)); printf("DF2895 KENV_GET(127-char name) rv=%d value=%s\n", rv, rv > 0 ? small : "-"); (void)kenv(KENV_UNSET, name, NULL, 0); return 0; } |