|
@@ -1438,9 +1438,37 @@ bpf_object__load_progs(struct bpf_object *obj)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int bpf_object__validate(struct bpf_object *obj)
|
|
|
+static bool bpf_prog_type__needs_kver(enum bpf_prog_type type)
|
|
|
+{
|
|
|
+ switch (type) {
|
|
|
+ case BPF_PROG_TYPE_SOCKET_FILTER:
|
|
|
+ case BPF_PROG_TYPE_SCHED_CLS:
|
|
|
+ case BPF_PROG_TYPE_SCHED_ACT:
|
|
|
+ case BPF_PROG_TYPE_XDP:
|
|
|
+ case BPF_PROG_TYPE_CGROUP_SKB:
|
|
|
+ case BPF_PROG_TYPE_CGROUP_SOCK:
|
|
|
+ case BPF_PROG_TYPE_LWT_IN:
|
|
|
+ case BPF_PROG_TYPE_LWT_OUT:
|
|
|
+ case BPF_PROG_TYPE_LWT_XMIT:
|
|
|
+ case BPF_PROG_TYPE_SOCK_OPS:
|
|
|
+ case BPF_PROG_TYPE_SK_SKB:
|
|
|
+ case BPF_PROG_TYPE_CGROUP_DEVICE:
|
|
|
+ case BPF_PROG_TYPE_SK_MSG:
|
|
|
+ case BPF_PROG_TYPE_CGROUP_SOCK_ADDR:
|
|
|
+ return false;
|
|
|
+ case BPF_PROG_TYPE_UNSPEC:
|
|
|
+ case BPF_PROG_TYPE_KPROBE:
|
|
|
+ case BPF_PROG_TYPE_TRACEPOINT:
|
|
|
+ case BPF_PROG_TYPE_PERF_EVENT:
|
|
|
+ case BPF_PROG_TYPE_RAW_TRACEPOINT:
|
|
|
+ default:
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static int bpf_object__validate(struct bpf_object *obj, bool needs_kver)
|
|
|
{
|
|
|
- if (obj->kern_version == 0) {
|
|
|
+ if (needs_kver && obj->kern_version == 0) {
|
|
|
pr_warning("%s doesn't provide kernel version\n",
|
|
|
obj->path);
|
|
|
return -LIBBPF_ERRNO__KVERSION;
|
|
@@ -1449,7 +1477,8 @@ static int bpf_object__validate(struct bpf_object *obj)
|
|
|
}
|
|
|
|
|
|
static struct bpf_object *
|
|
|
-__bpf_object__open(const char *path, void *obj_buf, size_t obj_buf_sz)
|
|
|
+__bpf_object__open(const char *path, void *obj_buf, size_t obj_buf_sz,
|
|
|
+ bool needs_kver)
|
|
|
{
|
|
|
struct bpf_object *obj;
|
|
|
int err;
|
|
@@ -1467,7 +1496,7 @@ __bpf_object__open(const char *path, void *obj_buf, size_t obj_buf_sz)
|
|
|
CHECK_ERR(bpf_object__check_endianness(obj), err, out);
|
|
|
CHECK_ERR(bpf_object__elf_collect(obj), err, out);
|
|
|
CHECK_ERR(bpf_object__collect_reloc(obj), err, out);
|
|
|
- CHECK_ERR(bpf_object__validate(obj), err, out);
|
|
|
+ CHECK_ERR(bpf_object__validate(obj, needs_kver), err, out);
|
|
|
|
|
|
bpf_object__elf_finish(obj);
|
|
|
return obj;
|
|
@@ -1484,7 +1513,7 @@ struct bpf_object *bpf_object__open(const char *path)
|
|
|
|
|
|
pr_debug("loading %s\n", path);
|
|
|
|
|
|
- return __bpf_object__open(path, NULL, 0);
|
|
|
+ return __bpf_object__open(path, NULL, 0, true);
|
|
|
}
|
|
|
|
|
|
struct bpf_object *bpf_object__open_buffer(void *obj_buf,
|
|
@@ -1507,7 +1536,7 @@ struct bpf_object *bpf_object__open_buffer(void *obj_buf,
|
|
|
pr_debug("loading object '%s' from buffer\n",
|
|
|
name);
|
|
|
|
|
|
- return __bpf_object__open(name, obj_buf, obj_buf_sz);
|
|
|
+ return __bpf_object__open(name, obj_buf, obj_buf_sz, true);
|
|
|
}
|
|
|
|
|
|
int bpf_object__unload(struct bpf_object *obj)
|
|
@@ -2164,8 +2193,11 @@ int bpf_prog_load_xattr(const struct bpf_prog_load_attr *attr,
|
|
|
|
|
|
if (!attr)
|
|
|
return -EINVAL;
|
|
|
+ if (!attr->file)
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
- obj = bpf_object__open(attr->file);
|
|
|
+ obj = __bpf_object__open(attr->file, NULL, 0,
|
|
|
+ bpf_prog_type__needs_kver(attr->prog_type));
|
|
|
if (IS_ERR(obj))
|
|
|
return -ENOENT;
|
|
|
|