Christos Zoulas wrote:
> On Jan 1,  6:21pm, [email protected] (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;
 
        /*

Reply via email to