aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_environment.c46
-rw-r--r--sys/sys/priv.h1
2 files changed, 41 insertions, 6 deletions
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.