]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
bpf: add map_alloc_check callback
authorJakub Kicinski <jakub.kicinski@netronome.com>
Fri, 12 Jan 2018 04:29:03 +0000 (20:29 -0800)
committerStefan Bader <stefan.bader@canonical.com>
Mon, 1 Oct 2018 12:58:00 +0000 (14:58 +0200)
BugLink: http://bugs.launchpad.net/bugs/1794889
.map_alloc callbacks contain a number of checks validating user-
-provided map attributes against constraints of a particular map
type.  For offloaded maps we will need to check map attributes
without actually allocating any memory on the host.  Add a new
callback for validating attributes before any memory is allocated.
This callback can be selectively implemented by map types for
sharing code with offloads, or simply to separate the logical
steps of validation and allocation.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
(cherry picked from commit 1110f3a9bcf394c06b81a98206aee9b6860653c8)
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
include/linux/bpf.h
kernel/bpf/syscall.c

index 0b25cf87b6d608b6a1646e89e1408270f148a783..c250fefe9cae7e5abc9069b04f43fe3451d585f8 100644 (file)
@@ -24,6 +24,7 @@ struct bpf_map;
 /* map is generic key/value storage optionally accesible by eBPF programs */
 struct bpf_map_ops {
        /* funcs callable from userspace (via syscall) */
+       int (*map_alloc_check)(union bpf_attr *attr);
        struct bpf_map *(*map_alloc)(union bpf_attr *attr);
        void (*map_release)(struct bpf_map *map, struct file *map_file);
        void (*map_free)(struct bpf_map *map);
index b719351b48d2e8cca92242985ce795dc16193be0..4e5624a56fd28b5f32dc544a70c4bd22ffe3b0cc 100644 (file)
@@ -96,16 +96,25 @@ static int check_uarg_tail_zero(void __user *uaddr,
 
 static struct bpf_map *find_and_alloc_map(union bpf_attr *attr)
 {
+       const struct bpf_map_ops *ops;
        struct bpf_map *map;
+       int err;
 
-       if (attr->map_type >= ARRAY_SIZE(bpf_map_types) ||
-           !bpf_map_types[attr->map_type])
+       if (attr->map_type >= ARRAY_SIZE(bpf_map_types))
+               return ERR_PTR(-EINVAL);
+       ops = bpf_map_types[attr->map_type];
+       if (!ops)
                return ERR_PTR(-EINVAL);
 
-       map = bpf_map_types[attr->map_type]->map_alloc(attr);
+       if (ops->map_alloc_check) {
+               err = ops->map_alloc_check(attr);
+               if (err)
+                       return ERR_PTR(err);
+       }
+       map = ops->map_alloc(attr);
        if (IS_ERR(map))
                return map;
-       map->ops = bpf_map_types[attr->map_type];
+       map->ops = ops;
        map->map_type = attr->map_type;
        return map;
 }