From patchwork Fri Mar 19 23:56:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Piotr Krysiuk X-Patchwork-Id: 405383 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9ABB1C433C1 for ; Fri, 19 Mar 2021 23:57:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5532861940 for ; Fri, 19 Mar 2021 23:57:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229723AbhCSX5D (ORCPT ); Fri, 19 Mar 2021 19:57:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36678 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229748AbhCSX4a (ORCPT ); Fri, 19 Mar 2021 19:56:30 -0400 Received: from mail-wm1-x32f.google.com (mail-wm1-x32f.google.com [IPv6:2a00:1450:4864:20::32f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 53D76C061760 for ; Fri, 19 Mar 2021 16:56:30 -0700 (PDT) Received: by mail-wm1-x32f.google.com with SMTP id d191so6256970wmd.2 for ; Fri, 19 Mar 2021 16:56:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to:cc; bh=E68Z9qdAJD/qGpbFLT/yIIqmWpjvQ3RSNWgCpTxieT8=; b=m/CBoo+jYaMnpUavn0NWnggHCFfsgBaWWeD0kG+/EI0G5l9Chzi1Gkbvu7lnW9cDu6 Py/gkm7RJalEAPWVO4xfKOcQZAL/L2TWaI/RT/En+AcRfbo8fxQLUQs7ZuTBJRtgn0JD zZTLDBfehnLSQon7IwFepDfQDkAtJLbWNr0GSx2tKTG1r/E0BZO/8poWX32HbJBG2Rra D/SxjvgOtd6ZDci+CD8bZyai4/g9+jEZM8JXX+2mSRocnMu92+d4poOFOQE5/XnaDZCM BNue1f5bbd97sNRPXNa1SWVVs0kuQXmccg2D211VUAdKR0yV3iA5VlU2Cp4gcRX+UQMM h+1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to:cc; bh=E68Z9qdAJD/qGpbFLT/yIIqmWpjvQ3RSNWgCpTxieT8=; b=LSTgd1Md3r1R/QpvopLyb1w2eM+apNg0ZblUBf+N4Mow0svKBFgLkrKWHSUQS02Wzl fANr6qFFiVyjxyutPI3eD70MBriVws1GyW8PRADxlsY2J4FXe+vBEDl6hKXO/TTFaasN /9ZhOzx47hBhU+khqRzWIIfPdq8r+JVvelMHhaBq1RiXfRvjxR4Os+aGiDKkFWJjd1cZ 2K39ilonv81a3fMR6EKXdSrYDTKlvrm+QBUj6mAXMGBqQfKdgeJ3oSGMkSMfoDJ1Uo77 MmMwM8kwn1wtZpjs2y/FDFZ+GbdW36rrDYmQmoxAtXaFh6buBeaCB2SGbe3s+XGKyARn 6Xww== X-Gm-Message-State: AOAM532r1D63+FLXXVwFxouOZv4v9Ad8rJbIluwF0D090x3ygrbOHx12 E2jwz4BIjZnf1dcksLD57lA0Lt/eI1tMah8Urhsq7zG/s3uyxzAZ X-Google-Smtp-Source: ABdhPJxPzKCCxuSFSj+uZGqUotme0dSVpAsbltHLYl1JYntIYCnGM6rWbyW3abJLasvA7xcqriKMsqf+mtCVeW3GK88= X-Received: by 2002:a1c:df8a:: with SMTP id w132mr5655961wmg.53.1616198188951; Fri, 19 Mar 2021 16:56:28 -0700 (PDT) MIME-Version: 1.0 From: Piotr Krysiuk Date: Fri, 19 Mar 2021 23:56:18 +0000 Message-ID: Subject: bpf speculative execution fixes for 4.14.y To: gregkh@linuxfoundation.org Cc: Alexei Starovoitov , Daniel Borkmann , stable@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org I noticed that bpf speculative execution fixes are already queued for 4.14.y except for f232326f6966 ("bpf: Prohibit alu ops for pointer types not defining ptr_limit"). It is important that for all patches from this series to be applied together, so we avoid introducing a new vulnerability. For the missing patch, I see conflicting lines in the context diffs due to API change that apparently caused import to fail. I'm attaching a copy of the patch that is backported to 4.14.y. The only change comparing with version queued for newer version is that "verbose" API does not take "env" parameter. Please queue or let me know how to proceed. Thanks, Piotr >From f232326f6966cf2a1d1db7bc917a4ce5f9f55f76 Mon Sep 17 00:00:00 2001 From: Piotr Krysiuk Date: Tue, 16 Mar 2021 09:47:02 +0100 Subject: bpf: Prohibit alu ops for pointer types not defining ptr_limit From: Piotr Krysiuk commit f232326f6966cf2a1d1db7bc917a4ce5f9f55f76 upstream. The purpose of this patch is to streamline error propagation and in particular to propagate retrieve_ptr_limit() errors for pointer types that are not defining a ptr_limit such that register-based alu ops against these types can be rejected. The main rationale is that a gap has been identified by Piotr in the existing protection against speculatively out-of-bounds loads, for example, in case of ctx pointers, unprivileged programs can still perform pointer arithmetic. This can be abused to execute speculatively out-of-bounds loads without restrictions and thus extract contents of kernel memory. Fix this by rejecting unprivileged programs that attempt any pointer arithmetic on unprotected pointer types. The two affected ones are pointer to ctx as well as pointer to map. Field access to a modified ctx' pointer is rejected at a later point in time in the verifier, and 7c6967326267 ("bpf: Permit map_ptr arithmetic with opcode add and offset 0") only relevant for root-only use cases. Risk of unprivileged program breakage is considered very low. Fixes: 7c6967326267 ("bpf: Permit map_ptr arithmetic with opcode add and offset 0") Fixes: b2157399cc98 ("bpf: prevent out-of-bounds speculation") Signed-off-by: Piotr Krysiuk Co-developed-by: Daniel Borkmann Signed-off-by: Daniel Borkmann Acked-by: Alexei Starovoitov --- kernel/bpf/verifier.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 4192a9e56654..1c8cbef7cc14 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -5934,6 +5934,7 @@ static int sanitize_ptr_alu(struct bpf_verifier_env *env, u32 alu_state, alu_limit; struct bpf_reg_state tmp; bool ret; + int err; if (can_skip_alu_sanitation(env, insn)) return 0; @@ -5949,10 +5950,13 @@ static int sanitize_ptr_alu(struct bpf_verifier_env *env, alu_state |= ptr_is_dst_reg ? BPF_ALU_SANITIZE_SRC : BPF_ALU_SANITIZE_DST; - if (retrieve_ptr_limit(ptr_reg, &alu_limit, opcode, off_is_neg)) - return 0; - if (update_alu_sanitation_state(aux, alu_state, alu_limit)) - return -EACCES; + err = retrieve_ptr_limit(ptr_reg, &alu_limit, opcode, off_is_neg); + if (err < 0) + return err; + + err = update_alu_sanitation_state(aux, alu_state, alu_limit); + if (err < 0) + return err; do_sim: /* Simulate and find potential out-of-bounds access under * speculative execution from truncation as a result of @@ -6103,7 +6107,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, case BPF_ADD: ret = sanitize_ptr_alu(env, insn, ptr_reg, dst_reg, smin_val < 0); if (ret < 0) { - verbose("R%d tried to add from different maps or paths\n", dst); + verbose("R%d tried to add from different maps, paths, or prohibited types\n", dst); return ret; } /* We can take a fixed offset as long as it doesn't overflow @@ -6158,7 +6162,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, case BPF_SUB: ret = sanitize_ptr_alu(env, insn, ptr_reg, dst_reg, smin_val < 0); if (ret < 0) { - verbose("R%d tried to sub from different maps or paths\n", dst); + verbose("R%d tried to sub from different maps, paths, or prohibited types\n", dst); return ret; } if (dst_reg == off_reg) { -- 2.25.1