From patchwork Thu Apr 27 20:04:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 13225724 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 58999C77B73 for ; Thu, 27 Apr 2023 20:04:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344052AbjD0UER (ORCPT ); Thu, 27 Apr 2023 16:04:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44410 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229750AbjD0UEQ (ORCPT ); Thu, 27 Apr 2023 16:04:16 -0400 Received: from mail-pg1-x54a.google.com (mail-pg1-x54a.google.com [IPv6:2607:f8b0:4864:20::54a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8BA773595 for ; Thu, 27 Apr 2023 13:04:13 -0700 (PDT) Received: by mail-pg1-x54a.google.com with SMTP id 41be03b00d2f7-51bb4164162so8004243a12.2 for ; Thu, 27 Apr 2023 13:04:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1682625853; x=1685217853; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=heydORlx8T15rvgU8Yk1jGEI7xIKLNNxTYW35qTk5Hs=; b=0KEHb6TFvgmeSplF5jADOJq2NyjcXuTIoKrUVJYObqFiriO8r0GACbnxKNB97xFqSz 0VdRFiapKbQjLNLaKp59yaMfM7vwCBJbN7c4EyKtgqcP++oYL1+uxvTojzkXWkMNVa5O I3zCIsjAeSjyFyUDMc02hqdKD1NgRcvP8UHXBROTRThoXNua1DutzGpnZb+l9ye8r3j1 Fbyz7SL2FmQizweQ+2t1uLNS/pWBcfJSHhQFUa6Zkfzz5KG/i8ivqxYEwLGyw60zvSR+ ymzNuZ8/vq0RLueSrqjJOU+hwP3bqbglvL0Q/vt/rdYXlgOwUPHz4/D/cR71StUStFvP AfUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682625853; x=1685217853; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=heydORlx8T15rvgU8Yk1jGEI7xIKLNNxTYW35qTk5Hs=; b=Xy/T+nMfRiUg4Pqo0egiTO6H06MozXk3ZCGoJ9Ec245fjOgx9wV2yxEUTO+qPTqIyo +Uc6dAwRhw2Ln88kOb/SQzRXjEvaxBMMaBYBV/ydw6q2wuZQElE0aBWr235A+3TX9Uoy nVHHwMSYNHI0B7wlZ0T654Q1DH2zE98koDc9YI00vZmBf+7qNZt440YmD5Qn/RaSG471 m7xNGPwO7Pbx3XeZc7m8qXyLsQZxjOg87y/ZMi0UYn+PtgXXdOSv2jvKi/agvxXuLawT EtOX4erlHbaTYL1KeEg0UnpCzNBanKnm8ve8Anrxrg+AicPbGRazBkPv0Gs0wgPc5zdq Qthg== X-Gm-Message-State: AC+VfDwE8oQbJz06EjaofDzcxk+euBNzhoS8nK9aXkZ9/+ux0IDJEzAR 9/MmsP95ayYrvQc/Vc8l4GTekBAHY5/Vn0rOUtTbeSq1B0bMORMh9HRjZd+lkqKzB0qy+VwbfUP VmT4nxxY5dS2fJlFuJyV48r0SiFtVDyXypnxwj0WVtV7VTSNLug== X-Google-Smtp-Source: ACHHUZ6d0ZpkSGLWxs0F7EpCAUY0VqArK9d7/aRKUwUACgqpazrdkPvyHlDhsVu6V/syVU5tnTJiWbI= X-Received: from sdf.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5935]) (user=sdf job=sendgmr) by 2002:a63:6bc9:0:b0:524:bc58:5e5c with SMTP id g192-20020a636bc9000000b00524bc585e5cmr659177pgc.8.1682625852851; Thu, 27 Apr 2023 13:04:12 -0700 (PDT) Date: Thu, 27 Apr 2023 13:04:06 -0700 In-Reply-To: <20230427200409.1785263-1-sdf@google.com> Mime-Version: 1.0 References: <20230427200409.1785263-1-sdf@google.com> X-Mailer: git-send-email 2.40.1.495.gc816e09b53d-goog Message-ID: <20230427200409.1785263-2-sdf@google.com> Subject: [PATCH bpf-next v2 1/4] bpf: Don't EFAULT for {g,s}setsockopt with wrong optlen From: Stanislav Fomichev To: bpf@vger.kernel.org Cc: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, martin.lau@linux.dev, song@kernel.org, yhs@fb.com, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, jolsa@kernel.org, Martin KaFai Lau Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net With the way the hooks implemented right now, we have a special condition: optval larger than PAGE_SIZE will expose only first 4k into BPF; any modifications to the optval are ignored. If the BPF program doesn't handle this condition by resetting optlen to 0, the userspace will get EFAULT. The intention of the EFAULT was to make it apparent to the developers that the program is doing something wrong. However, this inadvertently might affect production workloads with the BPF programs that are not too careful (i.e., returning EFAULT for perfectly valid setsockopt/getsockopt calls). Let's try to minimize the chance of BPF program screwing up userspace by ignoring the output of those BPF programs (instead of returning EFAULT to the userspace). pr_info_once those cases to the dmesg to help with figuring out what's going wrong. Fixes: 0d01da6afc54 ("bpf: implement getsockopt and setsockopt hooks") Suggested-by: Martin KaFai Lau Signed-off-by: Stanislav Fomichev --- kernel/bpf/cgroup.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c index a06e118a9be5..e041159a1ce0 100644 --- a/kernel/bpf/cgroup.c +++ b/kernel/bpf/cgroup.c @@ -1826,6 +1826,11 @@ int __cgroup_bpf_run_filter_setsockopt(struct sock *sk, int *level, ret = 1; } else if (ctx.optlen > max_optlen || ctx.optlen < -1) { /* optlen is out of bounds */ + if (*optlen > PAGE_SIZE && ctx.optlen >= 0) { + pr_info_once("bpf setsockopt: ignoring program buffer with optlen=%d (max_optlen=%d)\n", + ctx.optlen, max_optlen); + goto out; + } ret = -EFAULT; } else { /* optlen within bounds, run kernel handler */ @@ -1881,8 +1886,10 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level, .optname = optname, .current_task = current, }; + int orig_optlen; int ret; + orig_optlen = max_optlen; ctx.optlen = max_optlen; max_optlen = sockopt_alloc_buf(&ctx, max_optlen, &buf); if (max_optlen < 0) @@ -1922,6 +1929,11 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level, goto out; if (optval && (ctx.optlen > max_optlen || ctx.optlen < 0)) { + if (orig_optlen > PAGE_SIZE && ctx.optlen >= 0) { + pr_info_once("bpf getsockopt: ignoring program buffer with optlen=%d (max_optlen=%d)\n", + ctx.optlen, max_optlen); + goto out; + } ret = -EFAULT; goto out; } From patchwork Thu Apr 27 20:04:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 13225725 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0E5A4C77B61 for ; Thu, 27 Apr 2023 20:04:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229750AbjD0UES (ORCPT ); Thu, 27 Apr 2023 16:04:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44412 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245540AbjD0UEQ (ORCPT ); Thu, 27 Apr 2023 16:04:16 -0400 Received: from mail-pf1-x44a.google.com (mail-pf1-x44a.google.com [IPv6:2607:f8b0:4864:20::44a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1A43C2D74 for ; Thu, 27 Apr 2023 13:04:15 -0700 (PDT) Received: by mail-pf1-x44a.google.com with SMTP id d2e1a72fcca58-64115ef7234so5811011b3a.1 for ; Thu, 27 Apr 2023 13:04:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1682625854; x=1685217854; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=X6ZC+1x9ueI+ENQfDLLj/ebYGpNxhIsZZ44SjLDor/o=; b=CG+Do3v/bMrrZSXfYsNG+U3C+B0VWZSeG+f8ibIcH9mzKDiFoeOnhXLlWrSWVYpNIp MdAEdUqs+jjhWDy0+QpsXZ47DssQ0hu45tuly2Al7nnjha2ccEa55O/69NEG+PIoV9kb UV3OoL2i9Qw7QKpRwRPD+jgt4IkjMGpEyJh8z2K7wJLT+OTijPHtVFONZfdIhTyUHORt 5zlt5k0Dh8iwM6yh4HO9BavQev4UzbocyZIjCnc//aWjJ2Y4CVMo9bFb85GJ8FPJcEwp gGDJ9hMgYB1611Er8fzzaCNY+FXCCZTmesNCp1cK6JaPeM+s5++g0iDeRg6Xm1ZgKIpx IGgg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682625854; x=1685217854; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=X6ZC+1x9ueI+ENQfDLLj/ebYGpNxhIsZZ44SjLDor/o=; b=TXUYtkJgLENeBmrfp/pEGJL+uyLdpE4CymNQ5ANXCyE6lhxXyjQwuB5S1YNHIZVy9+ QyDcqu45OoUi8DUe64x33GxuMTzzGaNlLLgtD8jAAngAJdqPEeTG+qHDKnPCf3ysbVjs AEe0XDDcvSObsOfZhK0tglLpOHw49XpXDhTp1gCmaugyZkNx2+vMGbHHy7mJqOMRrkx0 IGx5MxdtNwKDsY0YvqEyli9oU58K8YVoWWxQojkPGX9KHETde9a1EzPkmygq/pLunpdq te6c0pZgmjRImAgZtJIBLNj4VTxDsnuSIBvoBto7u+QgdoCYtk2zgu/MYgHvtdjhVXQK bSpA== X-Gm-Message-State: AC+VfDz3QpWNoe1BBs/vIVIFfcLewDHgauSrHWvptcyt65M+ruhBnA1o HcWqB8RMbsWgHq/p8O9nP3GzXmG2LGd093TDqqc0dE6VPPbxTQMRTXzqTvtkv7Sgw8NOH+2e7Y3 sKyEs5RnhwM2cm2qHDE4s9hENd41FAD8RR3gD8VfOAFIBm3kycw== X-Google-Smtp-Source: ACHHUZ63Ok0VMTftBu9lOB/PxjEAzFjfvSgSccoFWurF+TDBHLog28uJkhezl7DewAmSb6OrJM5fWe0= X-Received: from sdf.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5935]) (user=sdf job=sendgmr) by 2002:a63:fc4b:0:b0:521:70e7:a8b with SMTP id r11-20020a63fc4b000000b0052170e70a8bmr1833684pgk.1.1682625854494; Thu, 27 Apr 2023 13:04:14 -0700 (PDT) Date: Thu, 27 Apr 2023 13:04:07 -0700 In-Reply-To: <20230427200409.1785263-1-sdf@google.com> Mime-Version: 1.0 References: <20230427200409.1785263-1-sdf@google.com> X-Mailer: git-send-email 2.40.1.495.gc816e09b53d-goog Message-ID: <20230427200409.1785263-3-sdf@google.com> Subject: [PATCH bpf-next v2 2/4] selftests/bpf: Update EFAULT {g,s}etsockopt selftests From: Stanislav Fomichev To: bpf@vger.kernel.org Cc: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, martin.lau@linux.dev, song@kernel.org, yhs@fb.com, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, jolsa@kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net Instead of assuming EFAULT, let's assume the BPF program's output is ignored. Remove "getsockopt: deny arbitrary ctx->retval" because it was actually testing optlen. We have separate set of tests for retval. Signed-off-by: Stanislav Fomichev --- .../selftests/bpf/prog_tests/sockopt.c | 80 +++++++++++++++++-- 1 file changed, 74 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/sockopt.c b/tools/testing/selftests/bpf/prog_tests/sockopt.c index aa4debf62fc6..8dad30ce910e 100644 --- a/tools/testing/selftests/bpf/prog_tests/sockopt.c +++ b/tools/testing/selftests/bpf/prog_tests/sockopt.c @@ -273,10 +273,30 @@ static struct sockopt_test { .error = EFAULT_GETSOCKOPT, }, { - .descr = "getsockopt: deny arbitrary ctx->retval", + .descr = "getsockopt: ignore >PAGE_SIZE optlen", .insns = { - /* ctx->retval = 123 */ - BPF_MOV64_IMM(BPF_REG_0, 123), + /* write 0xFF to the first optval byte */ + + /* r6 = ctx->optval */ + BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, + offsetof(struct bpf_sockopt, optval)), + /* r2 = ctx->optval */ + BPF_MOV64_REG(BPF_REG_2, BPF_REG_6), + /* r6 = ctx->optval + 1 */ + BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1), + + /* r7 = ctx->optval_end */ + BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_1, + offsetof(struct bpf_sockopt, optval_end)), + + /* if (ctx->optval + 1 <= ctx->optval_end) { */ + BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 1), + /* ctx->optval[0] = 0xF0 */ + BPF_ST_MEM(BPF_B, BPF_REG_2, 0, 0xFF), + /* } */ + + /* ctx->retval = 0 */ + BPF_MOV64_IMM(BPF_REG_0, 0), BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, offsetof(struct bpf_sockopt, retval)), @@ -287,9 +307,10 @@ static struct sockopt_test { .attach_type = BPF_CGROUP_GETSOCKOPT, .expected_attach_type = BPF_CGROUP_GETSOCKOPT, - .get_optlen = 64, - - .error = EFAULT_GETSOCKOPT, + .get_level = 1234, + .get_optname = 5678, + .get_optval = {}, /* the changes are ignored */ + .get_optlen = 4096 + 1, }, { .descr = "getsockopt: support smaller ctx->optlen", @@ -648,6 +669,49 @@ static struct sockopt_test { .error = EFAULT_SETSOCKOPT, }, + { + .descr = "setsockopt: ignore >PAGE_SIZE optlen", + .insns = { + /* write 0xFF to the first optval byte */ + + /* r6 = ctx->optval */ + BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, + offsetof(struct bpf_sockopt, optval)), + /* r2 = ctx->optval */ + BPF_MOV64_REG(BPF_REG_2, BPF_REG_6), + /* r6 = ctx->optval + 1 */ + BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1), + + /* r7 = ctx->optval_end */ + BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_1, + offsetof(struct bpf_sockopt, optval_end)), + + /* if (ctx->optval + 1 <= ctx->optval_end) { */ + BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 1), + /* ctx->optval[0] = 0xF0 */ + BPF_ST_MEM(BPF_B, BPF_REG_2, 0, 0xFF), + /* } */ + + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_SETSOCKOPT, + .expected_attach_type = BPF_CGROUP_SETSOCKOPT, + + .set_level = SOL_IP, + .set_optname = IP_TOS, + .set_optval = { 1 << 3 }, + .set_optlen = 4096 + 1, + + .get_level = SOL_IP, + .get_optname = IP_TOS, +#if __BYTE_ORDER == __LITTLE_ENDIAN + .get_optval = { 1 << 3, 0, 0, 0 }, /* the changes are ignored */ +#else + .get_optval = { 0, 0, 0, 1 << 3 }, /* the changes are ignored */ +#endif + .get_optlen = 4, + }, { .descr = "setsockopt: allow changing ctx->optlen within bounds", .insns = { @@ -922,6 +986,7 @@ static int run_test(int cgroup_fd, struct sockopt_test *test) if (test->get_optlen) { optval = malloc(test->get_optlen); + memset(optval, 0, test->get_optlen); socklen_t optlen = test->get_optlen; socklen_t expected_get_optlen = test->get_optlen_ret ?: test->get_optlen; @@ -946,6 +1011,9 @@ static int run_test(int cgroup_fd, struct sockopt_test *test) goto free_optval; } + if (optlen > sizeof(test->get_optval)) + optlen = sizeof(test->get_optval); + if (memcmp(optval, test->get_optval, optlen) != 0) { errno = 0; log_err("getsockopt returned unexpected optval"); From patchwork Thu Apr 27 20:04:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 13225726 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AF506C7EE21 for ; Thu, 27 Apr 2023 20:04:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245540AbjD0UET (ORCPT ); Thu, 27 Apr 2023 16:04:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44426 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344077AbjD0UES (ORCPT ); Thu, 27 Apr 2023 16:04:18 -0400 Received: from mail-pf1-x44a.google.com (mail-pf1-x44a.google.com [IPv6:2607:f8b0:4864:20::44a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BE51F3A99 for ; Thu, 27 Apr 2023 13:04:16 -0700 (PDT) Received: by mail-pf1-x44a.google.com with SMTP id d2e1a72fcca58-64115ef7234so5811142b3a.1 for ; Thu, 27 Apr 2023 13:04:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1682625856; x=1685217856; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=58JiO1X9FSfj/irRqUMpeVrE7gOAAc85t/q77kIFj6U=; b=JuVlRDlV1oscwGtIcdCcgOJFxQl+Hm0AenzDXc8QgUFO2/+F0W0vackVK1tFdQGz71 z5vjNHavuIxrtR8EcjkLs6qGUM33Hj+GrYmWjLGrApQAaiont1/1PU/2PPlYRUorOlGe Hk7mBcsCAs1M9seBt1zZhwcPXIIVbj+XODEJGzJhZbY+EbxS5H7/vW9M3z7qwLg7PwdG bF8mlJpiA3U4Y3VWkUJ3qTqlqdlfYy/ba6fTkwHUOTStgyPvrq/eInuC5Sgbk/jG57av YHwf5ux0bILDVLree0ytO0lY+Xrf5NuGSw491g0cGxENdTlP9axTKkFOOQTbjfPqiAKW 3tkA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682625856; x=1685217856; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=58JiO1X9FSfj/irRqUMpeVrE7gOAAc85t/q77kIFj6U=; b=Hazj/GT2sSRisDed7gDcp9LzrVlu/Y4EZc37qOmvfw63Y+4vfWDdXkZ2mwRR/RkdR6 /+Mqu8j0leYD0eFTMqJdMxc+z5nifcoeTKY4OobcjzU20I4N43VBTIx1fci+3BR1odiw NFE6Ag41slQE6yX2PbMleIH8kFmEp3EW2SEx0DmXgK/Z7iwYptdkatjxTAl2ZWU3Moz+ UGMMNO3oKlKtcI3mNE6RUR13CBdXZj7wIrmcGDyCGTOTIB1VFi5nuo2J31qjDpppsTzM qkGVPYivfdBITOAGZLMCkedcUNWm29LUrZRmqdAlOvxeF/FZU9yXLkZFFgsva35frNuo jGng== X-Gm-Message-State: AC+VfDyzZZ6/pzHaGAk/HMf3VYyGe1Heb6NO9iRAX3xPlrl1MXdpVbt1 vDHLErgQ8+dybQV3uVLTptp/fxOxD/7LVoBMWMlP1m62NP8iN6YLOcof3a4bMBAHSgN41vqNnKG lTcs+Vh9n8rEXdE5MTG3KEMpUzj+jEaR2+jiKItYNHhDlpkv2nw== X-Google-Smtp-Source: ACHHUZ7XbdYavyU8EUL+tE+dthwmP8k1uzDxM295jMWk0dB2K8PaF6tN+RGrV6Xc1hNLs9ygmDoLEVM= X-Received: from sdf.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5935]) (user=sdf job=sendgmr) by 2002:a17:902:f98b:b0:1a5:22f3:220e with SMTP id ky11-20020a170902f98b00b001a522f3220emr2415669plb.3.1682625856152; Thu, 27 Apr 2023 13:04:16 -0700 (PDT) Date: Thu, 27 Apr 2023 13:04:08 -0700 In-Reply-To: <20230427200409.1785263-1-sdf@google.com> Mime-Version: 1.0 References: <20230427200409.1785263-1-sdf@google.com> X-Mailer: git-send-email 2.40.1.495.gc816e09b53d-goog Message-ID: <20230427200409.1785263-4-sdf@google.com> Subject: [PATCH bpf-next v2 3/4] selftests/bpf: Correctly handle optlen > 4096 From: Stanislav Fomichev To: bpf@vger.kernel.org Cc: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, martin.lau@linux.dev, song@kernel.org, yhs@fb.com, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, jolsa@kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net Even though it's not relevant in selftests, the people might still copy-paste from them. So let's take care of optlen > 4096 cases explicitly. Signed-off-by: Stanislav Fomichev --- .../progs/cgroup_getset_retval_getsockopt.c | 12 +++++++++ .../progs/cgroup_getset_retval_setsockopt.c | 16 ++++++++++++ .../selftests/bpf/progs/sockopt_inherit.c | 16 ++++++++++-- .../selftests/bpf/progs/sockopt_multi.c | 24 +++++++++++++++--- .../selftests/bpf/progs/sockopt_qos_to_cc.c | 8 +++++- .../testing/selftests/bpf/progs/sockopt_sk.c | 25 +++++++++++++------ 6 files changed, 88 insertions(+), 13 deletions(-) diff --git a/tools/testing/selftests/bpf/progs/cgroup_getset_retval_getsockopt.c b/tools/testing/selftests/bpf/progs/cgroup_getset_retval_getsockopt.c index b2a409e6382a..b66454886cc4 100644 --- a/tools/testing/selftests/bpf/progs/cgroup_getset_retval_getsockopt.c +++ b/tools/testing/selftests/bpf/progs/cgroup_getset_retval_getsockopt.c @@ -20,6 +20,10 @@ int get_retval(struct bpf_sockopt *ctx) ctx_retval_value = ctx->retval; __sync_fetch_and_add(&invocations, 1); + /* optval larger than PAGE_SIZE use kernel's buffer. */ + if (ctx->optlen > 4096) + ctx->optlen = 0; + return 1; } @@ -31,6 +35,10 @@ int set_eisconn(struct bpf_sockopt *ctx) if (bpf_set_retval(-EISCONN)) assertion_error = 1; + /* optval larger than PAGE_SIZE use kernel's buffer. */ + if (ctx->optlen > 4096) + ctx->optlen = 0; + return 1; } @@ -41,5 +49,9 @@ int clear_retval(struct bpf_sockopt *ctx) ctx->retval = 0; + /* optval larger than PAGE_SIZE use kernel's buffer. */ + if (ctx->optlen > 4096) + ctx->optlen = 0; + return 1; } diff --git a/tools/testing/selftests/bpf/progs/cgroup_getset_retval_setsockopt.c b/tools/testing/selftests/bpf/progs/cgroup_getset_retval_setsockopt.c index d6e5903e06ba..68fce0311771 100644 --- a/tools/testing/selftests/bpf/progs/cgroup_getset_retval_setsockopt.c +++ b/tools/testing/selftests/bpf/progs/cgroup_getset_retval_setsockopt.c @@ -18,6 +18,10 @@ int get_retval(struct bpf_sockopt *ctx) retval_value = bpf_get_retval(); __sync_fetch_and_add(&invocations, 1); + /* optval larger than PAGE_SIZE use kernel's buffer. */ + if (ctx->optlen > 4096) + ctx->optlen = 0; + return 1; } @@ -29,6 +33,10 @@ int set_eunatch(struct bpf_sockopt *ctx) if (bpf_set_retval(-EUNATCH)) assertion_error = 1; + /* optval larger than PAGE_SIZE use kernel's buffer. */ + if (ctx->optlen > 4096) + ctx->optlen = 0; + return 0; } @@ -40,6 +48,10 @@ int set_eisconn(struct bpf_sockopt *ctx) if (bpf_set_retval(-EISCONN)) assertion_error = 1; + /* optval larger than PAGE_SIZE use kernel's buffer. */ + if (ctx->optlen > 4096) + ctx->optlen = 0; + return 0; } @@ -48,5 +60,9 @@ int legacy_eperm(struct bpf_sockopt *ctx) { __sync_fetch_and_add(&invocations, 1); + /* optval larger than PAGE_SIZE use kernel's buffer. */ + if (ctx->optlen > 4096) + ctx->optlen = 0; + return 0; } diff --git a/tools/testing/selftests/bpf/progs/sockopt_inherit.c b/tools/testing/selftests/bpf/progs/sockopt_inherit.c index 9fb241b97291..78e56070dbcf 100644 --- a/tools/testing/selftests/bpf/progs/sockopt_inherit.c +++ b/tools/testing/selftests/bpf/progs/sockopt_inherit.c @@ -55,7 +55,7 @@ int _getsockopt(struct bpf_sockopt *ctx) __u8 *optval = ctx->optval; if (ctx->level != SOL_CUSTOM) - return 1; /* only interested in SOL_CUSTOM */ + goto out; /* only interested in SOL_CUSTOM */ if (optval + 1 > optval_end) return 0; /* EPERM, bounds check */ @@ -70,6 +70,12 @@ int _getsockopt(struct bpf_sockopt *ctx) ctx->optlen = 1; return 1; + +out: + /* optval larger than PAGE_SIZE use kernel's buffer. */ + if (ctx->optlen > 4096) + ctx->optlen = 0; + return 1; } SEC("cgroup/setsockopt") @@ -80,7 +86,7 @@ int _setsockopt(struct bpf_sockopt *ctx) __u8 *optval = ctx->optval; if (ctx->level != SOL_CUSTOM) - return 1; /* only interested in SOL_CUSTOM */ + goto out; /* only interested in SOL_CUSTOM */ if (optval + 1 > optval_end) return 0; /* EPERM, bounds check */ @@ -93,4 +99,10 @@ int _setsockopt(struct bpf_sockopt *ctx) ctx->optlen = -1; return 1; + +out: + /* optval larger than PAGE_SIZE use kernel's buffer. */ + if (ctx->optlen > 4096) + ctx->optlen = 0; + return 1; } diff --git a/tools/testing/selftests/bpf/progs/sockopt_multi.c b/tools/testing/selftests/bpf/progs/sockopt_multi.c index 177a59069dae..f645eb253c6c 100644 --- a/tools/testing/selftests/bpf/progs/sockopt_multi.c +++ b/tools/testing/selftests/bpf/progs/sockopt_multi.c @@ -12,7 +12,7 @@ int _getsockopt_child(struct bpf_sockopt *ctx) __u8 *optval = ctx->optval; if (ctx->level != SOL_IP || ctx->optname != IP_TOS) - return 1; + goto out; if (optval + 1 > optval_end) return 0; /* EPERM, bounds check */ @@ -26,6 +26,12 @@ int _getsockopt_child(struct bpf_sockopt *ctx) ctx->optlen = 1; return 1; + +out: + /* optval larger than PAGE_SIZE use kernel's buffer. */ + if (ctx->optlen > 4096) + ctx->optlen = 0; + return 1; } SEC("cgroup/getsockopt") @@ -35,7 +41,7 @@ int _getsockopt_parent(struct bpf_sockopt *ctx) __u8 *optval = ctx->optval; if (ctx->level != SOL_IP || ctx->optname != IP_TOS) - return 1; + goto out; if (optval + 1 > optval_end) return 0; /* EPERM, bounds check */ @@ -49,6 +55,12 @@ int _getsockopt_parent(struct bpf_sockopt *ctx) ctx->optlen = 1; return 1; + +out: + /* optval larger than PAGE_SIZE use kernel's buffer. */ + if (ctx->optlen > 4096) + ctx->optlen = 0; + return 1; } SEC("cgroup/setsockopt") @@ -58,7 +70,7 @@ int _setsockopt(struct bpf_sockopt *ctx) __u8 *optval = ctx->optval; if (ctx->level != SOL_IP || ctx->optname != IP_TOS) - return 1; + goto out; if (optval + 1 > optval_end) return 0; /* EPERM, bounds check */ @@ -67,4 +79,10 @@ int _setsockopt(struct bpf_sockopt *ctx) ctx->optlen = 1; return 1; + +out: + /* optval larger than PAGE_SIZE use kernel's buffer. */ + if (ctx->optlen > 4096) + ctx->optlen = 0; + return 1; } diff --git a/tools/testing/selftests/bpf/progs/sockopt_qos_to_cc.c b/tools/testing/selftests/bpf/progs/sockopt_qos_to_cc.c index 1bce83b6e3a7..597f3e276cf7 100644 --- a/tools/testing/selftests/bpf/progs/sockopt_qos_to_cc.c +++ b/tools/testing/selftests/bpf/progs/sockopt_qos_to_cc.c @@ -19,7 +19,7 @@ int sockopt_qos_to_cc(struct bpf_sockopt *ctx) char cc_cubic[TCP_CA_NAME_MAX] = "cubic"; if (ctx->level != SOL_IPV6 || ctx->optname != IPV6_TCLASS) - return 1; + goto out; if (optval + 1 > optval_end) return 0; /* EPERM, bounds check */ @@ -36,4 +36,10 @@ int sockopt_qos_to_cc(struct bpf_sockopt *ctx) return 0; } return 1; + +out: + /* optval larger than PAGE_SIZE use kernel's buffer. */ + if (ctx->optlen > 4096) + ctx->optlen = 0; + return 1; } diff --git a/tools/testing/selftests/bpf/progs/sockopt_sk.c b/tools/testing/selftests/bpf/progs/sockopt_sk.c index fe1df4cd206e..e1aed858c208 100644 --- a/tools/testing/selftests/bpf/progs/sockopt_sk.c +++ b/tools/testing/selftests/bpf/progs/sockopt_sk.c @@ -37,7 +37,7 @@ int _getsockopt(struct bpf_sockopt *ctx) /* Bypass AF_NETLINK. */ sk = ctx->sk; if (sk && sk->family == AF_NETLINK) - return 1; + goto out; /* Make sure bpf_get_netns_cookie is callable. */ @@ -52,8 +52,7 @@ int _getsockopt(struct bpf_sockopt *ctx) * let next BPF program in the cgroup chain or kernel * handle it. */ - ctx->optlen = 0; /* bypass optval>PAGE_SIZE */ - return 1; + goto out; } if (ctx->level == SOL_SOCKET && ctx->optname == SO_SNDBUF) { @@ -61,7 +60,7 @@ int _getsockopt(struct bpf_sockopt *ctx) * let next BPF program in the cgroup chain or kernel * handle it. */ - return 1; + goto out; } if (ctx->level == SOL_TCP && ctx->optname == TCP_CONGESTION) { @@ -69,7 +68,7 @@ int _getsockopt(struct bpf_sockopt *ctx) * let next BPF program in the cgroup chain or kernel * handle it. */ - return 1; + goto out; } if (ctx->level == SOL_TCP && ctx->optname == TCP_ZEROCOPY_RECEIVE) { @@ -85,7 +84,7 @@ int _getsockopt(struct bpf_sockopt *ctx) if (((struct tcp_zerocopy_receive *)optval)->address != 0) return 0; /* unexpected data */ - return 1; + goto out; } if (ctx->level == SOL_IP && ctx->optname == IP_FREEBIND) { @@ -129,6 +128,12 @@ int _getsockopt(struct bpf_sockopt *ctx) ctx->optlen = 1; return 1; + +out: + /* optval larger than PAGE_SIZE use kernel's buffer. */ + if (ctx->optlen > 4096) + ctx->optlen = 0; + return 1; } SEC("cgroup/setsockopt") @@ -142,7 +147,7 @@ int _setsockopt(struct bpf_sockopt *ctx) /* Bypass AF_NETLINK. */ sk = ctx->sk; if (sk && sk->family == AF_NETLINK) - return 1; + goto out; /* Make sure bpf_get_netns_cookie is callable. */ @@ -224,4 +229,10 @@ int _setsockopt(struct bpf_sockopt *ctx) */ return 1; + +out: + /* optval larger than PAGE_SIZE use kernel's buffer. */ + if (ctx->optlen > 4096) + ctx->optlen = 0; + return 1; } From patchwork Thu Apr 27 20:04:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 13225727 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 24BB3C77B73 for ; Thu, 27 Apr 2023 20:04:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244414AbjD0UEV (ORCPT ); Thu, 27 Apr 2023 16:04:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44448 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343660AbjD0UEU (ORCPT ); Thu, 27 Apr 2023 16:04:20 -0400 Received: from mail-pl1-x649.google.com (mail-pl1-x649.google.com [IPv6:2607:f8b0:4864:20::649]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8FAD6359D for ; Thu, 27 Apr 2023 13:04:18 -0700 (PDT) Received: by mail-pl1-x649.google.com with SMTP id d9443c01a7336-1a6ce2cdb92so94179265ad.3 for ; Thu, 27 Apr 2023 13:04:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1682625858; x=1685217858; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=JMnXpbgbJK1tBOJAoq/xoB1rsubwxMbquh5P5alNzmc=; b=TYCZVhO8l5KX+hdFxEqPhRF19ppZw/OJm39lYR02LqzsWXABLtj2ycjcjcFYzOn6j2 +7MLYv+EOCJurAyrHlGCAEDRmUbVjUGWhMPI6MIzfT0hLm8NaZ/wiLJcdyuOaKUxnT4o Y4i+58CcH9jiqJcEKascr+JEcMClpoxqvsh919lbzVe21QCqf+muCA7AGzqM8CZYWJBF N46E5/uCC2tXXrTZ5nB1LZ8ZC2tsc3bgXeUHtnYj96UBllbTZa3SqzzlZ19tHpQ/qrcA oxj/FjYatPd39ztPV/oWTLrHan+p3shPLAD+efrrvHed6AA3KCBxRTXw8CwB9E5hLvW9 vKpg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682625858; x=1685217858; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=JMnXpbgbJK1tBOJAoq/xoB1rsubwxMbquh5P5alNzmc=; b=BzXnIMH3pqggWwKKSIaZISlmyRZg/JIh/ijGIzYjYn+NgY15ZBqtIo6QyvbGQi0dE6 dsX/ygppUV8fAhue9rR0fYJYZZ8H4ITuvpO/7FbcSZhRoPhq24q2A5mAaqIe/Zoy4r+e rlD58tah7erzIqjq3iiDVJHYT+VO1O4CZU3vM93sIWeMdUTyp3xrXm9PR6Sh02xX/7EO RoIjyjrXevgQKnat8vgZi09tXXzjwZXaDOFjTKOHc0Z0xtP+xdn7KBt6KJp8WhaCKpFW KKsBUSC1qqSnL4ZHPKjgV4gBxK8cRPFn7ZgzfUvIOlJjvV312fgUoyq4E4Y4WGplPhMS 4hCA== X-Gm-Message-State: AC+VfDyPiEhZ5B36DmIljkJOSi+HKdgRm0Gw48rOSpKyfqKBfBlI8IMc GNDNQ8DqY7U3xpBaKu+uCBa2zsA6w0ax7eLlj2hfZ9VSqfYfuyFI7yw0rraPZqAFbWXLqWFIqCG KciDq5sUm1r7YdSaERPbzv7ItFpj5ulkGaVYcufU1BzHAXN3U0A== X-Google-Smtp-Source: ACHHUZ5W2eLi7BDwgpawpryx/Qpq9b8AU5fn/GtZrMe9hNUy6xcDXq3IDm0e/g8am2CnAvrUq089DHM= X-Received: from sdf.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5935]) (user=sdf job=sendgmr) by 2002:a17:903:190:b0:1a2:185a:cd6 with SMTP id z16-20020a170903019000b001a2185a0cd6mr891091plg.4.1682625858076; Thu, 27 Apr 2023 13:04:18 -0700 (PDT) Date: Thu, 27 Apr 2023 13:04:09 -0700 In-Reply-To: <20230427200409.1785263-1-sdf@google.com> Mime-Version: 1.0 References: <20230427200409.1785263-1-sdf@google.com> X-Mailer: git-send-email 2.40.1.495.gc816e09b53d-goog Message-ID: <20230427200409.1785263-5-sdf@google.com> Subject: [PATCH bpf-next v2 4/4] bpf: Document EFAULT changes for sockopt From: Stanislav Fomichev To: bpf@vger.kernel.org Cc: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, martin.lau@linux.dev, song@kernel.org, yhs@fb.com, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, jolsa@kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net And add examples for how to correctly handle large optlens. This is less relevant now when we don't EFAULT anymore, but that's still the correct thing to do. Signed-off-by: Stanislav Fomichev --- Documentation/bpf/prog_cgroup_sockopt.rst | 57 ++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/Documentation/bpf/prog_cgroup_sockopt.rst b/Documentation/bpf/prog_cgroup_sockopt.rst index 172f957204bf..d5cca25135b6 100644 --- a/Documentation/bpf/prog_cgroup_sockopt.rst +++ b/Documentation/bpf/prog_cgroup_sockopt.rst @@ -98,10 +98,65 @@ When the ``optval`` is greater than the ``PAGE_SIZE``, the BPF program indicates that the kernel should use BPF's trimmed ``optval``. When the BPF program returns with the ``optlen`` greater than -``PAGE_SIZE``, the userspace will receive ``EFAULT`` errno. +``PAGE_SIZE``, the userspace will receive original kernel +buffers without any modifications that the BPF program might have +applied. Example ======= +Recommended way to handle BPF programs is as follows: + +.. code-block:: c + + SEC("cgroup/getsockopt") + int getsockopt(struct bpf_sockopt *ctx) + { + /* Custom socket option. */ + if (ctx->level == MY_SOL && ctx->optname == MY_OPTNAME) { + ctx->retval = 0; + optval[0] = ...; + ctx->optlen = 1; + return 1; + } + + /* Modify kernel's socket option. */ + if (ctx->level == SOL_IP && ctx->optname == IP_FREEBIND) { + ctx->retval = 0; + optval[0] = ...; + ctx->optlen = 1; + return 1; + } + + /* optval larger than PAGE_SIZE use kernel's buffer. */ + if (ctx->optlen > 4096) + ctx->optlen = 0; + + return 1; + } + + SEC("cgroup/setsockopt") + int setsockopt(struct bpf_sockopt *ctx) + { + /* Custom socket option. */ + if (ctx->level == MY_SOL && ctx->optname == MY_OPTNAME) { + /* do something */ + ctx->optlen = -1; + return 1; + } + + /* Modify kernel's socket option. */ + if (ctx->level == SOL_IP && ctx->optname == IP_FREEBIND) { + optval[0] = ...; + return 1; + } + + /* optval larger than PAGE_SIZE use kernel's buffer. */ + if (ctx->optlen > 4096) + ctx->optlen = 0; + + return 1; + } + See ``tools/testing/selftests/bpf/progs/sockopt_sk.c`` for an example of BPF program that handles socket options.