diff options
Diffstat (limited to 'kernel/bpf/syscall.c')
-rw-r--r-- | kernel/bpf/syscall.c | 23 |
1 files changed, 12 insertions, 11 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 8e9d065bb7cd..38da55905ab0 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c | |||
@@ -1057,22 +1057,23 @@ struct bpf_prog *bpf_prog_inc_not_zero(struct bpf_prog *prog) | |||
1057 | } | 1057 | } |
1058 | EXPORT_SYMBOL_GPL(bpf_prog_inc_not_zero); | 1058 | EXPORT_SYMBOL_GPL(bpf_prog_inc_not_zero); |
1059 | 1059 | ||
1060 | static bool bpf_prog_can_attach(struct bpf_prog *prog, | 1060 | static bool bpf_prog_get_ok(struct bpf_prog *prog, |
1061 | enum bpf_prog_type *attach_type, | 1061 | enum bpf_prog_type *attach_type, bool attach_drv) |
1062 | struct net_device *netdev) | ||
1063 | { | 1062 | { |
1064 | struct bpf_dev_offload *offload = prog->aux->offload; | 1063 | /* not an attachment, just a refcount inc, always allow */ |
1064 | if (!attach_type) | ||
1065 | return true; | ||
1065 | 1066 | ||
1066 | if (prog->type != *attach_type) | 1067 | if (prog->type != *attach_type) |
1067 | return false; | 1068 | return false; |
1068 | if (offload && offload->netdev != netdev) | 1069 | if (bpf_prog_is_dev_bound(prog->aux) && !attach_drv) |
1069 | return false; | 1070 | return false; |
1070 | 1071 | ||
1071 | return true; | 1072 | return true; |
1072 | } | 1073 | } |
1073 | 1074 | ||
1074 | static struct bpf_prog *__bpf_prog_get(u32 ufd, enum bpf_prog_type *attach_type, | 1075 | static struct bpf_prog *__bpf_prog_get(u32 ufd, enum bpf_prog_type *attach_type, |
1075 | struct net_device *netdev) | 1076 | bool attach_drv) |
1076 | { | 1077 | { |
1077 | struct fd f = fdget(ufd); | 1078 | struct fd f = fdget(ufd); |
1078 | struct bpf_prog *prog; | 1079 | struct bpf_prog *prog; |
@@ -1080,7 +1081,7 @@ static struct bpf_prog *__bpf_prog_get(u32 ufd, enum bpf_prog_type *attach_type, | |||
1080 | prog = ____bpf_prog_get(f); | 1081 | prog = ____bpf_prog_get(f); |
1081 | if (IS_ERR(prog)) | 1082 | if (IS_ERR(prog)) |
1082 | return prog; | 1083 | return prog; |
1083 | if (attach_type && !bpf_prog_can_attach(prog, attach_type, netdev)) { | 1084 | if (!bpf_prog_get_ok(prog, attach_type, attach_drv)) { |
1084 | prog = ERR_PTR(-EINVAL); | 1085 | prog = ERR_PTR(-EINVAL); |
1085 | goto out; | 1086 | goto out; |
1086 | } | 1087 | } |
@@ -1093,12 +1094,12 @@ out: | |||
1093 | 1094 | ||
1094 | struct bpf_prog *bpf_prog_get(u32 ufd) | 1095 | struct bpf_prog *bpf_prog_get(u32 ufd) |
1095 | { | 1096 | { |
1096 | return __bpf_prog_get(ufd, NULL, NULL); | 1097 | return __bpf_prog_get(ufd, NULL, false); |
1097 | } | 1098 | } |
1098 | 1099 | ||
1099 | struct bpf_prog *bpf_prog_get_type(u32 ufd, enum bpf_prog_type type) | 1100 | struct bpf_prog *bpf_prog_get_type(u32 ufd, enum bpf_prog_type type) |
1100 | { | 1101 | { |
1101 | struct bpf_prog *prog = __bpf_prog_get(ufd, &type, NULL); | 1102 | struct bpf_prog *prog = __bpf_prog_get(ufd, &type, false); |
1102 | 1103 | ||
1103 | if (!IS_ERR(prog)) | 1104 | if (!IS_ERR(prog)) |
1104 | trace_bpf_prog_get_type(prog); | 1105 | trace_bpf_prog_get_type(prog); |
@@ -1107,9 +1108,9 @@ struct bpf_prog *bpf_prog_get_type(u32 ufd, enum bpf_prog_type type) | |||
1107 | EXPORT_SYMBOL_GPL(bpf_prog_get_type); | 1108 | EXPORT_SYMBOL_GPL(bpf_prog_get_type); |
1108 | 1109 | ||
1109 | struct bpf_prog *bpf_prog_get_type_dev(u32 ufd, enum bpf_prog_type type, | 1110 | struct bpf_prog *bpf_prog_get_type_dev(u32 ufd, enum bpf_prog_type type, |
1110 | struct net_device *netdev) | 1111 | bool attach_drv) |
1111 | { | 1112 | { |
1112 | struct bpf_prog *prog = __bpf_prog_get(ufd, &type, netdev); | 1113 | struct bpf_prog *prog = __bpf_prog_get(ufd, &type, attach_drv); |
1113 | 1114 | ||
1114 | if (!IS_ERR(prog)) | 1115 | if (!IS_ERR(prog)) |
1115 | trace_bpf_prog_get_type(prog); | 1116 | trace_bpf_prog_get_type(prog); |