tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: jit code and securelevel



Christos Zoulas wrote:
> On Jan 1,  6:21pm, alnsn%yandex.ru@localhost (Alexander Nasonov) wrote:
> | They might spot use-after-free bug and reuse freed memory for bpf_d
> | object which has a pointer to jit code.
> 
> The exploit takes advantage of being able to insert particular code
> sequences that have different meanings at different code offsets (which
> can happen naturally too -- there is a paper that describes such attacks),
> and depends on other kernel bugs to be functional.

A hypothetical use-after-free bug alone wouldn't let you jump to
a different offset, but those guys are very creative. If they ever
succeed in exploiting a system with a help of bpfjit code, I'd very
interested in details ;-)

> At the same time killing
> jit at securelevel 1 it is not really fatal with the exception on npf.
> 
> Perhaps having a sysctl to enable/disable it that can only be enabled
> at a low securelevel can let people choose the behavior they want.

I implemented it, see below, but I feel it's not right to query
securelevel directly, adding new KAUTH_SYSTEM_BPFJIT would be
a better approach. Not sure it's worth the effort.

Alex

Index: sys/net/bpf.c
===================================================================
RCS file: /cvsroot/src/sys/net/bpf.c,v
retrieving revision 1.190
diff -p -u -u -r1.190 bpf.c
--- sys/net/bpf.c	29 Dec 2014 13:38:13 -0000	1.190
+++ sys/net/bpf.c	1 Jan 2015 20:00:18 -0000
@@ -88,6 +88,7 @@ __KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.19
 #include <netinet/in.h>
 #include <netinet/if_inarp.h>
 
+#include <secmodel/secmodel.h>
 
 #include <compat/sys/sockio.h>
 
@@ -1084,6 +1085,17 @@ bpf_ioctl(struct file *fp, u_long cmd, v
 	return (error);
 }
 
+static bool
+is_securelevel_above(int level)
+{
+	bool above;
+	int error;
+
+	error = secmodel_eval("org.netbsd.secmodel.securelevel",
+	    "is-securelevel-above", KAUTH_ARG(level), &above);
+	return error == 0 && above;
+}
+
 /*
  * Set d's packet filter program to fp.  If this file already has a filter,
  * free it and replace it.  Returns EINVAL for bogus requests.
@@ -1116,7 +1128,7 @@ bpf_setf(struct bpf_d *d, struct bpf_pro
 			return EINVAL;
 		}
 		membar_consumer();
-		if (bpf_jit)
+		if (bpf_jit && !is_securelevel_above(0))
 			jcode = bpf_jit_generate(NULL, fcode, flen);
 	} else {
 		fcode = NULL;
@@ -1941,6 +1953,9 @@ sysctl_net_bpf_jit(SYSCTLFN_ARGS)
 	if (error != 0 || newp == NULL)
 		return error;
 
+	if (newval && is_securelevel_above(0))
+		return EPERM;
+
 	bpf_jit = newval;
 
 	/*


Home | Main Index | Thread Index | Old Index