Received: by 2002:ab2:3141:0:b0:1ed:23cc:44d1 with SMTP id i1csp134606lqg; Thu, 29 Feb 2024 23:53:26 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCUrwGsNfsDA2VF4S4Zgx2nqVb0uwIgnpOihp+u+xfBJTGAY3ket/xfeplRiU7k08fQGTZj9TBUawtKNXKJOkBqxrckC/XVpT6QmaPIqXw== X-Google-Smtp-Source: AGHT+IFwNViQMQ4t57FRrInhtUMdp+kt7gbokb5Fda+ktEdinukgzKIPqawcQUmlBk/Rt/KPtQ5f X-Received: by 2002:a05:620a:2714:b0:788:e0c:aead with SMTP id b20-20020a05620a271400b007880e0caeadmr249794qkp.8.1709279606060; Thu, 29 Feb 2024 23:53:26 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1709279606; cv=pass; d=google.com; s=arc-20160816; b=MfVnPk2gB6db0JIfwRlpysoA9LxD9WvlgSmutVsvuSKQ1WxBBqOrsxGVOZhoJqOoMO mzKCt5u8wjBIXJmmLdSWVe8yU6r9LdtVcDERn+53Ipv4pMuhPb7DpCj6IV5/EAOvnWM1 4V8Wk21seEn0R+enwM5N5zt653DL3gB3gB80JywJJIY93t4y7CxNs9dRmWb4Ng5wknBB M5xxysLbbZhhiK4+dJ2e4c+ZmN6UFkpY9/jkNXWhCv960YCCoRnx5Td4yrMoETybUMpk L4rm8UC2kUaNEQWH5+KTCO9t6Qj2eZj5dbsW1BBaeuBWPv8BUu6FKXkZqQFeEq8qGN5I 7zng== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from; bh=wPb/lMDcIG1uvpKrwYLOh/d+26kdj7UPHfEjLseFweg=; fh=DCs1jU90vzdwUm4ViyOmiLJZ6g6wWuEHu5W9Hy2+rhs=; b=LmGZqVoio/AF0jA61XOAE+43RY9Yk0fUFO5ceGsrkmfYJ7S5Oo8uZBzedZPH6f0PoI sYGTfRXELM81h4F5bLowjxpoQl/lM5ZY35FCVVmDSsoh8I47jcQBmQWRvMpunquLpGhI ZS9GeJeJb2u0jFSFroA9TC4H3+GKP1pl2TBpNplrdJpAPJgz/OOPQJE1ldLiGFEk8QMz bVqdx42IuN0hKGu/kBk9tG8f9N4OiynmhQkE8SUHQJkdT/RQXW3BR3WxSxo083VyRY9h vhK84YXcwGKK3hF36dvNE8/Xpn4QwVMHY6aSXxtS8KCjQcACG+dWSsy+Uf6djpIRlSyD XoEQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; arc=pass (i=1 spf=pass spfdomain=csgroup.eu dmarc=pass fromdomain=csgroup.eu); spf=pass (google.com: domain of linux-kernel+bounces-88036-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-88036-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=QUARANTINE) header.from=csgroup.eu Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id pe16-20020a05620a851000b00787c4635c2fsi3085358qkn.337.2024.02.29.23.53.25 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Feb 2024 23:53:26 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-88036-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; arc=pass (i=1 spf=pass spfdomain=csgroup.eu dmarc=pass fromdomain=csgroup.eu); spf=pass (google.com: domain of linux-kernel+bounces-88036-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-88036-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=QUARANTINE) header.from=csgroup.eu Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id B8CCD1C22940 for ; Fri, 1 Mar 2024 07:53:25 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id C293269DED; Fri, 1 Mar 2024 07:52:52 +0000 (UTC) Received: from pegase1.c-s.fr (pegase1.c-s.fr [93.17.236.30]) (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 C387769D2C; Fri, 1 Mar 2024 07:52:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=93.17.236.30 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709279571; cv=none; b=MGFCO/W/iynpVk7Oow/LpBEVxdM5DSX/fYMRJ/nugscZeaqaVt9srdgr5wdxaA0gIcGrFQAMveBNC962nsh+2NjkX4kG/dlOKlqExvXJXDyrlVzF/s/OrPxuc9jQBPrOopbovRj1bTGKk2a2zcSYA9UUsdevC+Ub1lRkf6wSKPI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709279571; c=relaxed/simple; bh=GJoGYVYbfZiut87n1nSS7BcfQrTwvw0VTfVTDeXeEWg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=t1XuwGd/pAPeg0goSKf2aBVq1sfLLA669CbdlbBuW0lvLngxcmDOnr1x0Ji4VfWcIwSgEnOx7pkeUwg/oXYqH78iLvJg6XegmxsKaGjAIiaPEVdisEI4FDtmEV3mVUWSOKIPLGfxt0VDiCSr0Nd7kGbu/6k1Twi19oiZ5PECMuM= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=csgroup.eu; spf=pass smtp.mailfrom=csgroup.eu; arc=none smtp.client-ip=93.17.236.30 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=csgroup.eu Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=csgroup.eu Received: from localhost (mailhub3.si.c-s.fr [192.168.12.233]) by localhost (Postfix) with ESMTP id 4TmL0k0ZNqz9tfK; Fri, 1 Mar 2024 08:52:38 +0100 (CET) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase1.c-s.fr ([192.168.12.234]) by localhost (pegase1.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ppBHJeKqOrcf; Fri, 1 Mar 2024 08:52:37 +0100 (CET) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase1.c-s.fr (Postfix) with ESMTP id 4TmL0h5050z9tFS; Fri, 1 Mar 2024 08:52:36 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 9E0878B766; Fri, 1 Mar 2024 08:52:36 +0100 (CET) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id KiSVsXDP8rUo; Fri, 1 Mar 2024 08:52:36 +0100 (CET) Received: from PO20335.idsi0.si.c-s.fr (unknown [192.168.232.117]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 800998B773; Fri, 1 Mar 2024 08:52:34 +0100 (CET) From: Christophe Leroy To: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Eduard Zingerman , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Russell King , Puranjay Mohan , Tiezhu Yang , Hengqi Chen , Huacai Chen , WANG Xuerui , Johan Almbladh , Paul Burton , Thomas Bogendoerfer , "James E.J. Bottomley" , Helge Deller , Ilya Leoshkevich , Heiko Carstens , Vasily Gorbik , Alexander Gordeev , Christian Borntraeger , Sven Schnelle , "David S. Miller" , David Ahern , Wang YanQing , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" Cc: Christophe Leroy , bpf@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, loongarch@lists.linux.dev, linux-mips@vger.kernel.org, linux-parisc@vger.kernel.org, linux-s390@vger.kernel.org, sparclinux@vger.kernel.org, netdev@vger.kernel.org, "linux-hardening @ vger . kernel . org" , Kees Cook Subject: [PATCH net-next v2 2/2] bpf: Take return from set_memory_rox() into account with bpf_jit_binary_lock_ro() Date: Fri, 1 Mar 2024 08:52:25 +0100 Message-ID: <9c0b7a2e25f05c7128adcd04cf33a2df64c82627.1709279160.git.christophe.leroy@csgroup.eu> X-Mailer: git-send-email 2.43.0 In-Reply-To: <8f3b3823cce2177e5912ff5f2f11381a16db07db.1709279160.git.christophe.leroy@csgroup.eu> References: <8f3b3823cce2177e5912ff5f2f11381a16db07db.1709279160.git.christophe.leroy@csgroup.eu> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1709279548; l=8082; i=christophe.leroy@csgroup.eu; s=20211009; h=from:subject:message-id; bh=GJoGYVYbfZiut87n1nSS7BcfQrTwvw0VTfVTDeXeEWg=; b=xNJLs+iv2tmlj/BIX3EoYGlX/P3yvA7lrReNe1X9Mqz3l+X3UKz9yXHwuaQ0ygmCUhOAtBWQa KaTAubgOKjbDbakW2C/tdnSmE9IOUcm+oy44pDfmDDMuu7utTRrbVLt X-Developer-Key: i=christophe.leroy@csgroup.eu; a=ed25519; pk=HIzTzUj91asvincQGOFx6+ZF5AoUuP9GdOtQChs7Mm0= Content-Transfer-Encoding: 8bit set_memory_rox() can fail, leaving memory unprotected. Check return and bail out when bpf_jit_binary_lock_ro() returns an error. Link: https://github.com/KSPP/linux/issues/7 Signed-off-by: Christophe Leroy Cc: linux-hardening@vger.kernel.org Reviewed-by: Kees Cook Reviewed-by: Puranjay Mohan Reviewed-by: Ilya Leoshkevich # s390x Acked-by: Tiezhu Yang # LoongArch Reviewed-by: Johan Almbladh # MIPS Part --- Previous patch introduces a dependency on this patch because it modifies bpf_prog_lock_ro(), but they are independant. It is possible to apply this patch as standalone by handling trivial conflict with unmodified bpf_prog_lock_ro(). v2: - Dropped arm64 change following commit 1dad391daef1 ("bpf, arm64: use bpf_prog_pack for memory management") - Fixed too long lines reported by checkpatch --- arch/arm/net/bpf_jit_32.c | 25 ++++++++++++------------- arch/loongarch/net/bpf_jit.c | 22 ++++++++++++++++------ arch/mips/net/bpf_jit_comp.c | 3 ++- arch/parisc/net/bpf_jit_core.c | 8 +++++++- arch/s390/net/bpf_jit_comp.c | 6 +++++- arch/sparc/net/bpf_jit_comp_64.c | 6 +++++- arch/x86/net/bpf_jit_comp32.c | 3 +-- include/linux/filter.h | 5 +++-- 8 files changed, 51 insertions(+), 27 deletions(-) diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c index 1d672457d02f..01516f83a95a 100644 --- a/arch/arm/net/bpf_jit_32.c +++ b/arch/arm/net/bpf_jit_32.c @@ -2222,28 +2222,21 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) /* If building the body of the JITed code fails somehow, * we fall back to the interpretation. */ - if (build_body(&ctx) < 0) { - image_ptr = NULL; - bpf_jit_binary_free(header); - prog = orig_prog; - goto out_imms; - } + if (build_body(&ctx) < 0) + goto out_free; build_epilogue(&ctx); /* 3.) Extra pass to validate JITed Code */ - if (validate_code(&ctx)) { - image_ptr = NULL; - bpf_jit_binary_free(header); - prog = orig_prog; - goto out_imms; - } + if (validate_code(&ctx)) + goto out_free; flush_icache_range((u32)header, (u32)(ctx.target + ctx.idx)); if (bpf_jit_enable > 1) /* there are 2 passes here */ bpf_jit_dump(prog->len, image_size, 2, ctx.target); - bpf_jit_binary_lock_ro(header); + if (bpf_jit_binary_lock_ro(header)) + goto out_free; prog->bpf_func = (void *)ctx.target; prog->jited = 1; prog->jited_len = image_size; @@ -2260,5 +2253,11 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) bpf_jit_prog_release_other(prog, prog == orig_prog ? tmp : orig_prog); return prog; + +out_free: + image_ptr = NULL; + bpf_jit_binary_free(header); + prog = orig_prog; + goto out_imms; } diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c index e73323d759d0..7dbefd4ba210 100644 --- a/arch/loongarch/net/bpf_jit.c +++ b/arch/loongarch/net/bpf_jit.c @@ -1294,16 +1294,19 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) flush_icache_range((unsigned long)header, (unsigned long)(ctx.image + ctx.idx)); if (!prog->is_func || extra_pass) { + int err; + if (extra_pass && ctx.idx != jit_data->ctx.idx) { pr_err_once("multi-func JIT bug %d != %d\n", ctx.idx, jit_data->ctx.idx); - bpf_jit_binary_free(header); - prog->bpf_func = NULL; - prog->jited = 0; - prog->jited_len = 0; - goto out_offset; + goto out_free; + } + err = bpf_jit_binary_lock_ro(header); + if (err) { + pr_err_once("bpf_jit_binary_lock_ro() returned %d\n", + err); + goto out_free; } - bpf_jit_binary_lock_ro(header); } else { jit_data->ctx = ctx; jit_data->image = image_ptr; @@ -1334,6 +1337,13 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) out_offset = -1; return prog; + +out_free: + bpf_jit_binary_free(header); + prog->bpf_func = NULL; + prog->jited = 0; + prog->jited_len = 0; + goto out_offset; } /* Indicate the JIT backend supports mixing bpf2bpf and tailcalls. */ diff --git a/arch/mips/net/bpf_jit_comp.c b/arch/mips/net/bpf_jit_comp.c index a40d926b6513..e355dfca4400 100644 --- a/arch/mips/net/bpf_jit_comp.c +++ b/arch/mips/net/bpf_jit_comp.c @@ -1012,7 +1012,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) bpf_prog_fill_jited_linfo(prog, &ctx.descriptors[1]); /* Set as read-only exec and flush instruction cache */ - bpf_jit_binary_lock_ro(header); + if (bpf_jit_binary_lock_ro(header)) + goto out_err; flush_icache_range((unsigned long)header, (unsigned long)&ctx.target[ctx.jit_index]); diff --git a/arch/parisc/net/bpf_jit_core.c b/arch/parisc/net/bpf_jit_core.c index d6ee2fd45550..979f45d4d1fb 100644 --- a/arch/parisc/net/bpf_jit_core.c +++ b/arch/parisc/net/bpf_jit_core.c @@ -167,7 +167,13 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) bpf_flush_icache(jit_data->header, ctx->insns + ctx->ninsns); if (!prog->is_func || extra_pass) { - bpf_jit_binary_lock_ro(jit_data->header); + if (bpf_jit_binary_lock_ro(jit_data->header)) { + bpf_jit_binary_free(jit_data->header); + prog->bpf_func = NULL; + prog->jited = 0; + prog->jited_len = 0; + goto out_offset; + } prologue_len = ctx->epilogue_offset - ctx->body_len; for (i = 0; i < prog->len; i++) ctx->offset[i] += prologue_len; diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index b418333bb086..e613eebfd349 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c @@ -2111,7 +2111,11 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp) print_fn_code(jit.prg_buf, jit.size_prg); } if (!fp->is_func || extra_pass) { - bpf_jit_binary_lock_ro(header); + if (bpf_jit_binary_lock_ro(header)) { + bpf_jit_binary_free(header); + fp = orig_fp; + goto free_addrs; + } } else { jit_data->header = header; jit_data->ctx = jit; diff --git a/arch/sparc/net/bpf_jit_comp_64.c b/arch/sparc/net/bpf_jit_comp_64.c index fa0759bfe498..73bf0aea8baf 100644 --- a/arch/sparc/net/bpf_jit_comp_64.c +++ b/arch/sparc/net/bpf_jit_comp_64.c @@ -1602,7 +1602,11 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) bpf_flush_icache(header, (u8 *)header + header->size); if (!prog->is_func || extra_pass) { - bpf_jit_binary_lock_ro(header); + if (bpf_jit_binary_lock_ro(header)) { + bpf_jit_binary_free(header); + prog = orig_prog; + goto out_off; + } } else { jit_data->ctx = ctx; jit_data->image = image_ptr; diff --git a/arch/x86/net/bpf_jit_comp32.c b/arch/x86/net/bpf_jit_comp32.c index b18ce19981ec..f2be1dcf3b24 100644 --- a/arch/x86/net/bpf_jit_comp32.c +++ b/arch/x86/net/bpf_jit_comp32.c @@ -2600,8 +2600,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) if (bpf_jit_enable > 1) bpf_jit_dump(prog->len, proglen, pass + 1, image); - if (image) { - bpf_jit_binary_lock_ro(header); + if (image && !bpf_jit_binary_lock_ro(header)) { prog->bpf_func = (void *)image; prog->jited = 1; prog->jited_len = proglen; diff --git a/include/linux/filter.h b/include/linux/filter.h index 7dd59bccaeec..fc42dcfdbd62 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -895,10 +895,11 @@ static inline int __must_check bpf_prog_lock_ro(struct bpf_prog *fp) return 0; } -static inline void bpf_jit_binary_lock_ro(struct bpf_binary_header *hdr) +static inline int __must_check +bpf_jit_binary_lock_ro(struct bpf_binary_header *hdr) { set_vm_flush_reset_perms(hdr); - set_memory_rox((unsigned long)hdr, hdr->size >> PAGE_SHIFT); + return set_memory_rox((unsigned long)hdr, hdr->size >> PAGE_SHIFT); } int sk_filter_trim_cap(struct sock *sk, struct sk_buff *skb, unsigned int cap); -- 2.43.0