Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Andrey Ignatov and committed by
Daniel Borkmann
5e43f899 807ae7da

+88 -29
+4 -1
include/linux/bpf.h
··· 208 208 209 209 struct bpf_verifier_ops { 210 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 215 /* return true if 'size' wide access at offset 'off' within bpf_context 214 216 * with 'type' (read or write) is allowed 215 217 */ 216 218 bool (*is_valid_access)(int off, int size, enum bpf_access_type type, 219 + const struct bpf_prog *prog, 217 220 struct bpf_insn_access_aux *info); 218 221 int (*gen_prologue)(struct bpf_insn *insn, bool direct_write, 219 222 const struct bpf_prog *prog);
+1
include/linux/filter.h
··· 469 469 is_func:1, /* program is a bpf function */ 470 470 kprobe_override:1; /* Do we override a kprobe? */ 471 471 enum bpf_prog_type type; /* Type of BPF program */ 472 + enum bpf_attach_type expected_attach_type; /* For some prog types */ 472 473 u32 len; /* Number of filter blocks */ 473 474 u32 jited_len; /* Size of jited insns in bytes */ 474 475 u8 tag[BPF_TAG_SIZE];
+5
include/uapi/linux/bpf.h
··· 296 296 __u32 prog_flags; 297 297 char prog_name[BPF_OBJ_NAME_LEN]; 298 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 306 struct { /* anonymous struct used by BPF_OBJ_* commands */
+2 -1
kernel/bpf/cgroup.c
··· 545 545 EXPORT_SYMBOL(__cgroup_bpf_check_dev_permission); 546 546 547 547 static const struct bpf_func_proto * 548 - cgroup_dev_func_proto(enum bpf_func_id func_id) 548 + cgroup_dev_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) 549 549 { 550 550 switch (func_id) { 551 551 case BPF_FUNC_map_lookup_elem: ··· 566 566 567 567 static bool cgroup_dev_is_valid_access(int off, int size, 568 568 enum bpf_access_type type, 569 + const struct bpf_prog *prog, 569 570 struct bpf_insn_access_aux *info) 570 571 { 571 572 const int size_default = sizeof(__u32);
+30 -1
kernel/bpf/syscall.c
··· 1171 1171 } 1172 1172 EXPORT_SYMBOL_GPL(bpf_prog_get_type_dev); 1173 1173 1174 + static int 1175 + bpf_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 + 1184 + static 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 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 1177 1196 static int bpf_prog_load(union bpf_attr *attr) 1178 1197 { ··· 1228 1209 !capable(CAP_SYS_ADMIN)) 1229 1210 return -EPERM; 1230 1211 1212 + if (bpf_prog_load_check_attach_type(type, attr->expected_attach_type)) 1213 + return -EINVAL; 1214 + 1231 1215 /* plain bpf_prog allocation */ 1232 1216 prog = bpf_prog_alloc(bpf_prog_size(attr->insn_cnt), GFP_USER); 1233 1217 if (!prog) 1234 1218 return -ENOMEM; 1219 + 1220 + prog->expected_attach_type = attr->expected_attach_type; 1235 1221 1236 1222 prog->aux->offload_requested = !!attr->prog_ifindex; 1237 1223 ··· 1497 1473 prog = bpf_prog_get_type(attr->attach_bpf_fd, ptype); 1498 1474 if (IS_ERR(prog)) 1499 1475 return PTR_ERR(prog); 1476 + 1477 + if (bpf_prog_attach_check_attach_type(prog, attr->attach_type)) { 1478 + bpf_prog_put(prog); 1479 + return -EINVAL; 1480 + } 1500 1481 1501 1482 cgrp = cgroup_get_from_fd(attr->target_fd); 1502 1483 if (IS_ERR(cgrp)) {
+3 -3
kernel/bpf/verifier.c
··· 1323 1323 }; 1324 1324 1325 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 1327 /* A non zero info.ctx_field_size indicates that this field is a 1328 1328 * candidate for later verifier transformation to load the whole 1329 1329 * field and then apply a mask when accessed with a narrower ··· 2349 2349 } 2350 2350 2351 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 2353 if (!fn) { 2354 2354 verbose(env, "unknown func %s#%d\n", func_id_name(func_id), 2355 2355 func_id); ··· 5572 5572 insn = new_prog->insnsi + i + delta; 5573 5573 } 5574 5574 patch_call_imm: 5575 - fn = env->ops->get_func_proto(insn->imm); 5575 + fn = env->ops->get_func_proto(insn->imm, env->prog); 5576 5576 /* all functions that have prototype and verifier allowed 5577 5577 * programs to call them, must be real in-kernel functions 5578 5578 */
+18 -9
kernel/trace/bpf_trace.c
··· 524 524 .arg3_type = ARG_ANYTHING, 525 525 }; 526 526 527 - static const struct bpf_func_proto *tracing_func_proto(enum bpf_func_id func_id) 527 + static const struct bpf_func_proto * 528 + tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) 528 529 { 529 530 switch (func_id) { 530 531 case BPF_FUNC_map_lookup_elem: ··· 569 568 } 570 569 } 571 570 572 - static const struct bpf_func_proto *kprobe_prog_func_proto(enum bpf_func_id func_id) 571 + static const struct bpf_func_proto * 572 + kprobe_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) 573 573 { 574 574 switch (func_id) { 575 575 case BPF_FUNC_perf_event_output: ··· 584 582 return &bpf_override_return_proto; 585 583 #endif 586 584 default: 587 - return tracing_func_proto(func_id); 585 + return tracing_func_proto(func_id, prog); 588 586 } 589 587 } 590 588 591 589 /* bpf+kprobe programs can access fields of 'struct pt_regs' */ 592 590 static bool kprobe_prog_is_valid_access(int off, int size, enum bpf_access_type type, 591 + const struct bpf_prog *prog, 593 592 struct bpf_insn_access_aux *info) 594 593 { 595 594 if (off < 0 || off >= sizeof(struct pt_regs)) ··· 664 661 .arg3_type = ARG_ANYTHING, 665 662 }; 666 663 667 - static const struct bpf_func_proto *tp_prog_func_proto(enum bpf_func_id func_id) 664 + static const struct bpf_func_proto * 665 + tp_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) 668 666 { 669 667 switch (func_id) { 670 668 case BPF_FUNC_perf_event_output: ··· 673 669 case BPF_FUNC_get_stackid: 674 670 return &bpf_get_stackid_proto_tp; 675 671 default: 676 - return tracing_func_proto(func_id); 672 + return tracing_func_proto(func_id, prog); 677 673 } 678 674 } 679 675 680 676 static bool tp_prog_is_valid_access(int off, int size, enum bpf_access_type type, 677 + const struct bpf_prog *prog, 681 678 struct bpf_insn_access_aux *info) 682 679 { 683 680 if (off < sizeof(void *) || off >= PERF_MAX_TRACE_SIZE) ··· 726 721 .arg3_type = ARG_CONST_SIZE, 727 722 }; 728 723 729 - static const struct bpf_func_proto *pe_prog_func_proto(enum bpf_func_id func_id) 724 + static const struct bpf_func_proto * 725 + pe_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) 730 726 { 731 727 switch (func_id) { 732 728 case BPF_FUNC_perf_event_output: ··· 737 731 case BPF_FUNC_perf_prog_read_value: 738 732 return &bpf_perf_prog_read_value_proto; 739 733 default: 740 - return tracing_func_proto(func_id); 734 + return tracing_func_proto(func_id, prog); 741 735 } 742 736 } 743 737 ··· 787 781 .arg3_type = ARG_ANYTHING, 788 782 }; 789 783 790 - static const struct bpf_func_proto *raw_tp_prog_func_proto(enum bpf_func_id func_id) 784 + static const struct bpf_func_proto * 785 + raw_tp_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) 791 786 { 792 787 switch (func_id) { 793 788 case BPF_FUNC_perf_event_output: ··· 796 789 case BPF_FUNC_get_stackid: 797 790 return &bpf_get_stackid_proto_raw_tp; 798 791 default: 799 - return tracing_func_proto(func_id); 792 + return tracing_func_proto(func_id, prog); 800 793 } 801 794 } 802 795 803 796 static bool raw_tp_prog_is_valid_access(int off, int size, 804 797 enum bpf_access_type type, 798 + const struct bpf_prog *prog, 805 799 struct bpf_insn_access_aux *info) 806 800 { 807 801 /* largest tracepoint in the kernel has 12 args */ ··· 824 816 }; 825 817 826 818 static bool pe_prog_is_valid_access(int off, int size, enum bpf_access_type type, 819 + const struct bpf_prog *prog, 827 820 struct bpf_insn_access_aux *info) 828 821 { 829 822 const int size_u64 = sizeof(u64);
+25 -14
net/core/filter.c
··· 3685 3685 } 3686 3686 3687 3687 static const struct bpf_func_proto * 3688 - sock_filter_func_proto(enum bpf_func_id func_id) 3688 + sock_filter_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) 3689 3689 { 3690 3690 switch (func_id) { 3691 3691 /* inet and inet6 sockets are created in a process ··· 3699 3699 } 3700 3700 3701 3701 static const struct bpf_func_proto * 3702 - sk_filter_func_proto(enum bpf_func_id func_id) 3702 + sk_filter_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) 3703 3703 { 3704 3704 switch (func_id) { 3705 3705 case BPF_FUNC_skb_load_bytes: ··· 3714 3714 } 3715 3715 3716 3716 static const struct bpf_func_proto * 3717 - tc_cls_act_func_proto(enum bpf_func_id func_id) 3717 + tc_cls_act_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) 3718 3718 { 3719 3719 switch (func_id) { 3720 3720 case BPF_FUNC_skb_store_bytes: ··· 3781 3781 } 3782 3782 3783 3783 static const struct bpf_func_proto * 3784 - xdp_func_proto(enum bpf_func_id func_id) 3784 + xdp_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) 3785 3785 { 3786 3786 switch (func_id) { 3787 3787 case BPF_FUNC_perf_event_output: ··· 3804 3804 } 3805 3805 3806 3806 static const struct bpf_func_proto * 3807 - lwt_inout_func_proto(enum bpf_func_id func_id) 3807 + lwt_inout_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) 3808 3808 { 3809 3809 switch (func_id) { 3810 3810 case BPF_FUNC_skb_load_bytes: ··· 3831 3831 } 3832 3832 3833 3833 static const struct bpf_func_proto * 3834 - sock_ops_func_proto(enum bpf_func_id func_id) 3834 + sock_ops_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) 3835 3835 { 3836 3836 switch (func_id) { 3837 3837 case BPF_FUNC_setsockopt: ··· 3847 3847 } 3848 3848 } 3849 3849 3850 - static const struct bpf_func_proto *sk_msg_func_proto(enum bpf_func_id func_id) 3850 + static const struct bpf_func_proto * 3851 + sk_msg_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) 3851 3852 { 3852 3853 switch (func_id) { 3853 3854 case BPF_FUNC_msg_redirect_map: ··· 3864 3863 } 3865 3864 } 3866 3865 3867 - static const struct bpf_func_proto *sk_skb_func_proto(enum bpf_func_id func_id) 3866 + static const struct bpf_func_proto * 3867 + sk_skb_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) 3868 3868 { 3869 3869 switch (func_id) { 3870 3870 case BPF_FUNC_skb_store_bytes: ··· 3890 3888 } 3891 3889 3892 3890 static const struct bpf_func_proto * 3893 - lwt_xmit_func_proto(enum bpf_func_id func_id) 3891 + lwt_xmit_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) 3894 3892 { 3895 3893 switch (func_id) { 3896 3894 case BPF_FUNC_skb_get_tunnel_key: ··· 3920 3918 case BPF_FUNC_set_hash_invalid: 3921 3919 return &bpf_set_hash_invalid_proto; 3922 3920 default: 3923 - return lwt_inout_func_proto(func_id); 3921 + return lwt_inout_func_proto(func_id, prog); 3924 3922 } 3925 3923 } 3926 3924 3927 3925 static bool bpf_skb_is_valid_access(int off, int size, enum bpf_access_type type, 3926 + const struct bpf_prog *prog, 3928 3927 struct bpf_insn_access_aux *info) 3929 3928 { 3930 3929 const int size_default = sizeof(__u32); ··· 3969 3966 3970 3967 static bool sk_filter_is_valid_access(int off, int size, 3971 3968 enum bpf_access_type type, 3969 + const struct bpf_prog *prog, 3972 3970 struct bpf_insn_access_aux *info) 3973 3971 { 3974 3972 switch (off) { ··· 3990 3986 } 3991 3987 } 3992 3988 3993 - return bpf_skb_is_valid_access(off, size, type, info); 3989 + return bpf_skb_is_valid_access(off, size, type, prog, info); 3994 3990 } 3995 3991 3996 3992 static bool lwt_is_valid_access(int off, int size, 3997 3993 enum bpf_access_type type, 3994 + const struct bpf_prog *prog, 3998 3995 struct bpf_insn_access_aux *info) 3999 3996 { 4000 3997 switch (off) { ··· 4025 4020 break; 4026 4021 } 4027 4022 4028 - return bpf_skb_is_valid_access(off, size, type, info); 4023 + return bpf_skb_is_valid_access(off, size, type, prog, info); 4029 4024 } 4030 4025 4031 4026 static bool sock_filter_is_valid_access(int off, int size, 4032 4027 enum bpf_access_type type, 4028 + const struct bpf_prog *prog, 4033 4029 struct bpf_insn_access_aux *info) 4034 4030 { 4035 4031 if (type == BPF_WRITE) { ··· 4102 4096 4103 4097 static bool tc_cls_act_is_valid_access(int off, int size, 4104 4098 enum bpf_access_type type, 4099 + const struct bpf_prog *prog, 4105 4100 struct bpf_insn_access_aux *info) 4106 4101 { 4107 4102 if (type == BPF_WRITE) { ··· 4132 4125 return false; 4133 4126 } 4134 4127 4135 - return bpf_skb_is_valid_access(off, size, type, info); 4128 + return bpf_skb_is_valid_access(off, size, type, prog, info); 4136 4129 } 4137 4130 4138 4131 static bool __is_valid_xdp_access(int off, int size) ··· 4149 4142 4150 4143 static bool xdp_is_valid_access(int off, int size, 4151 4144 enum bpf_access_type type, 4145 + const struct bpf_prog *prog, 4152 4146 struct bpf_insn_access_aux *info) 4153 4147 { 4154 4148 if (type == BPF_WRITE) ··· 4182 4174 4183 4175 static bool sock_ops_is_valid_access(int off, int size, 4184 4176 enum bpf_access_type type, 4177 + const struct bpf_prog *prog, 4185 4178 struct bpf_insn_access_aux *info) 4186 4179 { 4187 4180 const int size_default = sizeof(__u32); ··· 4229 4220 4230 4221 static bool sk_skb_is_valid_access(int off, int size, 4231 4222 enum bpf_access_type type, 4223 + const struct bpf_prog *prog, 4232 4224 struct bpf_insn_access_aux *info) 4233 4225 { 4234 4226 switch (off) { ··· 4259 4249 break; 4260 4250 } 4261 4251 4262 - return bpf_skb_is_valid_access(off, size, type, info); 4252 + return bpf_skb_is_valid_access(off, size, type, prog, info); 4263 4253 } 4264 4254 4265 4255 static bool sk_msg_is_valid_access(int off, int size, 4266 4256 enum bpf_access_type type, 4257 + const struct bpf_prog *prog, 4267 4258 struct bpf_insn_access_aux *info) 4268 4259 { 4269 4260 if (type == BPF_WRITE)