From patchwork Fri Aug 4 13:11:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Borkmann X-Patchwork-Id: 13341794 X-Patchwork-Delegate: bpf@iogearbox.net Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 12823A940 for ; Fri, 4 Aug 2023 13:11:57 +0000 (UTC) Received: from www62.your-server.de (www62.your-server.de [213.133.104.62]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BACBC13D for ; Fri, 4 Aug 2023 06:11:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=iogearbox.net; s=default2302; h=Content-Transfer-Encoding:MIME-Version: Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References; bh=8xHxz9zllmQxTKtEF8QIycucg5GDH06EI/yUcT3qAi8=; b=JweABOnaDR4/Kl5LDXGZnTp2PH aHC8ZxU8dpmL1xXp/hZX6F15drSC5US1wgCA3bzlrN4QzgKgQmtTQslhiwvtmLhxBpFFt6L8hicu5 5N0ZCfx65dPuWRK5qG0VRXfALM9vzPMMB19jRpenbcD3iS0E7aWSxt1VC5qI55gL2m9ma66D7SeaT dk+yd3HW0RqhM43XUX2dxvRY/W2/7+VFOT6yU+bm7gkUdqmdG/c5ntIm7dpHRRRVmJ4uXcVflxOku uec5B2M9LDkQYUcJx7yWienjAHHNKzB24RuW4rVP0QgH+q43g32Yqis4m5f3egkq+IiDcfZXTbpdz l8jN/9Og==; Received: from [180.200.247.117] (helo=localhost) by www62.your-server.de with esmtpsa (TLS1.3) tls TLS_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1qRuat-000IT3-Sw; Fri, 04 Aug 2023 15:11:52 +0200 From: Daniel Borkmann To: martin.lau@linux.dev Cc: bpf@vger.kernel.org, Daniel Borkmann , syzbot+0c06ba0f831fe07a8f27@syzkaller.appspotmail.com Subject: [PATCH bpf-next 1/2] bpf: Fix mprog detachment for empty mprog entry Date: Fri, 4 Aug 2023 15:11:11 +0200 Message-Id: <20230804131112.11012-1-daniel@iogearbox.net> X-Mailer: git-send-email 2.21.0 Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Authenticated-Sender: daniel@iogearbox.net X-Virus-Scanned: Clear (ClamAV 0.103.8/26990/Fri Aug 4 09:32:00 2023) X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: bpf@iogearbox.net syzbot reported an UBSAN array-index-out-of-bounds access in bpf_mprog_read() upon bpf_mprog_detach(). While it did not have a reproducer, I was able to manually reproduce through an empty mprog entry which just has miniq present. The latter is important given otherwise we get an ENOENT error as tcx detaches the whole mprog entry. The index 4294967295 was triggered via NULL dtuple.prog which then attempts to detach from the back. bpf_mprog_fetch() in this case did hit the idx == total and therefore tried to grab the entry at idx -1. Fix it by adding an explicit bpf_mprog_total() check in bpf_mprog_detach() and bail out early with ENOENT. Fixes: 053c8e1f235d ("bpf: Add generic attach/detach/query API for multi-progs") Reported-by: syzbot+0c06ba0f831fe07a8f27@syzkaller.appspotmail.com Signed-off-by: Daniel Borkmann --- kernel/bpf/mprog.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/bpf/mprog.c b/kernel/bpf/mprog.c index f7816d2bc3e4..32d2c4829eb8 100644 --- a/kernel/bpf/mprog.c +++ b/kernel/bpf/mprog.c @@ -337,6 +337,8 @@ int bpf_mprog_detach(struct bpf_mprog_entry *entry, return -EINVAL; if (revision && revision != bpf_mprog_revision(entry)) return -ESTALE; + if (!bpf_mprog_total(entry)) + return -ENOENT; ret = bpf_mprog_tuple_relative(&rtuple, id_or_fd, flags, prog ? prog->type : BPF_PROG_TYPE_UNSPEC); From patchwork Fri Aug 4 13:11:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Borkmann X-Patchwork-Id: 13341795 X-Patchwork-Delegate: bpf@iogearbox.net Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9E5ECA940 for ; Fri, 4 Aug 2023 13:12:00 +0000 (UTC) Received: from www62.your-server.de (www62.your-server.de [213.133.104.62]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6678C46A8 for ; Fri, 4 Aug 2023 06:11:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=iogearbox.net; s=default2302; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID; bh=JW6kJQwI1T84EIc1M685myGKFY6tDYT7PQzXyE1nGps=; b=HkKxibKYeV903XofreWwmbU/pK EG22ywtogtS0VqlwOAoQSHlpj+Lp2sQk1ZQ6pTCl6Uah4ywEmBIEoE4yRZgeXA2CaCCnx2SgQqz8O ZPEoVKzunAboiTxdDf0BHdDciM5rxltb4KT5ZFyhlD48QA6m3pLh6l6li429b8BL6VJNzEI6DmIq+ E6RvN4IbjKA7jfPNbXzlZrouj0KRzZ+A2GUkqHVZTuqkF7yjNzviJM6KmA9/M0L1KfFdoGRIoHooV 0SHManAd7I0fvdsc/krsElDa7wfxu7ZK4TbieLija4uzcHdcZfRHqHisrtWX+fyrbF7aFJ3dCfQ+g k/rfr4Ng==; Received: from [180.200.247.117] (helo=localhost) by www62.your-server.de with esmtpsa (TLS1.3) tls TLS_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1qRuaz-000IUK-7M; Fri, 04 Aug 2023 15:11:57 +0200 From: Daniel Borkmann To: martin.lau@linux.dev Cc: bpf@vger.kernel.org, Daniel Borkmann Subject: [PATCH bpf-next 2/2] selftests/bpf: Add test for detachment on empty mprog entry Date: Fri, 4 Aug 2023 15:11:12 +0200 Message-Id: <20230804131112.11012-2-daniel@iogearbox.net> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20230804131112.11012-1-daniel@iogearbox.net> References: <20230804131112.11012-1-daniel@iogearbox.net> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Authenticated-Sender: daniel@iogearbox.net X-Virus-Scanned: Clear (ClamAV 0.103.8/26990/Fri Aug 4 09:32:00 2023) X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: bpf@iogearbox.net Add a detachment test case with miniq present to assert that with and without the miniq we get the same error. # ./test_progs -t tc_opts #244 tc_opts_after:OK #245 tc_opts_append:OK #246 tc_opts_basic:OK #247 tc_opts_before:OK #248 tc_opts_chain_classic:OK #249 tc_opts_delete_empty:OK #250 tc_opts_demixed:OK #251 tc_opts_detach:OK #252 tc_opts_detach_after:OK #253 tc_opts_detach_before:OK #254 tc_opts_dev_cleanup:OK #255 tc_opts_invalid:OK #256 tc_opts_mixed:OK #257 tc_opts_prepend:OK #258 tc_opts_replace:OK #259 tc_opts_revision:OK Summary: 16/0 PASSED, 0 SKIPPED, 0 FAILED Signed-off-by: Daniel Borkmann --- .../selftests/bpf/prog_tests/tc_opts.c | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tools/testing/selftests/bpf/prog_tests/tc_opts.c b/tools/testing/selftests/bpf/prog_tests/tc_opts.c index 7914100f9b46..39bd253e41aa 100644 --- a/tools/testing/selftests/bpf/prog_tests/tc_opts.c +++ b/tools/testing/selftests/bpf/prog_tests/tc_opts.c @@ -2237,3 +2237,34 @@ void serial_test_tc_opts_detach_after(void) test_tc_opts_detach_after_target(BPF_TCX_INGRESS); test_tc_opts_detach_after_target(BPF_TCX_EGRESS); } + +static void test_tc_opts_delete_empty(int target, bool chain_tc_old) +{ + LIBBPF_OPTS(bpf_tc_hook, tc_hook, .ifindex = loopback); + LIBBPF_OPTS(bpf_prog_detach_opts, optd); + int err; + + assert_mprog_count(target, 0); + if (chain_tc_old) { + tc_hook.attach_point = target == BPF_TCX_INGRESS ? + BPF_TC_INGRESS : BPF_TC_EGRESS; + err = bpf_tc_hook_create(&tc_hook); + ASSERT_OK(err, "bpf_tc_hook_create"); + __assert_mprog_count(target, 0, true, loopback); + } + err = bpf_prog_detach_opts(0, loopback, target, &optd); + ASSERT_EQ(err, -ENOENT, "prog_detach"); + if (chain_tc_old) { + tc_hook.attach_point = BPF_TC_INGRESS | BPF_TC_EGRESS; + bpf_tc_hook_destroy(&tc_hook); + } + assert_mprog_count(target, 0); +} + +void serial_test_tc_opts_delete_empty(void) +{ + test_tc_opts_delete_empty(BPF_TCX_INGRESS, false); + test_tc_opts_delete_empty(BPF_TCX_EGRESS, false); + test_tc_opts_delete_empty(BPF_TCX_INGRESS, true); + test_tc_opts_delete_empty(BPF_TCX_EGRESS, true); +}