diff options
author | Martin KaFai Lau <kafai@fb.com> | 2019-03-12 13:23:09 -0400 |
---|---|---|
committer | Alexei Starovoitov <ast@kernel.org> | 2019-03-13 15:04:35 -0400 |
commit | b55aa7b04bb42274b4a894020b5b2fa059c3527e (patch) | |
tree | 32f0c9d89a04f571a0ee340c4d20c262a6201986 /tools | |
parent | ef776a272b093fb52612e6d8f4b3e77f9bb49554 (diff) |
bpf: Test ref release issue in bpf_tcp_sock and bpf_sk_fullsock
Adding verifier tests to ensure the ptr returned from bpf_tcp_sock() and
bpf_sk_fullsock() cannot be accessed after bpf_sk_release() is called.
A few of the tests are derived from a reproducer test by Lorenz Bauer.
Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/testing/selftests/bpf/verifier/ref_tracking.c | 168 | ||||
-rw-r--r-- | tools/testing/selftests/bpf/verifier/sock.c | 4 |
2 files changed, 170 insertions, 2 deletions
diff --git a/tools/testing/selftests/bpf/verifier/ref_tracking.c b/tools/testing/selftests/bpf/verifier/ref_tracking.c index 3ed3593bd8b6..923f2110072d 100644 --- a/tools/testing/selftests/bpf/verifier/ref_tracking.c +++ b/tools/testing/selftests/bpf/verifier/ref_tracking.c | |||
@@ -605,3 +605,171 @@ | |||
605 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | 605 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, |
606 | .result = ACCEPT, | 606 | .result = ACCEPT, |
607 | }, | 607 | }, |
608 | { | ||
609 | "reference tracking: use ptr from bpf_tcp_sock() after release", | ||
610 | .insns = { | ||
611 | BPF_SK_LOOKUP, | ||
612 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), | ||
613 | BPF_EXIT_INSN(), | ||
614 | BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), | ||
615 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), | ||
616 | BPF_EMIT_CALL(BPF_FUNC_tcp_sock), | ||
617 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3), | ||
618 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), | ||
619 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
620 | BPF_EXIT_INSN(), | ||
621 | BPF_MOV64_REG(BPF_REG_7, BPF_REG_0), | ||
622 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), | ||
623 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
624 | BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_7, offsetof(struct bpf_tcp_sock, snd_cwnd)), | ||
625 | BPF_EXIT_INSN(), | ||
626 | }, | ||
627 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | ||
628 | .result = REJECT, | ||
629 | .errstr = "invalid mem access", | ||
630 | }, | ||
631 | { | ||
632 | "reference tracking: use ptr from bpf_sk_fullsock() after release", | ||
633 | .insns = { | ||
634 | BPF_SK_LOOKUP, | ||
635 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), | ||
636 | BPF_EXIT_INSN(), | ||
637 | BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), | ||
638 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), | ||
639 | BPF_EMIT_CALL(BPF_FUNC_sk_fullsock), | ||
640 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3), | ||
641 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), | ||
642 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
643 | BPF_EXIT_INSN(), | ||
644 | BPF_MOV64_REG(BPF_REG_7, BPF_REG_0), | ||
645 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), | ||
646 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
647 | BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_7, offsetof(struct bpf_sock, type)), | ||
648 | BPF_EXIT_INSN(), | ||
649 | }, | ||
650 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | ||
651 | .result = REJECT, | ||
652 | .errstr = "invalid mem access", | ||
653 | }, | ||
654 | { | ||
655 | "reference tracking: use ptr from bpf_sk_fullsock(tp) after release", | ||
656 | .insns = { | ||
657 | BPF_SK_LOOKUP, | ||
658 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), | ||
659 | BPF_EXIT_INSN(), | ||
660 | BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), | ||
661 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), | ||
662 | BPF_EMIT_CALL(BPF_FUNC_tcp_sock), | ||
663 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3), | ||
664 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), | ||
665 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
666 | BPF_EXIT_INSN(), | ||
667 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), | ||
668 | BPF_EMIT_CALL(BPF_FUNC_sk_fullsock), | ||
669 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), | ||
670 | BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), | ||
671 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
672 | BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 0, 1), | ||
673 | BPF_EXIT_INSN(), | ||
674 | BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6, offsetof(struct bpf_sock, type)), | ||
675 | BPF_EXIT_INSN(), | ||
676 | }, | ||
677 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | ||
678 | .result = REJECT, | ||
679 | .errstr = "invalid mem access", | ||
680 | }, | ||
681 | { | ||
682 | "reference tracking: use sk after bpf_sk_release(tp)", | ||
683 | .insns = { | ||
684 | BPF_SK_LOOKUP, | ||
685 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), | ||
686 | BPF_EXIT_INSN(), | ||
687 | BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), | ||
688 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), | ||
689 | BPF_EMIT_CALL(BPF_FUNC_tcp_sock), | ||
690 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3), | ||
691 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), | ||
692 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
693 | BPF_EXIT_INSN(), | ||
694 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), | ||
695 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
696 | BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6, offsetof(struct bpf_sock, type)), | ||
697 | BPF_EXIT_INSN(), | ||
698 | }, | ||
699 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | ||
700 | .result = REJECT, | ||
701 | .errstr = "invalid mem access", | ||
702 | }, | ||
703 | { | ||
704 | "reference tracking: use ptr from bpf_get_listener_sock() after bpf_sk_release(sk)", | ||
705 | .insns = { | ||
706 | BPF_SK_LOOKUP, | ||
707 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), | ||
708 | BPF_EXIT_INSN(), | ||
709 | BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), | ||
710 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), | ||
711 | BPF_EMIT_CALL(BPF_FUNC_get_listener_sock), | ||
712 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3), | ||
713 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), | ||
714 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
715 | BPF_EXIT_INSN(), | ||
716 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), | ||
717 | BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), | ||
718 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
719 | BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6, offsetof(struct bpf_sock, src_port)), | ||
720 | BPF_EXIT_INSN(), | ||
721 | }, | ||
722 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | ||
723 | .result = ACCEPT, | ||
724 | }, | ||
725 | { | ||
726 | "reference tracking: bpf_sk_release(listen_sk)", | ||
727 | .insns = { | ||
728 | BPF_SK_LOOKUP, | ||
729 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), | ||
730 | BPF_EXIT_INSN(), | ||
731 | BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), | ||
732 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), | ||
733 | BPF_EMIT_CALL(BPF_FUNC_get_listener_sock), | ||
734 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3), | ||
735 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), | ||
736 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
737 | BPF_EXIT_INSN(), | ||
738 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), | ||
739 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
740 | BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6, offsetof(struct bpf_sock, type)), | ||
741 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), | ||
742 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
743 | BPF_EXIT_INSN(), | ||
744 | }, | ||
745 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | ||
746 | .result = REJECT, | ||
747 | .errstr = "reference has not been acquired before", | ||
748 | }, | ||
749 | { | ||
750 | /* !bpf_sk_fullsock(sk) is checked but !bpf_tcp_sock(sk) is not checked */ | ||
751 | "reference tracking: tp->snd_cwnd after bpf_sk_fullsock(sk) and bpf_tcp_sock(sk)", | ||
752 | .insns = { | ||
753 | BPF_SK_LOOKUP, | ||
754 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), | ||
755 | BPF_EXIT_INSN(), | ||
756 | BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), | ||
757 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), | ||
758 | BPF_EMIT_CALL(BPF_FUNC_sk_fullsock), | ||
759 | BPF_MOV64_REG(BPF_REG_7, BPF_REG_0), | ||
760 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), | ||
761 | BPF_EMIT_CALL(BPF_FUNC_tcp_sock), | ||
762 | BPF_MOV64_REG(BPF_REG_8, BPF_REG_0), | ||
763 | BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0, 3), | ||
764 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), | ||
765 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
766 | BPF_EXIT_INSN(), | ||
767 | BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_8, offsetof(struct bpf_tcp_sock, snd_cwnd)), | ||
768 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), | ||
769 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
770 | BPF_EXIT_INSN(), | ||
771 | }, | ||
772 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | ||
773 | .result = REJECT, | ||
774 | .errstr = "invalid mem access", | ||
775 | }, | ||
diff --git a/tools/testing/selftests/bpf/verifier/sock.c b/tools/testing/selftests/bpf/verifier/sock.c index 0ddfdf76aba5..416436231fab 100644 --- a/tools/testing/selftests/bpf/verifier/sock.c +++ b/tools/testing/selftests/bpf/verifier/sock.c | |||
@@ -342,7 +342,7 @@ | |||
342 | }, | 342 | }, |
343 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | 343 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, |
344 | .result = REJECT, | 344 | .result = REJECT, |
345 | .errstr = "type=sock_common expected=sock", | 345 | .errstr = "reference has not been acquired before", |
346 | }, | 346 | }, |
347 | { | 347 | { |
348 | "bpf_sk_release(bpf_sk_fullsock(skb->sk))", | 348 | "bpf_sk_release(bpf_sk_fullsock(skb->sk))", |
@@ -380,5 +380,5 @@ | |||
380 | }, | 380 | }, |
381 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | 381 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, |
382 | .result = REJECT, | 382 | .result = REJECT, |
383 | .errstr = "type=tcp_sock expected=sock", | 383 | .errstr = "reference has not been acquired before", |
384 | }, | 384 | }, |