]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - kernel/bpf/core.c
Merge remote-tracking branch 'rdma/for-next'
[karo-tx-linux.git] / kernel / bpf / core.c
index 67c380cfa9ca5b6ed8e48b69b38ba3c611d51a65..334b1bdd572c1e66007bd7163c9b98ee9c37deb5 100644 (file)
@@ -82,6 +82,8 @@ struct bpf_prog *bpf_prog_alloc(unsigned int size, gfp_t gfp_extra_flags)
        if (fp == NULL)
                return NULL;
 
+       kmemcheck_annotate_bitfield(fp, meta);
+
        aux = kzalloc(sizeof(*aux), GFP_KERNEL | gfp_extra_flags);
        if (aux == NULL) {
                vfree(fp);
@@ -90,6 +92,7 @@ struct bpf_prog *bpf_prog_alloc(unsigned int size, gfp_t gfp_extra_flags)
 
        fp->pages = size / PAGE_SIZE;
        fp->aux = aux;
+       fp->aux->prog = fp;
 
        return fp;
 }
@@ -110,8 +113,11 @@ struct bpf_prog *bpf_prog_realloc(struct bpf_prog *fp_old, unsigned int size,
 
        fp = __vmalloc(size, gfp_flags, PAGE_KERNEL);
        if (fp != NULL) {
+               kmemcheck_annotate_bitfield(fp, meta);
+
                memcpy(fp, fp_old, fp_old->pages * PAGE_SIZE);
                fp->pages = size / PAGE_SIZE;
+               fp->aux->prog = fp;
 
                /* We keep fp->aux from fp_old around in the new
                 * reallocated structure.
@@ -722,11 +728,36 @@ void bpf_prog_free(struct bpf_prog *fp)
        struct bpf_prog_aux *aux = fp->aux;
 
        INIT_WORK(&aux->work, bpf_prog_free_deferred);
-       aux->prog = fp;
        schedule_work(&aux->work);
 }
 EXPORT_SYMBOL_GPL(bpf_prog_free);
 
+/* RNG for unpriviledged user space with separated state from prandom_u32(). */
+static DEFINE_PER_CPU(struct rnd_state, bpf_user_rnd_state);
+
+void bpf_user_rnd_init_once(void)
+{
+       prandom_init_once(&bpf_user_rnd_state);
+}
+
+u64 bpf_user_rnd_u32(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5)
+{
+       /* Should someone ever have the rather unwise idea to use some
+        * of the registers passed into this function, then note that
+        * this function is called from native eBPF and classic-to-eBPF
+        * transformations. Register assignments from both sides are
+        * different, f.e. classic always sets fn(ctx, A, X) here.
+        */
+       struct rnd_state *state;
+       u32 res;
+
+       state = &get_cpu_var(bpf_user_rnd_state);
+       res = prandom_u32_state(state);
+       put_cpu_var(state);
+
+       return res;
+}
+
 /* Weak definitions of helper functions in case we don't have bpf syscall. */
 const struct bpf_func_proto bpf_map_lookup_elem_proto __weak;
 const struct bpf_func_proto bpf_map_update_elem_proto __weak;