diff options
| -rw-r--r-- | bin/kenv/kenv.1 | 10 | ||||
| -rw-r--r-- | lib/libsys/kenv.2 | 7 | ||||
| -rw-r--r-- | share/man/man7/security.7 | 4 | ||||
| -rw-r--r-- | sys/kern/kern_environment.c | 46 | ||||
| -rw-r--r-- | sys/sys/priv.h | 1 |
5 files changed, 59 insertions, 9 deletions
diff --git a/bin/kenv/kenv.1 b/bin/kenv/kenv.1 index 9b6d0e0b33f2..c0cf0c29cabe 100644 --- a/bin/kenv/kenv.1 +++ b/bin/kenv/kenv.1 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd June 20, 2021 +.Dd June 22, 2026 .Dt KENV 1 .Os .Sh NAME @@ -166,3 +166,11 @@ The .Nm utility appeared in .Fx 4.1.1 . +.Sh SECURITY CONSIDERATIONS +Note that unprivileged users are allowed to read from the kernel environment, +unless the +.Va security.bsd.unprivileged_kenv_read +sysctl is set to 0. +This includes both listing the kernel environment, as well as getting a specific +.Va variable +from the environment. diff --git a/lib/libsys/kenv.2 b/lib/libsys/kenv.2 index 9f179ff2faa6..bdf4dd7f1386 100644 --- a/lib/libsys/kenv.2 +++ b/lib/libsys/kenv.2 @@ -24,7 +24,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH .\" DAMAGE. .\" -.Dd June 20, 2021 +.Dd June 22, 2026 .Dt KENV 2 .Os .Sh NAME @@ -161,6 +161,11 @@ The kernel is configured to destroy these environments by default. .It Bq Er EPERM A user other than the superuser attempted to set or unset a kernel environment variable. +.It Bq Er EPERM +A user other than the superuser attempted to get a variable from or dump the +kernel environment, and the +.Va security.bsd.unprivileged_kenv_read +sysctl is set to 0. .It Bq Er EFAULT A bad address was encountered while attempting to copy in user arguments or copy out value(s). diff --git a/share/man/man7/security.7 b/share/man/man7/security.7 index 395cf082c2fc..bec5c4f0b001 100644 --- a/share/man/man7/security.7 +++ b/share/man/man7/security.7 @@ -26,7 +26,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd March 22, 2026 +.Dd June 22, 2026 .Dt SECURITY 7 .Os .Sh NAME @@ -987,6 +987,8 @@ and usual termination signals like and .Dv SIGTERM , to the processes executing programs with changed uids. +.It Va security.bsd.unprivileged_kenv_read +Controls availability of kernel environment variables to non-root users. .It Va security.bsd.unprivileged_proc_debug Controls availability of the process debugging facilities to non-root users. See also diff --git a/sys/kern/kern_environment.c b/sys/kern/kern_environment.c index 7c0654769581..72c7544b4bac 100644 --- a/sys/kern/kern_environment.c +++ b/sys/kern/kern_environment.c @@ -49,6 +49,7 @@ #include <sys/priv.h> #include <sys/proc.h> #include <sys/queue.h> +#include <sys/sysctl.h> #include <sys/sysent.h> #include <sys/sysproto.h> @@ -91,6 +92,11 @@ bool dynamic_kenv; #define KENV_CHECK if (!dynamic_kenv) \ panic("%s: called before SI_SUB_KMEM", __func__) +static int unprivileged_kenv_read = 1; +SYSCTL_INT(_security_bsd, OID_AUTO, unprivileged_kenv_read, CTLFLAG_RW, + &unprivileged_kenv_read, 1, + "Unprivileged processes can read the kernel environment"); + static int kenv_dump(struct thread *td, char **envp, int what, char *value, int len) { @@ -155,6 +161,33 @@ kenv_dump(struct thread *td, char **envp, int what, char *value, int len) return (error); } +static int +kenv_read_allowed(struct thread *td, int which) +{ + int error; + + if (!unprivileged_kenv_read) { + error = priv_check(td, PRIV_KENV_READ); + if (error) + return (error); + } + + switch (which) { + case KENV_DUMP: + case KENV_DUMP_LOADER: + case KENV_DUMP_STATIC: +#ifdef MAC + error = mac_kenv_check_dump(td->td_ucred); +#endif + break; + default: + error = 0; + break; + } + + return (error); +} + int sys_kenv(struct thread *td, struct kenv_args *uap) { @@ -168,19 +201,15 @@ sys_kenv(struct thread *td, struct kenv_args *uap) switch (uap->what) { case KENV_DUMP: -#ifdef MAC - error = mac_kenv_check_dump(td->td_ucred); + error = kenv_read_allowed(td, uap->what); if (error) return (error); -#endif return (kenv_dump(td, kenvp, uap->what, uap->value, uap->len)); case KENV_DUMP_LOADER: case KENV_DUMP_STATIC: -#ifdef MAC - error = mac_kenv_check_dump(td->td_ucred); + error = kenv_read_allowed(td, uap->what); if (error) return (error); -#endif #ifdef PRESERVE_EARLY_KENV return (kenv_dump(td, uap->what == KENV_DUMP_LOADER ? (char **)md_envp : @@ -199,6 +228,11 @@ sys_kenv(struct thread *td, struct kenv_args *uap) if (error) return (error); break; + case KENV_GET: + error = kenv_read_allowed(td, uap->what); + if (error) + return (error); + break; } name = malloc(KENV_MNAMELEN + 1, M_TEMP, M_WAITOK); diff --git a/sys/sys/priv.h b/sys/sys/priv.h index 148f2191c6e0..87775632f8a8 100644 --- a/sys/sys/priv.h +++ b/sys/sys/priv.h @@ -141,6 +141,7 @@ */ #define PRIV_KENV_SET 120 /* Set kernel env. variables. */ #define PRIV_KENV_UNSET 121 /* Unset kernel env. variables. */ +#define PRIV_KENV_READ 122 /* Get/dump kernel env. variables. */ /* * Loadable kernel module privileges. |
