diff options
| -rw-r--r-- | include/linux/bpf.h | 8 | ||||
| -rw-r--r-- | kernel/bpf/sockmap.c | 2 | ||||
| -rw-r--r-- | kernel/bpf/syscall.c | 27 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/test_maps.c | 51 |
4 files changed, 72 insertions, 16 deletions
diff --git a/include/linux/bpf.h b/include/linux/bpf.h index c2cb1b5c094e..8390859e79e7 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h | |||
| @@ -385,16 +385,16 @@ static inline void __dev_map_flush(struct bpf_map *map) | |||
| 385 | 385 | ||
| 386 | #if defined(CONFIG_STREAM_PARSER) && defined(CONFIG_BPF_SYSCALL) | 386 | #if defined(CONFIG_STREAM_PARSER) && defined(CONFIG_BPF_SYSCALL) |
| 387 | struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key); | 387 | struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key); |
| 388 | int sock_map_attach_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type); | 388 | int sock_map_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type); |
| 389 | #else | 389 | #else |
| 390 | static inline struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key) | 390 | static inline struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key) |
| 391 | { | 391 | { |
| 392 | return NULL; | 392 | return NULL; |
| 393 | } | 393 | } |
| 394 | 394 | ||
| 395 | static inline int sock_map_attach_prog(struct bpf_map *map, | 395 | static inline int sock_map_prog(struct bpf_map *map, |
| 396 | struct bpf_prog *prog, | 396 | struct bpf_prog *prog, |
| 397 | u32 type) | 397 | u32 type) |
| 398 | { | 398 | { |
| 399 | return -EOPNOTSUPP; | 399 | return -EOPNOTSUPP; |
| 400 | } | 400 | } |
diff --git a/kernel/bpf/sockmap.c b/kernel/bpf/sockmap.c index f6ffde9c6a68..6424ce0e4969 100644 --- a/kernel/bpf/sockmap.c +++ b/kernel/bpf/sockmap.c | |||
| @@ -792,7 +792,7 @@ out_progs: | |||
| 792 | return err; | 792 | return err; |
| 793 | } | 793 | } |
| 794 | 794 | ||
| 795 | int sock_map_attach_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type) | 795 | int sock_map_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type) |
| 796 | { | 796 | { |
| 797 | struct bpf_stab *stab = container_of(map, struct bpf_stab, map); | 797 | struct bpf_stab *stab = container_of(map, struct bpf_stab, map); |
| 798 | struct bpf_prog *orig; | 798 | struct bpf_prog *orig; |
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 70ad8e220343..cb17e1cd1d43 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c | |||
| @@ -1096,10 +1096,10 @@ static int bpf_obj_get(const union bpf_attr *attr) | |||
| 1096 | 1096 | ||
| 1097 | #define BPF_PROG_ATTACH_LAST_FIELD attach_flags | 1097 | #define BPF_PROG_ATTACH_LAST_FIELD attach_flags |
| 1098 | 1098 | ||
| 1099 | static int sockmap_get_from_fd(const union bpf_attr *attr) | 1099 | static int sockmap_get_from_fd(const union bpf_attr *attr, bool attach) |
| 1100 | { | 1100 | { |
| 1101 | struct bpf_prog *prog = NULL; | ||
| 1101 | int ufd = attr->target_fd; | 1102 | int ufd = attr->target_fd; |
| 1102 | struct bpf_prog *prog; | ||
| 1103 | struct bpf_map *map; | 1103 | struct bpf_map *map; |
| 1104 | struct fd f; | 1104 | struct fd f; |
| 1105 | int err; | 1105 | int err; |
| @@ -1109,16 +1109,20 @@ static int sockmap_get_from_fd(const union bpf_attr *attr) | |||
| 1109 | if (IS_ERR(map)) | 1109 | if (IS_ERR(map)) |
| 1110 | return PTR_ERR(map); | 1110 | return PTR_ERR(map); |
| 1111 | 1111 | ||
| 1112 | prog = bpf_prog_get_type(attr->attach_bpf_fd, BPF_PROG_TYPE_SK_SKB); | 1112 | if (attach) { |
| 1113 | if (IS_ERR(prog)) { | 1113 | prog = bpf_prog_get_type(attr->attach_bpf_fd, |
| 1114 | fdput(f); | 1114 | BPF_PROG_TYPE_SK_SKB); |
| 1115 | return PTR_ERR(prog); | 1115 | if (IS_ERR(prog)) { |
| 1116 | fdput(f); | ||
| 1117 | return PTR_ERR(prog); | ||
| 1118 | } | ||
| 1116 | } | 1119 | } |
| 1117 | 1120 | ||
| 1118 | err = sock_map_attach_prog(map, prog, attr->attach_type); | 1121 | err = sock_map_prog(map, prog, attr->attach_type); |
| 1119 | if (err) { | 1122 | if (err) { |
| 1120 | fdput(f); | 1123 | fdput(f); |
| 1121 | bpf_prog_put(prog); | 1124 | if (prog) |
| 1125 | bpf_prog_put(prog); | ||
| 1122 | return err; | 1126 | return err; |
| 1123 | } | 1127 | } |
| 1124 | 1128 | ||
| @@ -1155,7 +1159,7 @@ static int bpf_prog_attach(const union bpf_attr *attr) | |||
| 1155 | break; | 1159 | break; |
| 1156 | case BPF_SK_SKB_STREAM_PARSER: | 1160 | case BPF_SK_SKB_STREAM_PARSER: |
| 1157 | case BPF_SK_SKB_STREAM_VERDICT: | 1161 | case BPF_SK_SKB_STREAM_VERDICT: |
| 1158 | return sockmap_get_from_fd(attr); | 1162 | return sockmap_get_from_fd(attr, true); |
| 1159 | default: | 1163 | default: |
| 1160 | return -EINVAL; | 1164 | return -EINVAL; |
| 1161 | } | 1165 | } |
| @@ -1204,7 +1208,10 @@ static int bpf_prog_detach(const union bpf_attr *attr) | |||
| 1204 | ret = cgroup_bpf_update(cgrp, NULL, attr->attach_type, false); | 1208 | ret = cgroup_bpf_update(cgrp, NULL, attr->attach_type, false); |
| 1205 | cgroup_put(cgrp); | 1209 | cgroup_put(cgrp); |
| 1206 | break; | 1210 | break; |
| 1207 | 1211 | case BPF_SK_SKB_STREAM_PARSER: | |
| 1212 | case BPF_SK_SKB_STREAM_VERDICT: | ||
| 1213 | ret = sockmap_get_from_fd(attr, false); | ||
| 1214 | break; | ||
| 1208 | default: | 1215 | default: |
| 1209 | return -EINVAL; | 1216 | return -EINVAL; |
| 1210 | } | 1217 | } |
diff --git a/tools/testing/selftests/bpf/test_maps.c b/tools/testing/selftests/bpf/test_maps.c index 4acc772a28c0..fe3a443a1102 100644 --- a/tools/testing/selftests/bpf/test_maps.c +++ b/tools/testing/selftests/bpf/test_maps.c | |||
| @@ -558,7 +558,7 @@ static void test_sockmap(int tasks, void *data) | |||
| 558 | } | 558 | } |
| 559 | } | 559 | } |
| 560 | 560 | ||
| 561 | /* Test attaching bad fds */ | 561 | /* Test attaching/detaching bad fds */ |
| 562 | err = bpf_prog_attach(-1, fd, BPF_SK_SKB_STREAM_PARSER, 0); | 562 | err = bpf_prog_attach(-1, fd, BPF_SK_SKB_STREAM_PARSER, 0); |
| 563 | if (!err) { | 563 | if (!err) { |
| 564 | printf("Failed invalid parser prog attach\n"); | 564 | printf("Failed invalid parser prog attach\n"); |
| @@ -571,6 +571,30 @@ static void test_sockmap(int tasks, void *data) | |||
| 571 | goto out_sockmap; | 571 | goto out_sockmap; |
| 572 | } | 572 | } |
| 573 | 573 | ||
| 574 | err = bpf_prog_attach(-1, fd, __MAX_BPF_ATTACH_TYPE, 0); | ||
| 575 | if (!err) { | ||
| 576 | printf("Failed unknown prog attach\n"); | ||
| 577 | goto out_sockmap; | ||
| 578 | } | ||
| 579 | |||
| 580 | err = bpf_prog_detach(fd, BPF_SK_SKB_STREAM_PARSER); | ||
| 581 | if (err) { | ||
| 582 | printf("Failed empty parser prog detach\n"); | ||
| 583 | goto out_sockmap; | ||
| 584 | } | ||
| 585 | |||
| 586 | err = bpf_prog_detach(fd, BPF_SK_SKB_STREAM_VERDICT); | ||
| 587 | if (err) { | ||
| 588 | printf("Failed empty verdict prog detach\n"); | ||
| 589 | goto out_sockmap; | ||
| 590 | } | ||
| 591 | |||
| 592 | err = bpf_prog_detach(fd, __MAX_BPF_ATTACH_TYPE); | ||
| 593 | if (!err) { | ||
| 594 | printf("Detach invalid prog successful\n"); | ||
| 595 | goto out_sockmap; | ||
| 596 | } | ||
| 597 | |||
| 574 | /* Load SK_SKB program and Attach */ | 598 | /* Load SK_SKB program and Attach */ |
| 575 | err = bpf_prog_load(SOCKMAP_PARSE_PROG, | 599 | err = bpf_prog_load(SOCKMAP_PARSE_PROG, |
| 576 | BPF_PROG_TYPE_SK_SKB, &obj, &parse_prog); | 600 | BPF_PROG_TYPE_SK_SKB, &obj, &parse_prog); |
| @@ -643,6 +667,13 @@ static void test_sockmap(int tasks, void *data) | |||
| 643 | goto out_sockmap; | 667 | goto out_sockmap; |
| 644 | } | 668 | } |
| 645 | 669 | ||
| 670 | err = bpf_prog_attach(verdict_prog, map_fd_rx, | ||
| 671 | __MAX_BPF_ATTACH_TYPE, 0); | ||
| 672 | if (!err) { | ||
| 673 | printf("Attached unknown bpf prog\n"); | ||
| 674 | goto out_sockmap; | ||
| 675 | } | ||
| 676 | |||
| 646 | /* Test map update elem afterwards fd lives in fd and map_fd */ | 677 | /* Test map update elem afterwards fd lives in fd and map_fd */ |
| 647 | for (i = 0; i < 6; i++) { | 678 | for (i = 0; i < 6; i++) { |
| 648 | err = bpf_map_update_elem(map_fd_rx, &i, &sfd[i], BPF_ANY); | 679 | err = bpf_map_update_elem(map_fd_rx, &i, &sfd[i], BPF_ANY); |
| @@ -809,6 +840,24 @@ static void test_sockmap(int tasks, void *data) | |||
| 809 | assert(status == 0); | 840 | assert(status == 0); |
| 810 | } | 841 | } |
| 811 | 842 | ||
| 843 | err = bpf_prog_detach(map_fd_rx, __MAX_BPF_ATTACH_TYPE); | ||
| 844 | if (!err) { | ||
| 845 | printf("Detached an invalid prog type.\n"); | ||
| 846 | goto out_sockmap; | ||
| 847 | } | ||
| 848 | |||
| 849 | err = bpf_prog_detach(map_fd_rx, BPF_SK_SKB_STREAM_PARSER); | ||
| 850 | if (err) { | ||
| 851 | printf("Failed parser prog detach\n"); | ||
| 852 | goto out_sockmap; | ||
| 853 | } | ||
| 854 | |||
| 855 | err = bpf_prog_detach(map_fd_rx, BPF_SK_SKB_STREAM_VERDICT); | ||
| 856 | if (err) { | ||
| 857 | printf("Failed parser prog detach\n"); | ||
| 858 | goto out_sockmap; | ||
| 859 | } | ||
| 860 | |||
| 812 | /* Test map close sockets */ | 861 | /* Test map close sockets */ |
| 813 | for (i = 0; i < 6; i++) | 862 | for (i = 0; i < 6; i++) |
| 814 | close(sfd[i]); | 863 | close(sfd[i]); |
