batman-adv: iv_ogm_send_to_if, declare char* as const
[deliverable/linux.git] / net / core / filter.c
index bf831a85c315905896496c3eb537c0e7c6d15d4b..3adcca6f17a42c538c4a5edfa256ec4a1c162593 100644 (file)
@@ -36,6 +36,7 @@
 #include <net/netlink.h>
 #include <linux/skbuff.h>
 #include <net/sock.h>
+#include <net/flow_dissector.h>
 #include <linux/errno.h>
 #include <linux/timer.h>
 #include <asm/uaccess.h>
@@ -355,8 +356,8 @@ static bool convert_bpf_extensions(struct sock_filter *fp,
  * for socket filters: ctx == 'struct sk_buff *', for seccomp:
  * ctx == 'struct seccomp_data *'.
  */
-int bpf_convert_filter(struct sock_filter *prog, int len,
-                      struct bpf_insn *new_prog, int *new_len)
+static int bpf_convert_filter(struct sock_filter *prog, int len,
+                             struct bpf_insn *new_prog, int *new_len)
 {
        int new_flen = 0, pass = 0, target, i;
        struct bpf_insn *new_insn;
@@ -371,7 +372,8 @@ int bpf_convert_filter(struct sock_filter *prog, int len,
                return -EINVAL;
 
        if (new_prog) {
-               addrs = kcalloc(len, sizeof(*addrs), GFP_KERNEL);
+               addrs = kcalloc(len, sizeof(*addrs),
+                               GFP_KERNEL | __GFP_NOWARN);
                if (!addrs)
                        return -ENOMEM;
        }
@@ -751,7 +753,8 @@ static bool chk_code_allowed(u16 code_to_probe)
  *
  * Returns 0 if the rule set is legal or -EINVAL if not.
  */
-int bpf_check_classic(const struct sock_filter *filter, unsigned int flen)
+static int bpf_check_classic(const struct sock_filter *filter,
+                            unsigned int flen)
 {
        bool anc_found;
        int pc;
@@ -825,7 +828,6 @@ int bpf_check_classic(const struct sock_filter *filter, unsigned int flen)
 
        return -EINVAL;
 }
-EXPORT_SYMBOL(bpf_check_classic);
 
 static int bpf_prog_store_orig_filter(struct bpf_prog *fp,
                                      const struct sock_fprog *fprog)
@@ -839,7 +841,9 @@ static int bpf_prog_store_orig_filter(struct bpf_prog *fp,
 
        fkprog = fp->orig_prog;
        fkprog->len = fprog->len;
-       fkprog->filter = kmemdup(fp->insns, fsize, GFP_KERNEL);
+
+       fkprog->filter = kmemdup(fp->insns, fsize,
+                                GFP_KERNEL | __GFP_NOWARN);
        if (!fkprog->filter) {
                kfree(fp->orig_prog);
                return -ENOMEM;
@@ -941,7 +945,7 @@ static struct bpf_prog *bpf_migrate_filter(struct bpf_prog *fp)
         * pass. At this time, the user BPF is stored in fp->insns.
         */
        old_prog = kmemdup(fp->insns, old_len * sizeof(struct sock_filter),
-                          GFP_KERNEL);
+                          GFP_KERNEL | __GFP_NOWARN);
        if (!old_prog) {
                err = -ENOMEM;
                goto out_err;
@@ -988,7 +992,8 @@ out_err:
        return ERR_PTR(err);
 }
 
-static struct bpf_prog *bpf_prepare_filter(struct bpf_prog *fp)
+static struct bpf_prog *bpf_prepare_filter(struct bpf_prog *fp,
+                                          bpf_aux_classic_check_t trans)
 {
        int err;
 
@@ -1001,6 +1006,17 @@ static struct bpf_prog *bpf_prepare_filter(struct bpf_prog *fp)
                return ERR_PTR(err);
        }
 
+       /* There might be additional checks and transformations
+        * needed on classic filters, f.e. in case of seccomp.
+        */
+       if (trans) {
+               err = trans(fp->insns, fp->len);
+               if (err) {
+                       __bpf_prog_release(fp);
+                       return ERR_PTR(err);
+               }
+       }
+
        /* Probe if we can JIT compile the filter and if so, do
         * the compilation of the filter.
         */
@@ -1050,7 +1066,7 @@ int bpf_prog_create(struct bpf_prog **pfp, struct sock_fprog_kern *fprog)
        /* bpf_prepare_filter() already takes care of freeing
         * memory in case something goes wrong.
         */
-       fp = bpf_prepare_filter(fp);
+       fp = bpf_prepare_filter(fp, NULL);
        if (IS_ERR(fp))
                return PTR_ERR(fp);
 
@@ -1059,6 +1075,53 @@ int bpf_prog_create(struct bpf_prog **pfp, struct sock_fprog_kern *fprog)
 }
 EXPORT_SYMBOL_GPL(bpf_prog_create);
 
+/**
+ *     bpf_prog_create_from_user - create an unattached filter from user buffer
+ *     @pfp: the unattached filter that is created
+ *     @fprog: the filter program
+ *     @trans: post-classic verifier transformation handler
+ *
+ * This function effectively does the same as bpf_prog_create(), only
+ * that it builds up its insns buffer from user space provided buffer.
+ * It also allows for passing a bpf_aux_classic_check_t handler.
+ */
+int bpf_prog_create_from_user(struct bpf_prog **pfp, struct sock_fprog *fprog,
+                             bpf_aux_classic_check_t trans)
+{
+       unsigned int fsize = bpf_classic_proglen(fprog);
+       struct bpf_prog *fp;
+
+       /* Make sure new filter is there and in the right amounts. */
+       if (fprog->filter == NULL)
+               return -EINVAL;
+
+       fp = bpf_prog_alloc(bpf_prog_size(fprog->len), 0);
+       if (!fp)
+               return -ENOMEM;
+
+       if (copy_from_user(fp->insns, fprog->filter, fsize)) {
+               __bpf_prog_free(fp);
+               return -EFAULT;
+       }
+
+       fp->len = fprog->len;
+       /* Since unattached filters are not copied back to user
+        * space through sk_get_filter(), we do not need to hold
+        * a copy here, and can spare us the work.
+        */
+       fp->orig_prog = NULL;
+
+       /* bpf_prepare_filter() already takes care of freeing
+        * memory in case something goes wrong.
+        */
+       fp = bpf_prepare_filter(fp, trans);
+       if (IS_ERR(fp))
+               return PTR_ERR(fp);
+
+       *pfp = fp;
+       return 0;
+}
+
 void bpf_prog_destroy(struct bpf_prog *fp)
 {
        __bpf_prog_release(fp);
@@ -1135,7 +1198,7 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
        /* bpf_prepare_filter() already takes care of freeing
         * memory in case something goes wrong.
         */
-       prog = bpf_prepare_filter(prog);
+       prog = bpf_prepare_filter(prog, NULL);
        if (IS_ERR(prog))
                return PTR_ERR(prog);
 
@@ -1358,6 +1421,8 @@ sk_filter_func_proto(enum bpf_func_id func_id)
                return &bpf_get_prandom_u32_proto;
        case BPF_FUNC_get_smp_processor_id:
                return &bpf_get_smp_processor_id_proto;
+       case BPF_FUNC_tail_call:
+               return &bpf_tail_call_proto;
        default:
                return NULL;
        }
This page took 0.028232 seconds and 5 git commands to generate.