aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/bpf.h8
-rw-r--r--kernel/bpf/sockmap.c2
-rw-r--r--kernel/bpf/syscall.c27
-rw-r--r--tools/testing/selftests/bpf/test_maps.c51
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)
387struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key); 387struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key);
388int sock_map_attach_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type); 388int sock_map_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type);
389#else 389#else
390static inline struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key) 390static 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
395static inline int sock_map_attach_prog(struct bpf_map *map, 395static 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
795int sock_map_attach_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type) 795int 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
1099static int sockmap_get_from_fd(const union bpf_attr *attr) 1099static 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]);