aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Ignatov <rdna@fb.com>2018-03-30 18:08:00 -0400
committerDaniel Borkmann <daniel@iogearbox.net>2018-03-30 20:14:44 -0400
commit5e43f899b03a3492ce5fc44e8900becb04dae9c0 (patch)
tree2811b77402c54e99a10a74f8a1b092b4bc2e24f6
parent807ae7daf5fb9ba9ef688344ae7c0d8cbebd211c (diff)
bpf: Check attach type at prog load time
== The problem == There are use-cases when a program of some type can be attached to multiple attach points and those attach points must have different permissions to access context or to call helpers. E.g. context structure may have fields for both IPv4 and IPv6 but it doesn't make sense to read from / write to IPv6 field when attach point is somewhere in IPv4 stack. Same applies to BPF-helpers: it may make sense to call some helper from some attach point, but not from other for same prog type. == The solution == Introduce `expected_attach_type` field in in `struct bpf_attr` for `BPF_PROG_LOAD` command. If scenario described in "The problem" section is the case for some prog type, the field will be checked twice: 1) At load time prog type is checked to see if attach type for it must be known to validate program permissions correctly. Prog will be rejected with EINVAL if it's the case and `expected_attach_type` is not specified or has invalid value. 2) At attach time `attach_type` is compared with `expected_attach_type`, if prog type requires to have one, and, if they differ, attach will be rejected with EINVAL. The `expected_attach_type` is now available as part of `struct bpf_prog` in both `bpf_verifier_ops->is_valid_access()` and `bpf_verifier_ops->get_func_proto()` () and can be used to check context accesses and calls to helpers correspondingly. Initially the idea was discussed by Alexei Starovoitov <ast@fb.com> and Daniel Borkmann <daniel@iogearbox.net> here: https://marc.info/?l=linux-netdev&m=152107378717201&w=2 Signed-off-by: Andrey Ignatov <rdna@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
-rw-r--r--include/linux/bpf.h5
-rw-r--r--include/linux/filter.h1
-rw-r--r--include/uapi/linux/bpf.h5
-rw-r--r--kernel/bpf/cgroup.c3
-rw-r--r--kernel/bpf/syscall.c31
-rw-r--r--kernel/bpf/verifier.c6
-rw-r--r--kernel/trace/bpf_trace.c27
-rw-r--r--net/core/filter.c39
8 files changed, 88 insertions, 29 deletions
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 819229c80eca..95a7abd0ee92 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -208,12 +208,15 @@ struct bpf_prog_ops {
208 208
209struct bpf_verifier_ops { 209struct bpf_verifier_ops {
210 /* return eBPF function prototype for verification */ 210 /* return eBPF function prototype for verification */
211 const struct bpf_func_proto *(*get_func_proto)(enum bpf_func_id func_id); 211 const struct bpf_func_proto *
212 (*get_func_proto)(enum bpf_func_id func_id,
213 const struct bpf_prog *prog);
212 214
213 /* return true if 'size' wide access at offset 'off' within bpf_context 215 /* return true if 'size' wide access at offset 'off' within bpf_context
214 * with 'type' (read or write) is allowed 216 * with 'type' (read or write) is allowed
215 */ 217 */
216 bool (*is_valid_access)(int off, int size, enum bpf_access_type type, 218 bool (*is_valid_access)(int off, int size, enum bpf_access_type type,
219 const struct bpf_prog *prog,
217 struct bpf_insn_access_aux *info); 220 struct bpf_insn_access_aux *info);
218 int (*gen_prologue)(struct bpf_insn *insn, bool direct_write, 221 int (*gen_prologue)(struct bpf_insn *insn, bool direct_write,
219 const struct bpf_prog *prog); 222 const struct bpf_prog *prog);
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 897ff3d95968..13c044e4832d 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -469,6 +469,7 @@ struct bpf_prog {
469 is_func:1, /* program is a bpf function */ 469 is_func:1, /* program is a bpf function */
470 kprobe_override:1; /* Do we override a kprobe? */ 470 kprobe_override:1; /* Do we override a kprobe? */
471 enum bpf_prog_type type; /* Type of BPF program */ 471 enum bpf_prog_type type; /* Type of BPF program */
472 enum bpf_attach_type expected_attach_type; /* For some prog types */
472 u32 len; /* Number of filter blocks */ 473 u32 len; /* Number of filter blocks */
473 u32 jited_len; /* Size of jited insns in bytes */ 474 u32 jited_len; /* Size of jited insns in bytes */
474 u8 tag[BPF_TAG_SIZE]; 475 u8 tag[BPF_TAG_SIZE];
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 1878201c2d77..102718624d1e 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -296,6 +296,11 @@ union bpf_attr {
296 __u32 prog_flags; 296 __u32 prog_flags;
297 char prog_name[BPF_OBJ_NAME_LEN]; 297 char prog_name[BPF_OBJ_NAME_LEN];
298 __u32 prog_ifindex; /* ifindex of netdev to prep for */ 298 __u32 prog_ifindex; /* ifindex of netdev to prep for */
299 /* For some prog types expected attach type must be known at
300 * load time to verify attach type specific parts of prog
301 * (context accesses, allowed helpers, etc).
302 */
303 __u32 expected_attach_type;
299 }; 304 };
300 305
301 struct { /* anonymous struct used by BPF_OBJ_* commands */ 306 struct { /* anonymous struct used by BPF_OBJ_* commands */
diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
index c1c0b60d3f2f..8730b24ed540 100644
--- a/kernel/bpf/cgroup.c
+++ b/kernel/bpf/cgroup.c
@@ -545,7 +545,7 @@ int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor,
545EXPORT_SYMBOL(__cgroup_bpf_check_dev_permission); 545EXPORT_SYMBOL(__cgroup_bpf_check_dev_permission);
546 546
547static const struct bpf_func_proto * 547static const struct bpf_func_proto *
548cgroup_dev_func_proto(enum bpf_func_id func_id) 548cgroup_dev_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
549{ 549{
550 switch (func_id) { 550 switch (func_id) {
551 case BPF_FUNC_map_lookup_elem: 551 case BPF_FUNC_map_lookup_elem:
@@ -566,6 +566,7 @@ cgroup_dev_func_proto(enum bpf_func_id func_id)
566 566
567static bool cgroup_dev_is_valid_access(int off, int size, 567static bool cgroup_dev_is_valid_access(int off, int size,
568 enum bpf_access_type type, 568 enum bpf_access_type type,
569 const struct bpf_prog *prog,
569 struct bpf_insn_access_aux *info) 570 struct bpf_insn_access_aux *info)
570{ 571{
571 const int size_default = sizeof(__u32); 572 const int size_default = sizeof(__u32);
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 95ca2523fa6e..9d3b572d4dec 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -1171,8 +1171,27 @@ struct bpf_prog *bpf_prog_get_type_dev(u32 ufd, enum bpf_prog_type type,
1171} 1171}
1172EXPORT_SYMBOL_GPL(bpf_prog_get_type_dev); 1172EXPORT_SYMBOL_GPL(bpf_prog_get_type_dev);
1173 1173
1174static int
1175bpf_prog_load_check_attach_type(enum bpf_prog_type prog_type,
1176 enum bpf_attach_type expected_attach_type)
1177{
1178 /* There are currently no prog types that require specifying
1179 * attach_type at load time.
1180 */
1181 return 0;
1182}
1183
1184static int bpf_prog_attach_check_attach_type(const struct bpf_prog *prog,
1185 enum bpf_attach_type attach_type)
1186{
1187 /* There are currently no prog types that require specifying
1188 * attach_type at load time.
1189 */
1190 return 0;
1191}
1192
1174/* last field in 'union bpf_attr' used by this command */ 1193/* last field in 'union bpf_attr' used by this command */
1175#define BPF_PROG_LOAD_LAST_FIELD prog_ifindex 1194#define BPF_PROG_LOAD_LAST_FIELD expected_attach_type
1176 1195
1177static int bpf_prog_load(union bpf_attr *attr) 1196static int bpf_prog_load(union bpf_attr *attr)
1178{ 1197{
@@ -1209,11 +1228,16 @@ static int bpf_prog_load(union bpf_attr *attr)
1209 !capable(CAP_SYS_ADMIN)) 1228 !capable(CAP_SYS_ADMIN))
1210 return -EPERM; 1229 return -EPERM;
1211 1230
1231 if (bpf_prog_load_check_attach_type(type, attr->expected_attach_type))
1232 return -EINVAL;
1233
1212 /* plain bpf_prog allocation */ 1234 /* plain bpf_prog allocation */
1213 prog = bpf_prog_alloc(bpf_prog_size(attr->insn_cnt), GFP_USER); 1235 prog = bpf_prog_alloc(bpf_prog_size(attr->insn_cnt), GFP_USER);
1214 if (!prog) 1236 if (!prog)
1215 return -ENOMEM; 1237 return -ENOMEM;
1216 1238
1239 prog->expected_attach_type = attr->expected_attach_type;
1240
1217 prog->aux->offload_requested = !!attr->prog_ifindex; 1241 prog->aux->offload_requested = !!attr->prog_ifindex;
1218 1242
1219 err = security_bpf_prog_alloc(prog->aux); 1243 err = security_bpf_prog_alloc(prog->aux);
@@ -1474,6 +1498,11 @@ static int bpf_prog_attach(const union bpf_attr *attr)
1474 if (IS_ERR(prog)) 1498 if (IS_ERR(prog))
1475 return PTR_ERR(prog); 1499 return PTR_ERR(prog);
1476 1500
1501 if (bpf_prog_attach_check_attach_type(prog, attr->attach_type)) {
1502 bpf_prog_put(prog);
1503 return -EINVAL;
1504 }
1505
1477 cgrp = cgroup_get_from_fd(attr->target_fd); 1506 cgrp = cgroup_get_from_fd(attr->target_fd);
1478 if (IS_ERR(cgrp)) { 1507 if (IS_ERR(cgrp)) {
1479 bpf_prog_put(prog); 1508 bpf_prog_put(prog);
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 8acd2207e412..10024323031d 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -1323,7 +1323,7 @@ static int check_ctx_access(struct bpf_verifier_env *env, int insn_idx, int off,
1323 }; 1323 };
1324 1324
1325 if (env->ops->is_valid_access && 1325 if (env->ops->is_valid_access &&
1326 env->ops->is_valid_access(off, size, t, &info)) { 1326 env->ops->is_valid_access(off, size, t, env->prog, &info)) {
1327 /* A non zero info.ctx_field_size indicates that this field is a 1327 /* A non zero info.ctx_field_size indicates that this field is a
1328 * candidate for later verifier transformation to load the whole 1328 * candidate for later verifier transformation to load the whole
1329 * field and then apply a mask when accessed with a narrower 1329 * field and then apply a mask when accessed with a narrower
@@ -2349,7 +2349,7 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
2349 } 2349 }
2350 2350
2351 if (env->ops->get_func_proto) 2351 if (env->ops->get_func_proto)
2352 fn = env->ops->get_func_proto(func_id); 2352 fn = env->ops->get_func_proto(func_id, env->prog);
2353 if (!fn) { 2353 if (!fn) {
2354 verbose(env, "unknown func %s#%d\n", func_id_name(func_id), 2354 verbose(env, "unknown func %s#%d\n", func_id_name(func_id),
2355 func_id); 2355 func_id);
@@ -5572,7 +5572,7 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
5572 insn = new_prog->insnsi + i + delta; 5572 insn = new_prog->insnsi + i + delta;
5573 } 5573 }
5574patch_call_imm: 5574patch_call_imm:
5575 fn = env->ops->get_func_proto(insn->imm); 5575 fn = env->ops->get_func_proto(insn->imm, env->prog);
5576 /* all functions that have prototype and verifier allowed 5576 /* all functions that have prototype and verifier allowed
5577 * programs to call them, must be real in-kernel functions 5577 * programs to call them, must be real in-kernel functions
5578 */ 5578 */
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 463e72d18c4c..d88e96d4e12c 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -524,7 +524,8 @@ static const struct bpf_func_proto bpf_probe_read_str_proto = {
524 .arg3_type = ARG_ANYTHING, 524 .arg3_type = ARG_ANYTHING,
525}; 525};
526 526
527static const struct bpf_func_proto *tracing_func_proto(enum bpf_func_id func_id) 527static const struct bpf_func_proto *
528tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
528{ 529{
529 switch (func_id) { 530 switch (func_id) {
530 case BPF_FUNC_map_lookup_elem: 531 case BPF_FUNC_map_lookup_elem:
@@ -568,7 +569,8 @@ static const struct bpf_func_proto *tracing_func_proto(enum bpf_func_id func_id)
568 } 569 }
569} 570}
570 571
571static const struct bpf_func_proto *kprobe_prog_func_proto(enum bpf_func_id func_id) 572static const struct bpf_func_proto *
573kprobe_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
572{ 574{
573 switch (func_id) { 575 switch (func_id) {
574 case BPF_FUNC_perf_event_output: 576 case BPF_FUNC_perf_event_output:
@@ -582,12 +584,13 @@ static const struct bpf_func_proto *kprobe_prog_func_proto(enum bpf_func_id func
582 return &bpf_override_return_proto; 584 return &bpf_override_return_proto;
583#endif 585#endif
584 default: 586 default:
585 return tracing_func_proto(func_id); 587 return tracing_func_proto(func_id, prog);
586 } 588 }
587} 589}
588 590
589/* bpf+kprobe programs can access fields of 'struct pt_regs' */ 591/* bpf+kprobe programs can access fields of 'struct pt_regs' */
590static bool kprobe_prog_is_valid_access(int off, int size, enum bpf_access_type type, 592static bool kprobe_prog_is_valid_access(int off, int size, enum bpf_access_type type,
593 const struct bpf_prog *prog,
591 struct bpf_insn_access_aux *info) 594 struct bpf_insn_access_aux *info)
592{ 595{
593 if (off < 0 || off >= sizeof(struct pt_regs)) 596 if (off < 0 || off >= sizeof(struct pt_regs))
@@ -661,7 +664,8 @@ static const struct bpf_func_proto bpf_get_stackid_proto_tp = {
661 .arg3_type = ARG_ANYTHING, 664 .arg3_type = ARG_ANYTHING,
662}; 665};
663 666
664static const struct bpf_func_proto *tp_prog_func_proto(enum bpf_func_id func_id) 667static const struct bpf_func_proto *
668tp_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
665{ 669{
666 switch (func_id) { 670 switch (func_id) {
667 case BPF_FUNC_perf_event_output: 671 case BPF_FUNC_perf_event_output:
@@ -669,11 +673,12 @@ static const struct bpf_func_proto *tp_prog_func_proto(enum bpf_func_id func_id)
669 case BPF_FUNC_get_stackid: 673 case BPF_FUNC_get_stackid:
670 return &bpf_get_stackid_proto_tp; 674 return &bpf_get_stackid_proto_tp;
671 default: 675 default:
672 return tracing_func_proto(func_id); 676 return tracing_func_proto(func_id, prog);
673 } 677 }
674} 678}
675 679
676static bool tp_prog_is_valid_access(int off, int size, enum bpf_access_type type, 680static bool tp_prog_is_valid_access(int off, int size, enum bpf_access_type type,
681 const struct bpf_prog *prog,
677 struct bpf_insn_access_aux *info) 682 struct bpf_insn_access_aux *info)
678{ 683{
679 if (off < sizeof(void *) || off >= PERF_MAX_TRACE_SIZE) 684 if (off < sizeof(void *) || off >= PERF_MAX_TRACE_SIZE)
@@ -721,7 +726,8 @@ static const struct bpf_func_proto bpf_perf_prog_read_value_proto = {
721 .arg3_type = ARG_CONST_SIZE, 726 .arg3_type = ARG_CONST_SIZE,
722}; 727};
723 728
724static const struct bpf_func_proto *pe_prog_func_proto(enum bpf_func_id func_id) 729static const struct bpf_func_proto *
730pe_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
725{ 731{
726 switch (func_id) { 732 switch (func_id) {
727 case BPF_FUNC_perf_event_output: 733 case BPF_FUNC_perf_event_output:
@@ -731,7 +737,7 @@ static const struct bpf_func_proto *pe_prog_func_proto(enum bpf_func_id func_id)
731 case BPF_FUNC_perf_prog_read_value: 737 case BPF_FUNC_perf_prog_read_value:
732 return &bpf_perf_prog_read_value_proto; 738 return &bpf_perf_prog_read_value_proto;
733 default: 739 default:
734 return tracing_func_proto(func_id); 740 return tracing_func_proto(func_id, prog);
735 } 741 }
736} 742}
737 743
@@ -781,7 +787,8 @@ static const struct bpf_func_proto bpf_get_stackid_proto_raw_tp = {
781 .arg3_type = ARG_ANYTHING, 787 .arg3_type = ARG_ANYTHING,
782}; 788};
783 789
784static const struct bpf_func_proto *raw_tp_prog_func_proto(enum bpf_func_id func_id) 790static const struct bpf_func_proto *
791raw_tp_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
785{ 792{
786 switch (func_id) { 793 switch (func_id) {
787 case BPF_FUNC_perf_event_output: 794 case BPF_FUNC_perf_event_output:
@@ -789,12 +796,13 @@ static const struct bpf_func_proto *raw_tp_prog_func_proto(enum bpf_func_id func
789 case BPF_FUNC_get_stackid: 796 case BPF_FUNC_get_stackid:
790 return &bpf_get_stackid_proto_raw_tp; 797 return &bpf_get_stackid_proto_raw_tp;
791 default: 798 default:
792 return tracing_func_proto(func_id); 799 return tracing_func_proto(func_id, prog);
793 } 800 }
794} 801}
795 802
796static bool raw_tp_prog_is_valid_access(int off, int size, 803static bool raw_tp_prog_is_valid_access(int off, int size,
797 enum bpf_access_type type, 804 enum bpf_access_type type,
805 const struct bpf_prog *prog,
798 struct bpf_insn_access_aux *info) 806 struct bpf_insn_access_aux *info)
799{ 807{
800 /* largest tracepoint in the kernel has 12 args */ 808 /* largest tracepoint in the kernel has 12 args */
@@ -816,6 +824,7 @@ const struct bpf_prog_ops raw_tracepoint_prog_ops = {
816}; 824};
817 825
818static bool pe_prog_is_valid_access(int off, int size, enum bpf_access_type type, 826static bool pe_prog_is_valid_access(int off, int size, enum bpf_access_type type,
827 const struct bpf_prog *prog,
819 struct bpf_insn_access_aux *info) 828 struct bpf_insn_access_aux *info)
820{ 829{
821 const int size_u64 = sizeof(u64); 830 const int size_u64 = sizeof(u64);
diff --git a/net/core/filter.c b/net/core/filter.c
index e989bf313195..7790fd128614 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -3685,7 +3685,7 @@ bpf_base_func_proto(enum bpf_func_id func_id)
3685} 3685}
3686 3686
3687static const struct bpf_func_proto * 3687static const struct bpf_func_proto *
3688sock_filter_func_proto(enum bpf_func_id func_id) 3688sock_filter_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
3689{ 3689{
3690 switch (func_id) { 3690 switch (func_id) {
3691 /* inet and inet6 sockets are created in a process 3691 /* inet and inet6 sockets are created in a process
@@ -3699,7 +3699,7 @@ sock_filter_func_proto(enum bpf_func_id func_id)
3699} 3699}
3700 3700
3701static const struct bpf_func_proto * 3701static const struct bpf_func_proto *
3702sk_filter_func_proto(enum bpf_func_id func_id) 3702sk_filter_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
3703{ 3703{
3704 switch (func_id) { 3704 switch (func_id) {
3705 case BPF_FUNC_skb_load_bytes: 3705 case BPF_FUNC_skb_load_bytes:
@@ -3714,7 +3714,7 @@ sk_filter_func_proto(enum bpf_func_id func_id)
3714} 3714}
3715 3715
3716static const struct bpf_func_proto * 3716static const struct bpf_func_proto *
3717tc_cls_act_func_proto(enum bpf_func_id func_id) 3717tc_cls_act_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
3718{ 3718{
3719 switch (func_id) { 3719 switch (func_id) {
3720 case BPF_FUNC_skb_store_bytes: 3720 case BPF_FUNC_skb_store_bytes:
@@ -3781,7 +3781,7 @@ tc_cls_act_func_proto(enum bpf_func_id func_id)
3781} 3781}
3782 3782
3783static const struct bpf_func_proto * 3783static const struct bpf_func_proto *
3784xdp_func_proto(enum bpf_func_id func_id) 3784xdp_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
3785{ 3785{
3786 switch (func_id) { 3786 switch (func_id) {
3787 case BPF_FUNC_perf_event_output: 3787 case BPF_FUNC_perf_event_output:
@@ -3804,7 +3804,7 @@ xdp_func_proto(enum bpf_func_id func_id)
3804} 3804}
3805 3805
3806static const struct bpf_func_proto * 3806static const struct bpf_func_proto *
3807lwt_inout_func_proto(enum bpf_func_id func_id) 3807lwt_inout_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
3808{ 3808{
3809 switch (func_id) { 3809 switch (func_id) {
3810 case BPF_FUNC_skb_load_bytes: 3810 case BPF_FUNC_skb_load_bytes:
@@ -3831,7 +3831,7 @@ lwt_inout_func_proto(enum bpf_func_id func_id)
3831} 3831}
3832 3832
3833static const struct bpf_func_proto * 3833static const struct bpf_func_proto *
3834 sock_ops_func_proto(enum bpf_func_id func_id) 3834sock_ops_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
3835{ 3835{
3836 switch (func_id) { 3836 switch (func_id) {
3837 case BPF_FUNC_setsockopt: 3837 case BPF_FUNC_setsockopt:
@@ -3847,7 +3847,8 @@ static const struct bpf_func_proto *
3847 } 3847 }
3848} 3848}
3849 3849
3850static const struct bpf_func_proto *sk_msg_func_proto(enum bpf_func_id func_id) 3850static const struct bpf_func_proto *
3851sk_msg_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
3851{ 3852{
3852 switch (func_id) { 3853 switch (func_id) {
3853 case BPF_FUNC_msg_redirect_map: 3854 case BPF_FUNC_msg_redirect_map:
@@ -3863,7 +3864,8 @@ static const struct bpf_func_proto *sk_msg_func_proto(enum bpf_func_id func_id)
3863 } 3864 }
3864} 3865}
3865 3866
3866static const struct bpf_func_proto *sk_skb_func_proto(enum bpf_func_id func_id) 3867static const struct bpf_func_proto *
3868sk_skb_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
3867{ 3869{
3868 switch (func_id) { 3870 switch (func_id) {
3869 case BPF_FUNC_skb_store_bytes: 3871 case BPF_FUNC_skb_store_bytes:
@@ -3888,7 +3890,7 @@ static const struct bpf_func_proto *sk_skb_func_proto(enum bpf_func_id func_id)
3888} 3890}
3889 3891
3890static const struct bpf_func_proto * 3892static const struct bpf_func_proto *
3891lwt_xmit_func_proto(enum bpf_func_id func_id) 3893lwt_xmit_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
3892{ 3894{
3893 switch (func_id) { 3895 switch (func_id) {
3894 case BPF_FUNC_skb_get_tunnel_key: 3896 case BPF_FUNC_skb_get_tunnel_key:
@@ -3918,11 +3920,12 @@ lwt_xmit_func_proto(enum bpf_func_id func_id)
3918 case BPF_FUNC_set_hash_invalid: 3920 case BPF_FUNC_set_hash_invalid:
3919 return &bpf_set_hash_invalid_proto; 3921 return &bpf_set_hash_invalid_proto;
3920 default: 3922 default:
3921 return lwt_inout_func_proto(func_id); 3923 return lwt_inout_func_proto(func_id, prog);
3922 } 3924 }
3923} 3925}
3924 3926
3925static bool bpf_skb_is_valid_access(int off, int size, enum bpf_access_type type, 3927static bool bpf_skb_is_valid_access(int off, int size, enum bpf_access_type type,
3928 const struct bpf_prog *prog,
3926 struct bpf_insn_access_aux *info) 3929 struct bpf_insn_access_aux *info)
3927{ 3930{
3928 const int size_default = sizeof(__u32); 3931 const int size_default = sizeof(__u32);
@@ -3966,6 +3969,7 @@ static bool bpf_skb_is_valid_access(int off, int size, enum bpf_access_type type
3966 3969
3967static bool sk_filter_is_valid_access(int off, int size, 3970static bool sk_filter_is_valid_access(int off, int size,
3968 enum bpf_access_type type, 3971 enum bpf_access_type type,
3972 const struct bpf_prog *prog,
3969 struct bpf_insn_access_aux *info) 3973 struct bpf_insn_access_aux *info)
3970{ 3974{
3971 switch (off) { 3975 switch (off) {
@@ -3986,11 +3990,12 @@ static bool sk_filter_is_valid_access(int off, int size,
3986 } 3990 }
3987 } 3991 }
3988 3992
3989 return bpf_skb_is_valid_access(off, size, type, info); 3993 return bpf_skb_is_valid_access(off, size, type, prog, info);
3990} 3994}
3991 3995
3992static bool lwt_is_valid_access(int off, int size, 3996static bool lwt_is_valid_access(int off, int size,
3993 enum bpf_access_type type, 3997 enum bpf_access_type type,
3998 const struct bpf_prog *prog,
3994 struct bpf_insn_access_aux *info) 3999 struct bpf_insn_access_aux *info)
3995{ 4000{
3996 switch (off) { 4001 switch (off) {
@@ -4020,11 +4025,12 @@ static bool lwt_is_valid_access(int off, int size,
4020 break; 4025 break;
4021 } 4026 }
4022 4027
4023 return bpf_skb_is_valid_access(off, size, type, info); 4028 return bpf_skb_is_valid_access(off, size, type, prog, info);
4024} 4029}
4025 4030
4026static bool sock_filter_is_valid_access(int off, int size, 4031static bool sock_filter_is_valid_access(int off, int size,
4027 enum bpf_access_type type, 4032 enum bpf_access_type type,
4033 const struct bpf_prog *prog,
4028 struct bpf_insn_access_aux *info) 4034 struct bpf_insn_access_aux *info)
4029{ 4035{
4030 if (type == BPF_WRITE) { 4036 if (type == BPF_WRITE) {
@@ -4096,6 +4102,7 @@ static int tc_cls_act_prologue(struct bpf_insn *insn_buf, bool direct_write,
4096 4102
4097static bool tc_cls_act_is_valid_access(int off, int size, 4103static bool tc_cls_act_is_valid_access(int off, int size,
4098 enum bpf_access_type type, 4104 enum bpf_access_type type,
4105 const struct bpf_prog *prog,
4099 struct bpf_insn_access_aux *info) 4106 struct bpf_insn_access_aux *info)
4100{ 4107{
4101 if (type == BPF_WRITE) { 4108 if (type == BPF_WRITE) {
@@ -4125,7 +4132,7 @@ static bool tc_cls_act_is_valid_access(int off, int size,
4125 return false; 4132 return false;
4126 } 4133 }
4127 4134
4128 return bpf_skb_is_valid_access(off, size, type, info); 4135 return bpf_skb_is_valid_access(off, size, type, prog, info);
4129} 4136}
4130 4137
4131static bool __is_valid_xdp_access(int off, int size) 4138static bool __is_valid_xdp_access(int off, int size)
@@ -4142,6 +4149,7 @@ static bool __is_valid_xdp_access(int off, int size)
4142 4149
4143static bool xdp_is_valid_access(int off, int size, 4150static bool xdp_is_valid_access(int off, int size,
4144 enum bpf_access_type type, 4151 enum bpf_access_type type,
4152 const struct bpf_prog *prog,
4145 struct bpf_insn_access_aux *info) 4153 struct bpf_insn_access_aux *info)
4146{ 4154{
4147 if (type == BPF_WRITE) 4155 if (type == BPF_WRITE)
@@ -4174,6 +4182,7 @@ EXPORT_SYMBOL_GPL(bpf_warn_invalid_xdp_action);
4174 4182
4175static bool sock_ops_is_valid_access(int off, int size, 4183static bool sock_ops_is_valid_access(int off, int size,
4176 enum bpf_access_type type, 4184 enum bpf_access_type type,
4185 const struct bpf_prog *prog,
4177 struct bpf_insn_access_aux *info) 4186 struct bpf_insn_access_aux *info)
4178{ 4187{
4179 const int size_default = sizeof(__u32); 4188 const int size_default = sizeof(__u32);
@@ -4220,6 +4229,7 @@ static int sk_skb_prologue(struct bpf_insn *insn_buf, bool direct_write,
4220 4229
4221static bool sk_skb_is_valid_access(int off, int size, 4230static bool sk_skb_is_valid_access(int off, int size,
4222 enum bpf_access_type type, 4231 enum bpf_access_type type,
4232 const struct bpf_prog *prog,
4223 struct bpf_insn_access_aux *info) 4233 struct bpf_insn_access_aux *info)
4224{ 4234{
4225 switch (off) { 4235 switch (off) {
@@ -4249,11 +4259,12 @@ static bool sk_skb_is_valid_access(int off, int size,
4249 break; 4259 break;
4250 } 4260 }
4251 4261
4252 return bpf_skb_is_valid_access(off, size, type, info); 4262 return bpf_skb_is_valid_access(off, size, type, prog, info);
4253} 4263}
4254 4264
4255static bool sk_msg_is_valid_access(int off, int size, 4265static bool sk_msg_is_valid_access(int off, int size,
4256 enum bpf_access_type type, 4266 enum bpf_access_type type,
4267 const struct bpf_prog *prog,
4257 struct bpf_insn_access_aux *info) 4268 struct bpf_insn_access_aux *info)
4258{ 4269{
4259 if (type == BPF_WRITE) 4270 if (type == BPF_WRITE)