From nobody Thu Apr 2 21:32:09 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=chromium.org ARC-Seal: i=1; a=rsa-sha256; t=1663701762; cv=none; d=zohomail.com; s=zohoarc; b=YPnvKwPO3cDrDDxvoypcAEWN5W5ag3QMMFudDu3/JmbMSxjl8HJRnuQpQf6R950ltv4ocAJizABFVc0/WBuLyP+A57wQqE14V5pxeuTxaPBI3BTU9007qvJXVdpcfbs7whcWjs9LlEtqn7dCFC/0R+wFEorabq2nm88z//OFOA8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1663701762; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=mRkb49hJ/o7sUzNJw/zHfFKhjBVcyGD1caVksculA00=; b=j9Eq9INwPPFLgtmWkBC3RjBBL28xEiULT1+syU8W3+JvqjIbH+3s3LHU1/wdEfH2wN6CBDxQdyUmVxUaHX3ECmfxC5kGVe3f78tldllVO56ywn518v7PKm7FK+a3l1PXPW9ZhA7hmnpJQLqnltC7vdXjhotEzxw98dCTNhcNHHw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1663701762314762.5644384773116; Tue, 20 Sep 2022 12:22:42 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.409564.652542 (Exim 4.92) (envelope-from ) id 1oaiow-0004QW-HY; Tue, 20 Sep 2022 19:22:14 +0000 Received: by outflank-mailman (output) from mailman id 409564.652542; Tue, 20 Sep 2022 19:22:14 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1oaiow-0004QP-Eq; Tue, 20 Sep 2022 19:22:14 +0000 Received: by outflank-mailman (input) for mailman id 409564; Tue, 20 Sep 2022 19:22:12 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1oaiou-0004QJ-Nc for xen-devel@lists.xenproject.org; Tue, 20 Sep 2022 19:22:12 +0000 Received: from mail-pj1-x102f.google.com (mail-pj1-x102f.google.com [2607:f8b0:4864:20::102f]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 85a2c9aa-3919-11ed-9647-05401a9f4f97; Tue, 20 Sep 2022 21:22:10 +0200 (CEST) Received: by mail-pj1-x102f.google.com with SMTP id fv3so4179847pjb.0 for ; Tue, 20 Sep 2022 12:22:10 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id i62-20020a17090a3dc400b001facf455c91sm286910pjc.21.2022.09.20.12.22.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Sep 2022 12:22:08 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 85a2c9aa-3919-11ed-9647-05401a9f4f97 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date; bh=mRkb49hJ/o7sUzNJw/zHfFKhjBVcyGD1caVksculA00=; b=PCUI69eggGWeXyBeTxep9IHUaH7o4uqq9Tn6NaYKT/NYgVgrpRX6+8DhNeX3ewe9ey clzFXuBXIjdIDBwAb0H1OJggBDLLvppduw51miVUkus5CCOXfCg6GLFkPmuoAUvBdVwx pWo63368x3lb04WlSCci+u5M/slQQLEVz5BeA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=mRkb49hJ/o7sUzNJw/zHfFKhjBVcyGD1caVksculA00=; b=axC7ZFY9vKrSTrfNiDnHbTnEI3iaLxdxmHn0rruPKNk9vq4WalW7JKTzGBpZbEhY9M kywPWHnOc37TxfeJuTHZLmeEM7QUtLwxmKGSLsJjOLO3wtuMeQ4Z8m3s4uCafwxJRRq2 6gYcyxXAeWXT2agdhCnT+xM2n9MwMx9qhdB9ZOkBrzkSm9nXPs3bB3yAzkDzy3hUotFg Iigre5UEmtnxuimkxf+qxJlYMwVqPoPoCAp1jOmEUHIqSitpaMuJ2cnT+npROqiiZNJY viDbapFNXZXN4BxqsgOu0I0lpou1CuhAm5iHBtnFR3kVdlCA7aVD/qyHOQ9WL99Oa4mn kJDg== X-Gm-Message-State: ACrzQf1gVDDfI0XAhwOZSzaNQZQ9eRN40PjzPiEYlbszRSGjkiQuLhir 5ubcCAnOkqBCRzoiBXBMccN4KQ== X-Google-Smtp-Source: AMsMyM761d7Fl9dtnwBzIqTJhW7NDE0KfYgW2Z3zOf5cFMrONbSUwHk2/D83vjqkbY1Tqo6olp+d4w== X-Received: by 2002:a17:903:1248:b0:172:f3c7:97a6 with SMTP id u8-20020a170903124800b00172f3c797a6mr1097776plh.128.1663701729091; Tue, 20 Sep 2022 12:22:09 -0700 (PDT) From: Kees Cook To: linux-hardening@vger.kernel.org Cc: Kees Cook , Juergen Gross , Boris Ostrovsky , Nathan Chancellor , Nick Desaulniers , xen-devel@lists.xenproject.org, llvm@lists.linux.dev, Siddhesh Poyarekar , Arnd Bergmann , Tom Rix , Miguel Ojeda , linux-kernel@vger.kernel.org Subject: [PATCH 1/4] x86/entry: Work around Clang __bdos() bug Date: Tue, 20 Sep 2022 12:21:59 -0700 Message-Id: <20220920192202.190793-2-keescook@chromium.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220920192202.190793-1-keescook@chromium.org> References: <20220920192202.190793-1-keescook@chromium.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1979; h=from:subject; bh=4MnVaPsx8mraEdez/1qUw/f+9P/3EjkrM/1wqdGlA2Y=; b=owEBbQKS/ZANAwAKAYly9N/cbcAmAcsmYgBjKhLZE7kAhe/OxfUVwh8eyd4pKAVAQvW03irD5DAW qRCvxvmJAjMEAAEKAB0WIQSlw/aPIp3WD3I+bhOJcvTf3G3AJgUCYyoS2QAKCRCJcvTf3G3AJuSWD/ 0YU5lJR6Qasvy4L3d9D2h5U5JWrfw5lBGb341IHXohJFP1UnzRH0CT/UnomvYDoLvjhR2joksvkjkn BNTSv7VoRq4RwprCdKG4kgHD8PGjx57z3qsj73lXyfUXt1MwvQB9y+YDpD/SE2IuUFQpf+4iZ2uEtn LvLw9kT0MNmAnaM2dSR5lA6wrcdt9dcqBf4C1O80RyWBKBnfJN2tT3TskZggBrAyk2Y4VxfAOg9UF2 vTENn7pVEn7EisxLJ6/wCFt835Ov9Op7ldWqez4GSVVxpyhYW3zjEzqFOZ1Jwto62iUKdM+V83O8ew rjJ/WRDJT6EN225b5IvYvTHVC742B3/OkrjefYwWsKruTy7sR4aGoXrx6gtHOCfsncloYhZnF1ayiE /BA9ncPIH958gJ01gz7eZndZ2kkOAFTm3BBIZ/Rm8ISXObKAWBd6rFb0MBYeVza2e4fbwvVJfgTG9H tv86FQuDi0OhoT1JbgJrNbf/GhLz8PegmQUKUoAhXk9LrWby/jti9NoGokj6bJKjjtuORb0ETDHUJU WM+b2N7anNSPw/Sovfcx5bkbvOrenXO1PW7ByUj5o5/nal3mnvLFtWS7g3Z17XB5ybO8nxngnjb9NG Fcmwv0P7fktHuuT0QNwTw4WG5vmaMeqDZTTYXOKsbqzpoOfwlI1qO6qXA0jQ== X-Developer-Key: i=keescook@chromium.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @chromium.org) X-ZM-MESSAGEID: 1663701763971100001 Content-Type: text/plain; charset="utf-8" After expanding bounds checking to use __builtin_dynamic_object_size(), Clang produces a false positive when building with CONFIG_FORTIFY_SOURCE=3Dy and CONFIG_UBSAN_BOUNDS=3Dy when operating on an array with a dynamic offset. Work around this by using a direct assignment of an empty instance. Avoids this warning: ../include/linux/fortify-string.h:309:4: warning: call to __write_overflow_= field declared with 'warn ing' attribute: detected write beyond size of field (1st parameter); maybe = use struct_group()? [-Wat tribute-warning] __write_overflow_field(p_size_field, size); ^ which was isolated to the memset() call in xen_load_idt(). Note that this looks very much like another bug that was worked around: https://github.com/ClangBuiltLinux/linux/issues/1592 Cc: Juergen Gross Cc: Boris Ostrovsky Cc: Nathan Chancellor Cc: Nick Desaulniers Cc: xen-devel@lists.xenproject.org Cc: llvm@lists.linux.dev Signed-off-by: Kees Cook Reviewed-by: Boris Ostrovsky --- arch/x86/xen/enlighten_pv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c index 0ed2e487a693..9b1a58dda935 100644 --- a/arch/x86/xen/enlighten_pv.c +++ b/arch/x86/xen/enlighten_pv.c @@ -765,6 +765,7 @@ static void xen_load_idt(const struct desc_ptr *desc) { static DEFINE_SPINLOCK(lock); static struct trap_info traps[257]; + static const struct trap_info zero =3D { }; unsigned out; =20 trace_xen_cpu_load_idt(desc); @@ -774,7 +775,7 @@ static void xen_load_idt(const struct desc_ptr *desc) memcpy(this_cpu_ptr(&idt_desc), desc, sizeof(idt_desc)); =20 out =3D xen_convert_trap_info(desc, traps, false); - memset(&traps[out], 0, sizeof(traps[0])); + traps[out] =3D zero; =20 xen_mc_flush(); if (HYPERVISOR_set_trap_table(traps)) --=20 2.34.1 From nobody Thu Apr 2 21:32:09 2026 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 70546C6FA82 for ; Tue, 20 Sep 2022 19:22:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231309AbiITTWW (ORCPT ); Tue, 20 Sep 2022 15:22:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37364 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231172AbiITTWL (ORCPT ); Tue, 20 Sep 2022 15:22:11 -0400 Received: from mail-pf1-x42d.google.com (mail-pf1-x42d.google.com [IPv6:2607:f8b0:4864:20::42d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3D3112BB29 for ; Tue, 20 Sep 2022 12:22:10 -0700 (PDT) Received: by mail-pf1-x42d.google.com with SMTP id u132so3661514pfc.6 for ; Tue, 20 Sep 2022 12:22:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date; bh=JX0ua+LFqhoPxmKV4FkFTEjLOIsGeEC5zMQTZ7gmmn0=; b=PWP5PK9w7OmL6GItthJmplzUuDG9moNLPk1mcXR9Camj5lYCFnho3xhjAIJ5jFVdQD BnG1hTJQPls+dKR8bJXIqGnHInIPWik0zjjmf2tJQpudCX/SrH/eQGDw6m4VoJNzKtQx hZe6UK4yikBf0kLC1TdwbX1/6fADVBSzEcVcM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=JX0ua+LFqhoPxmKV4FkFTEjLOIsGeEC5zMQTZ7gmmn0=; b=zXnC11s25eqNf52wk+CUEW+fnhXdv7xz8T4d8y04Qsrf0ZmKhmcFOPAs0KfnN3nNv/ MhCrAMI8I+4JcvaNum8aeEZV7JWKblbQrt+QG85puP2r3RF0sU8NZ7vKN25jZtNmBy1t m4iwo5Iz5au4TfwxC1Gkg09QIPBjM+sk/L+vmYHKY3dtBJY1iWt9T2Mo1diQUYZx7a2L ygk6oYYDG5J2CsSabco7SwweTAuWvZVEcAYe91ZOaOFfSGpozMUQdwjOB+bLUM5QXg79 IHWJbKL6HcPysX/xm9bdDei8vnlbXsA/qe7qlflR1mL+RlX2QfIkU+DOf7pyVcnb8nbD gpOw== X-Gm-Message-State: ACrzQf0kLEnIozHAb3f2DewKwvmREFgAY6hTJwXNadNh58E2fo9qo9ur JnFHspgyG9mvle6MpN10GkiciA== X-Google-Smtp-Source: AMsMyM4hPEYquldZYsARoLf9Epv/KmSgPcBvKIvtg1QdMq9AHUvzPJ5F7JBZcSTvNKqzgwJubVJMEg== X-Received: by 2002:a63:81c1:0:b0:439:ff01:ff81 with SMTP id t184-20020a6381c1000000b00439ff01ff81mr12874505pgd.39.1663701729659; Tue, 20 Sep 2022 12:22:09 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id s16-20020aa78bd0000000b0053e7d3b8d6dsm295543pfd.1.2022.09.20.12.22.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Sep 2022 12:22:08 -0700 (PDT) From: Kees Cook To: linux-hardening@vger.kernel.org Cc: Kees Cook , Siddhesh Poyarekar , Nathan Chancellor , Nick Desaulniers , Arnd Bergmann , Juergen Gross , Boris Ostrovsky , Tom Rix , Miguel Ojeda , linux-kernel@vger.kernel.org, llvm@lists.linux.dev Subject: [PATCH 2/4] fortify: Explicitly check bounds are compile-time constants Date: Tue, 20 Sep 2022 12:22:00 -0700 Message-Id: <20220920192202.190793-3-keescook@chromium.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220920192202.190793-1-keescook@chromium.org> References: <20220920192202.190793-1-keescook@chromium.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=6494; h=from:subject; bh=H1LlmpBscaiEe04I7Sh+ZCZmF9ZgzimcwM4cFmtVeLs=; b=owEBbQKS/ZANAwAKAYly9N/cbcAmAcsmYgBjKhLZNwEQUjp9SkNBWAp8JMozzL5lhw11d4e0rr46 SL0SNsGJAjMEAAEKAB0WIQSlw/aPIp3WD3I+bhOJcvTf3G3AJgUCYyoS2QAKCRCJcvTf3G3AJvs7D/ 9VRJeaTb6BW+4YIzT0+1vpKMjjFvHn5Vt8YD9KVShd7IMqv89ggecT7cEPzwYqGULXFFsgBiSMF1eF RQLaTRMR5ET9DQMztatGHuYJM1WoQ9wqcGieTl0s3NfYEknwNaIxb5Do6AvLiy6WLP9YC8rDLOU6jg +9XXHTf0CPxRiD0ZSF9J/S9FG2GTo8TDLLfOv/I51htuw0jhzXDFkGuOXv4k0VpC3ajwZE32iRtsOR KmVQNVPqo/nhKEQyplpeBxIX91oCn4wQR02lg+x7Fa7aXB8oHD7LhnSUpy4wQ3Ns/yG0tmWxfvOmmv rq0ktZA6z33b+Md/dM0CBN8Hs15I3EnViOYjsOb7h3/ou6vD6qhNzYoCGHmlBrEZ2emlCGiti1rMxq 9pkNNpQbxTI/92DbtUQDd5dbji7k0hCyT7aPobMd26ucldxq9F4LiTc+vVyBieBtqNmrNSAqYR1lti L3kgrtO5jJaoS62216+2WDIkVtFsRvHFJv0iqvpdxmFY0l5IH7wlo44icmLQkTSH1w5bEjCuYSQj82 NQbcPMtFm8cWYrSSyJ1drVOW/MUsYOyUY9DUiaTq1w6pZZcWtCaE/3Zph8Zot4spfo3UUcPadycuei DoMLVZPRh0tmtX6CCEzNfHUL3OAUUR+VnrL1n3UnUSa4RSgtuxFZPRpEoSDQ== X-Developer-Key: i=keescook@chromium.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" In preparation for replacing __builtin_object_size() with __builtin_dynamic_object_size(), all the compile-time size checks need to check that the bounds variables are, in fact, known at compile-time. Enforce what was guaranteed with __bos(). In other words, since all uses of __bos() were constant expressions, it was not required to test for this. When these change to __bdos(), they _may_ be constant expressions, and the checks are only valid when the prior condition holds. This results in no binary differences. Signed-off-by: Kees Cook --- include/linux/fortify-string.h | 50 +++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h index ff879efe94ed..71c0a432c638 100644 --- a/include/linux/fortify-string.h +++ b/include/linux/fortify-string.h @@ -80,6 +80,12 @@ extern char *__underlying_strncpy(char *p, const char *q= , __kernel_size_t size) #define POS __pass_object_size(1) #define POS0 __pass_object_size(0) =20 +#define __compiletime_lessthan(bounds, length) ( \ + __builtin_constant_p(length) && \ + __builtin_constant_p(bounds) && \ + bounds < length \ +) + /** * strncpy - Copy a string to memory with non-guaranteed NUL padding * @@ -117,7 +123,7 @@ char *strncpy(char * const POS p, const char *q, __kern= el_size_t size) { size_t p_size =3D __builtin_object_size(p, 1); =20 - if (__builtin_constant_p(size) && p_size < size) + if (__compiletime_lessthan(p_size, size)) __write_overflow(); if (p_size < size) fortify_panic(__func__); @@ -224,7 +230,7 @@ __FORTIFY_INLINE ssize_t strscpy(char * const POS p, co= nst char * const POS q, s * If size can be known at compile time and is greater than * p_size, generate a compile time write overflow error. */ - if (__builtin_constant_p(size) && size > p_size) + if (__compiletime_lessthan(p_size, size)) __write_overflow(); =20 /* @@ -281,15 +287,16 @@ __FORTIFY_INLINE void fortify_memset_chk(__kernel_siz= e_t size, /* * Length argument is a constant expression, so we * can perform compile-time bounds checking where - * buffer sizes are known. + * buffer sizes are also known at compile time. */ =20 /* Error when size is larger than enclosing struct. */ - if (p_size > p_size_field && p_size < size) + if (__compiletime_lessthan(p_size_field, p_size) && + __compiletime_lessthan(p_size, size)) __write_overflow(); =20 /* Warn when write size is larger than dest field. */ - if (p_size_field < size) + if (__compiletime_lessthan(p_size_field, size)) __write_overflow_field(p_size_field, size); } /* @@ -365,25 +372,28 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_siz= e_t size, /* * Length argument is a constant expression, so we * can perform compile-time bounds checking where - * buffer sizes are known. + * buffer sizes are also known at compile time. */ =20 /* Error when size is larger than enclosing struct. */ - if (p_size > p_size_field && p_size < size) + if (__compiletime_lessthan(p_size_field, p_size) && + __compiletime_lessthan(p_size, size)) __write_overflow(); - if (q_size > q_size_field && q_size < size) + if (__compiletime_lessthan(q_size_field, q_size) && + __compiletime_lessthan(q_size, size)) __read_overflow2(); =20 /* Warn when write size argument larger than dest field. */ - if (p_size_field < size) + if (__compiletime_lessthan(p_size_field, size)) __write_overflow_field(p_size_field, size); /* * Warn for source field over-read when building with W=3D1 * or when an over-write happened, so both can be fixed at * the same time. */ - if ((IS_ENABLED(KBUILD_EXTRA_WARN1) || p_size_field < size) && - q_size_field < size) + if ((IS_ENABLED(KBUILD_EXTRA_WARN1) || + __compiletime_lessthan(p_size_field, size)) && + __compiletime_lessthan(q_size_field, size)) __read_overflow2_field(q_size_field, size); } /* @@ -494,7 +504,7 @@ __FORTIFY_INLINE void *memscan(void * const POS0 p, int= c, __kernel_size_t size) { size_t p_size =3D __builtin_object_size(p, 0); =20 - if (__builtin_constant_p(size) && p_size < size) + if (__compiletime_lessthan(p_size, size)) __read_overflow(); if (p_size < size) fortify_panic(__func__); @@ -508,9 +518,9 @@ int memcmp(const void * const POS0 p, const void * cons= t POS0 q, __kernel_size_t size_t q_size =3D __builtin_object_size(q, 0); =20 if (__builtin_constant_p(size)) { - if (p_size < size) + if (__compiletime_lessthan(p_size, size)) __read_overflow(); - if (q_size < size) + if (__compiletime_lessthan(q_size, size)) __read_overflow2(); } if (p_size < size || q_size < size) @@ -523,7 +533,7 @@ void *memchr(const void * const POS0 p, int c, __kernel= _size_t size) { size_t p_size =3D __builtin_object_size(p, 0); =20 - if (__builtin_constant_p(size) && p_size < size) + if (__compiletime_lessthan(p_size, size)) __read_overflow(); if (p_size < size) fortify_panic(__func__); @@ -535,7 +545,7 @@ __FORTIFY_INLINE void *memchr_inv(const void * const PO= S0 p, int c, size_t size) { size_t p_size =3D __builtin_object_size(p, 0); =20 - if (__builtin_constant_p(size) && p_size < size) + if (__compiletime_lessthan(p_size, size)) __read_overflow(); if (p_size < size) fortify_panic(__func__); @@ -547,7 +557,7 @@ __FORTIFY_INLINE void *kmemdup(const void * const POS0 = p, size_t size, gfp_t gfp { size_t p_size =3D __builtin_object_size(p, 0); =20 - if (__builtin_constant_p(size) && p_size < size) + if (__compiletime_lessthan(p_size, size)) __read_overflow(); if (p_size < size) fortify_panic(__func__); @@ -563,11 +573,13 @@ char *strcpy(char * const POS p, const char * const P= OS q) size_t size; =20 /* If neither buffer size is known, immediately give up. */ - if (p_size =3D=3D SIZE_MAX && q_size =3D=3D SIZE_MAX) + if (__builtin_constant_p(p_size) && + __builtin_constant_p(q_size) && + p_size =3D=3D SIZE_MAX && q_size =3D=3D SIZE_MAX) return __underlying_strcpy(p, q); size =3D strlen(q) + 1; /* Compile-time check for const size overflow. */ - if (__builtin_constant_p(size) && p_size < size) + if (__compiletime_lessthan(p_size, size)) __write_overflow(); /* Run-time check for dynamic size overflow. */ if (p_size < size) --=20 2.34.1 From nobody Thu Apr 2 21:32:09 2026 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 2223AC6FA82 for ; Tue, 20 Sep 2022 19:22:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231287AbiITTW0 (ORCPT ); Tue, 20 Sep 2022 15:22:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37440 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231263AbiITTWN (ORCPT ); Tue, 20 Sep 2022 15:22:13 -0400 Received: from mail-pl1-x62c.google.com (mail-pl1-x62c.google.com [IPv6:2607:f8b0:4864:20::62c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 895C128E26 for ; Tue, 20 Sep 2022 12:22:12 -0700 (PDT) Received: by mail-pl1-x62c.google.com with SMTP id c24so3404967plo.3 for ; Tue, 20 Sep 2022 12:22:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date; bh=b7FvkRf/XameI3tAxI0qKDnPDgul0cfpqZiW5Ih+TfY=; b=G0yzd3YQmRHSm8hygGaJN23uIfHcIPVonGOjkqyNWhgM4CENWufgxK3rc2ksXWFaq5 W1pvS4BzvsxlUiZWzbHjFUgvT7hopNCjL7/IfebtaUkJyqFyjRtP+IPnqn4y0na+dKs7 J0wWa6WM4Qv2DbhPAozS3qg50xwRRqP+oeG5E= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=b7FvkRf/XameI3tAxI0qKDnPDgul0cfpqZiW5Ih+TfY=; b=b33tmwrHaxGL9R11PWf73rqkgnLTEsc6TMxNAT31EJRZd59cRmF0K+zwrXGQbTBPjw M0DbItsH+ARKxTSpkqBvDvqbfr045ntBW9tOtMy73QMzhdKMe1+cO3h1YiYfnhGQ8Vt9 1TumnySpn9gIWodFm8x0JSiFZ/FkN1ua+pUQ2JtiZIExRzVpfmxKHcQZBslRD7iFGTPQ jHMFXwbxSw/Luqivdf1tpBvNQ+KU2kap3xjQatZOJmA0U2axdd/S/X3LMGAf8WU3wxS0 cKM25Eb+aX/Txz6hLbh9KsGYPZdZzPIPWQzRTjn/h41MDBRkEhCOBbbNbSf4NAQffZIW oPxA== X-Gm-Message-State: ACrzQf3Awow2vgz+3MCozyWLarpIDhJuc8oWWBxMT2roActHC6x72rbp 4Xjnyzy5cdNHGNqXsKjP0zPs1w== X-Google-Smtp-Source: AMsMyM4MlWS2VfZxaUxG/J/yjFdlpSdd1ttEqoJXydSzcYurOBNsEyN3/lJvRpJhe6BzL1xIb54Ykg== X-Received: by 2002:a17:902:dac7:b0:178:b5e0:3627 with SMTP id q7-20020a170902dac700b00178b5e03627mr1050536plx.147.1663701732000; Tue, 20 Sep 2022 12:22:12 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id d10-20020a170902ceca00b0017732e4003bsm262226plg.141.2022.09.20.12.22.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Sep 2022 12:22:08 -0700 (PDT) From: Kees Cook To: linux-hardening@vger.kernel.org Cc: Kees Cook , Nathan Chancellor , Nick Desaulniers , Tom Rix , llvm@lists.linux.dev, Siddhesh Poyarekar , Arnd Bergmann , Juergen Gross , Boris Ostrovsky , Miguel Ojeda , linux-kernel@vger.kernel.org Subject: [PATCH 3/4] fortify: Convert to struct vs member helpers Date: Tue, 20 Sep 2022 12:22:01 -0700 Message-Id: <20220920192202.190793-4-keescook@chromium.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220920192202.190793-1-keescook@chromium.org> References: <20220920192202.190793-1-keescook@chromium.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=9864; h=from:subject; bh=BqQbiGaquIsbcMOqf8A6fSRC6Vfu8ZKyxxnc+qe3hgU=; b=owEBbQKS/ZANAwAKAYly9N/cbcAmAcsmYgBjKhLZ0Oxez6IX/gcUwsIFv3+tMCVKvwgPQj27qPt8 VXbpHlqJAjMEAAEKAB0WIQSlw/aPIp3WD3I+bhOJcvTf3G3AJgUCYyoS2QAKCRCJcvTf3G3AJkDdD/ 4q2zvDS9l/L4s2sAzrxtBwCZUnHjkBHzcdbXLIMLWrIepT/FQAM3Kk2z7w84mjlNBeiW0infuj23MH o1u1RPvNkHf9A/+vRJfGs21mJA+0+Fav4YMboXMqbp1hpIx9YxW9JJ7dJrkRGNpfLXY8n8t3jCRi7n FEUyBKp81hcgHgWxILxQ8mIqLf75AZxwCUyrTAcu8LyNbCR9O+buVloQ8tKdiGsET+3CYTF5KbLYhb PJeWtRKVBFO8QAOIWoWwkdCTn0mgfIKMzevZ3SZd7vuIF28ExS9VX9Oh+BSrYWN5SKR2+5VFypcVyM ln6dH04dg2abuCq7Dvft9pCN2OjVZZjmMU3qoVx69WaD4hViFuGBRXfS+PUAUtWOHwNPlrHkedlukV KkHl1OLS0ueDpoNZ2MkiKtuKGyxPs3lwC06Tp/uPgdzmCJbdwQzzS2MoZx3bXLRcfvr7jhUJmtSrD0 CpwYhQzocUF7Qz0exEUjIgOZwzkx/BgRoMxGD8aftpAzOCjXb95k3wQJDgSIspogue2cLDWwg1EP28 o9opm3tYeLVcIM89XXxu1rGM0jA8ZkfQAdK3ZFmCaB93ai7/BZOAdlB+ElB/7qtXaUgLZpaKmV0XBj wSrPBqjrKEijV2hEVqi7xjlhTwUdHp9HrHTrE7G1vvC0P0Q3TTyMo/sDet/A== X-Developer-Key: i=keescook@chromium.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" In preparation for adding support for __builtin_dynamic_object_size(), wrap each instance of __builtin_object_size(p, N) with either the new __struct_size(p) as __bos(p, 0), or __member_size(p) as __bos(p, 1). This will allow us to replace the definitions with __bdos() next. There are no binary differences from this change. Cc: Nathan Chancellor Cc: Nick Desaulniers Cc: Tom Rix Cc: linux-hardening@vger.kernel.org Cc: llvm@lists.linux.dev Signed-off-by: Kees Cook --- include/linux/fortify-string.h | 68 +++++++++++++++++----------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h index 71c0a432c638..3f1178584d7b 100644 --- a/include/linux/fortify-string.h +++ b/include/linux/fortify-string.h @@ -20,7 +20,7 @@ void __write_overflow_field(size_t avail, size_t wanted) = __compiletime_warning(" ({ \ unsigned char *__p =3D (unsigned char *)(p); \ size_t __ret =3D SIZE_MAX; \ - size_t __p_size =3D __builtin_object_size(p, 1); \ + size_t __p_size =3D __member_size(p); \ if (__p_size !=3D SIZE_MAX && \ __builtin_constant_p(*__p)) { \ size_t __p_len =3D __p_size - 1; \ @@ -72,13 +72,15 @@ extern char *__underlying_strncpy(char *p, const char *= q, __kernel_size_t size) __underlying_memcpy(dst, src, bytes) =20 /* - * Clang's use of __builtin_object_size() within inlines needs hinting via - * __pass_object_size(). The preference is to only ever use type 1 (member + * Clang's use of __builtin_*object_size() within inlines needs hinting via + * __pass_*object_size(). The preference is to only ever use type 1 (member * size, rather than struct size), but there remain some stragglers using * type 0 that will be converted in the future. */ -#define POS __pass_object_size(1) -#define POS0 __pass_object_size(0) +#define POS __pass_object_size(1) +#define POS0 __pass_object_size(0) +#define __struct_size(p) __builtin_object_size(p, 0) +#define __member_size(p) __builtin_object_size(p, 1) =20 #define __compiletime_lessthan(bounds, length) ( \ __builtin_constant_p(length) && \ @@ -121,7 +123,7 @@ extern char *__underlying_strncpy(char *p, const char *= q, __kernel_size_t size) __FORTIFY_INLINE __diagnose_as(__builtin_strncpy, 1, 2, 3) char *strncpy(char * const POS p, const char *q, __kernel_size_t size) { - size_t p_size =3D __builtin_object_size(p, 1); + size_t p_size =3D __member_size(p); =20 if (__compiletime_lessthan(p_size, size)) __write_overflow(); @@ -133,7 +135,7 @@ char *strncpy(char * const POS p, const char *q, __kern= el_size_t size) __FORTIFY_INLINE __diagnose_as(__builtin_strcat, 1, 2) char *strcat(char * const POS p, const char *q) { - size_t p_size =3D __builtin_object_size(p, 1); + size_t p_size =3D __member_size(p); =20 if (p_size =3D=3D SIZE_MAX) return __underlying_strcat(p, q); @@ -145,7 +147,7 @@ char *strcat(char * const POS p, const char *q) extern __kernel_size_t __real_strnlen(const char *, __kernel_size_t) __REN= AME(strnlen); __FORTIFY_INLINE __kernel_size_t strnlen(const char * const POS p, __kerne= l_size_t maxlen) { - size_t p_size =3D __builtin_object_size(p, 1); + size_t p_size =3D __member_size(p); size_t p_len =3D __compiletime_strlen(p); size_t ret; =20 @@ -175,7 +177,7 @@ __FORTIFY_INLINE __diagnose_as(__builtin_strlen, 1) __kernel_size_t __fortify_strlen(const char * const POS p) { __kernel_size_t ret; - size_t p_size =3D __builtin_object_size(p, 1); + size_t p_size =3D __member_size(p); =20 /* Give up if we don't know how large p is. */ if (p_size =3D=3D SIZE_MAX) @@ -190,8 +192,8 @@ __kernel_size_t __fortify_strlen(const char * const POS= p) extern size_t __real_strlcpy(char *, const char *, size_t) __RENAME(strlcp= y); __FORTIFY_INLINE size_t strlcpy(char * const POS p, const char * const POS= q, size_t size) { - size_t p_size =3D __builtin_object_size(p, 1); - size_t q_size =3D __builtin_object_size(q, 1); + size_t p_size =3D __member_size(p); + size_t q_size =3D __member_size(q); size_t q_len; /* Full count of source string length. */ size_t len; /* Count of characters going into destination. */ =20 @@ -219,8 +221,8 @@ __FORTIFY_INLINE ssize_t strscpy(char * const POS p, co= nst char * const POS q, s { size_t len; /* Use string size rather than possible enclosing struct size. */ - size_t p_size =3D __builtin_object_size(p, 1); - size_t q_size =3D __builtin_object_size(q, 1); + size_t p_size =3D __member_size(p); + size_t q_size =3D __member_size(q); =20 /* If we cannot get size of p and q default to call strscpy. */ if (p_size =3D=3D SIZE_MAX && q_size =3D=3D SIZE_MAX) @@ -265,8 +267,8 @@ __FORTIFY_INLINE __diagnose_as(__builtin_strncat, 1, 2,= 3) char *strncat(char * const POS p, const char * const POS q, __kernel_size_= t count) { size_t p_len, copy_len; - size_t p_size =3D __builtin_object_size(p, 1); - size_t q_size =3D __builtin_object_size(q, 1); + size_t p_size =3D __member_size(p); + size_t q_size =3D __member_size(q); =20 if (p_size =3D=3D SIZE_MAX && q_size =3D=3D SIZE_MAX) return __underlying_strncat(p, q, count); @@ -324,11 +326,11 @@ __FORTIFY_INLINE void fortify_memset_chk(__kernel_siz= e_t size, }) =20 /* - * __builtin_object_size() must be captured here to avoid evaluating argum= ent - * side-effects further into the macro layers. + * __struct_size() vs __member_size() must be captured here to avoid + * evaluating argument side-effects further into the macro layers. */ #define memset(p, c, s) __fortify_memset_chk(p, c, s, \ - __builtin_object_size(p, 0), __builtin_object_size(p, 1)) + __struct_size(p), __member_size(p)) =20 /* * To make sure the compiler can enforce protection against buffer overflo= ws, @@ -421,7 +423,7 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_size_= t size, * fake flexible arrays, until they are all converted to * proper flexible arrays. * - * The implementation of __builtin_object_size() behaves + * The implementation of __builtin_*object_size() behaves * like sizeof() when not directly referencing a flexible * array member, which means there will be many bounds checks * that will appear at run-time, without a way for them to be @@ -487,22 +489,22 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_siz= e_t size, */ =20 /* - * __builtin_object_size() must be captured here to avoid evaluating argum= ent - * side-effects further into the macro layers. + * __struct_size() vs __member_size() must be captured here to avoid + * evaluating argument side-effects further into the macro layers. */ #define memcpy(p, q, s) __fortify_memcpy_chk(p, q, s, \ - __builtin_object_size(p, 0), __builtin_object_size(q, 0), \ - __builtin_object_size(p, 1), __builtin_object_size(q, 1), \ + __struct_size(p), __struct_size(q), \ + __member_size(p), __member_size(q), \ memcpy) #define memmove(p, q, s) __fortify_memcpy_chk(p, q, s, \ - __builtin_object_size(p, 0), __builtin_object_size(q, 0), \ - __builtin_object_size(p, 1), __builtin_object_size(q, 1), \ + __struct_size(p), __struct_size(q), \ + __member_size(p), __member_size(q), \ memmove) =20 extern void *__real_memscan(void *, int, __kernel_size_t) __RENAME(memscan= ); __FORTIFY_INLINE void *memscan(void * const POS0 p, int c, __kernel_size_t= size) { - size_t p_size =3D __builtin_object_size(p, 0); + size_t p_size =3D __struct_size(p); =20 if (__compiletime_lessthan(p_size, size)) __read_overflow(); @@ -514,8 +516,8 @@ __FORTIFY_INLINE void *memscan(void * const POS0 p, int= c, __kernel_size_t size) __FORTIFY_INLINE __diagnose_as(__builtin_memcmp, 1, 2, 3) int memcmp(const void * const POS0 p, const void * const POS0 q, __kernel_= size_t size) { - size_t p_size =3D __builtin_object_size(p, 0); - size_t q_size =3D __builtin_object_size(q, 0); + size_t p_size =3D __struct_size(p); + size_t q_size =3D __struct_size(q); =20 if (__builtin_constant_p(size)) { if (__compiletime_lessthan(p_size, size)) @@ -531,7 +533,7 @@ int memcmp(const void * const POS0 p, const void * cons= t POS0 q, __kernel_size_t __FORTIFY_INLINE __diagnose_as(__builtin_memchr, 1, 2, 3) void *memchr(const void * const POS0 p, int c, __kernel_size_t size) { - size_t p_size =3D __builtin_object_size(p, 0); + size_t p_size =3D __struct_size(p); =20 if (__compiletime_lessthan(p_size, size)) __read_overflow(); @@ -543,7 +545,7 @@ void *memchr(const void * const POS0 p, int c, __kernel= _size_t size) void *__real_memchr_inv(const void *s, int c, size_t n) __RENAME(memchr_in= v); __FORTIFY_INLINE void *memchr_inv(const void * const POS0 p, int c, size_t= size) { - size_t p_size =3D __builtin_object_size(p, 0); + size_t p_size =3D __struct_size(p); =20 if (__compiletime_lessthan(p_size, size)) __read_overflow(); @@ -555,7 +557,7 @@ __FORTIFY_INLINE void *memchr_inv(const void * const PO= S0 p, int c, size_t size) extern void *__real_kmemdup(const void *src, size_t len, gfp_t gfp) __RENA= ME(kmemdup); __FORTIFY_INLINE void *kmemdup(const void * const POS0 p, size_t size, gfp= _t gfp) { - size_t p_size =3D __builtin_object_size(p, 0); + size_t p_size =3D __struct_size(p); =20 if (__compiletime_lessthan(p_size, size)) __read_overflow(); @@ -568,8 +570,8 @@ __FORTIFY_INLINE void *kmemdup(const void * const POS0 = p, size_t size, gfp_t gfp __FORTIFY_INLINE __diagnose_as(__builtin_strcpy, 1, 2) char *strcpy(char * const POS p, const char * const POS q) { - size_t p_size =3D __builtin_object_size(p, 1); - size_t q_size =3D __builtin_object_size(q, 1); + size_t p_size =3D __member_size(p); + size_t q_size =3D __member_size(q); size_t size; =20 /* If neither buffer size is known, immediately give up. */ --=20 2.34.1 From nobody Thu Apr 2 21:32:09 2026 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 0A540C6FA82 for ; Tue, 20 Sep 2022 19:22:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231381AbiITTWb (ORCPT ); Tue, 20 Sep 2022 15:22:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37452 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231209AbiITTWO (ORCPT ); Tue, 20 Sep 2022 15:22:14 -0400 Received: from mail-pl1-x635.google.com (mail-pl1-x635.google.com [IPv6:2607:f8b0:4864:20::635]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0FADF33A23 for ; Tue, 20 Sep 2022 12:22:13 -0700 (PDT) Received: by mail-pl1-x635.google.com with SMTP id d24so3400661pls.4 for ; Tue, 20 Sep 2022 12:22:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date; bh=1o1LGpQmDlpzu7Ike/ReIwaogbPO4zuoRH4aws7NQKw=; b=FXsWBJaEckAPDyoDiTuGCNmqPBDHU8OmeUYXqYEhHzpmgSVzhU9z/lEgbkR1kaUI6B pky8QUt2XZ7fpm7bVNYPfwkdR+NnTkqxrOFMRrhG0USUZJIluHryxIkbCc5bM1a2+KcF yKvv2CblYRVdr6M/Ht3buy67ScvtSCu7ccOx4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=1o1LGpQmDlpzu7Ike/ReIwaogbPO4zuoRH4aws7NQKw=; b=UfN0kiTfM6fI7ye4jA1q40sybG66rl83V2bI5BOI2smyxlF3FHXAxL2DuQZZePr4uz 2sFmvZtElLB0ZImLmpiIWFUxlVQUx+ThdGJs43+4vZ27rrodcODPVeWzuYetkCzzk+Lu aWosn/yEd0he6fENNRIR80VuLnAVCMRLZQdMQgjQxKc2g1K/z+5r3qd+aKnnc+21XIOA Bi4UpPIhilDBE0XmmQjLkrzegP59pA0mL+vuFrGxwY+px/X7SGz7RlTDHCwyHLa3RuAV JGtFhkRJmxcn5n2iM8JIYIluzN6qKkHlFeh+vlxajPVO15HMtOR3VBy/RE5xVYchwd2p +NUg== X-Gm-Message-State: ACrzQf3yHyIOOUkluo6Dr5u3giPEX/mcq16JgmkqI24y89LyWJJssD01 SwTS5ARuvwgs6FY/FT6f3VDjng== X-Google-Smtp-Source: AMsMyM5cGE6yDYaNnkOQI2S/AY/raVeY3MQmtPRCA7w7Y1F/Hp50JUsxZyNnn8zkQ8BUw5iA6TjTdQ== X-Received: by 2002:a17:90b:1b0a:b0:203:3947:1a73 with SMTP id nu10-20020a17090b1b0a00b0020339471a73mr5502968pjb.43.1663701732553; Tue, 20 Sep 2022 12:22:12 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id g6-20020aa79dc6000000b00540b3be3bf6sm241957pfq.196.2022.09.20.12.22.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Sep 2022 12:22:08 -0700 (PDT) From: Kees Cook To: linux-hardening@vger.kernel.org Cc: Kees Cook , Miguel Ojeda , Siddhesh Poyarekar , Arnd Bergmann , Nick Desaulniers , Nathan Chancellor , Tom Rix , llvm@lists.linux.dev, Juergen Gross , Boris Ostrovsky , linux-kernel@vger.kernel.org Subject: [PATCH 4/4] fortify: Use __builtin_dynamic_object_size() when available Date: Tue, 20 Sep 2022 12:22:02 -0700 Message-Id: <20220920192202.190793-5-keescook@chromium.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220920192202.190793-1-keescook@chromium.org> References: <20220920192202.190793-1-keescook@chromium.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=3540; h=from:subject; bh=SuFYab5ne2I0fynfIO4bCDx/ZuEkBNyDkYK1dq1mYyM=; b=owEBbQKS/ZANAwAKAYly9N/cbcAmAcsmYgBjKhLZYIErDe7TJDRHJVXzahhQK/yb2r2Hf0BSFlIk 1TRe4CGJAjMEAAEKAB0WIQSlw/aPIp3WD3I+bhOJcvTf3G3AJgUCYyoS2QAKCRCJcvTf3G3AJv/FEA Czrw6b87vzPgCg7ACdCSxIWAVzP/trBSumyV4j+mMLwNorFE6sFmGa1LuJ6nJ9vUo8EDqahBZ9CDBv CCFp8MECNgOMcPu/f9UeJe5xWlEhzXx50YVKLlo7VRhI8qaTjuwPStnIPCMhNAq5rUTrhFgzZ6TRNj OgfUKDOAKj66fCR9ZZF5XOrZ6L6jqb+s3UKC7cRRxMly4pF5kpDIWS5rDy8HCb62zZEpRWfx5keU+c wKIblI52S1m4B92gAPSzTovz30UDFmQ4h77kqjrD8IGfuxtaLDGCXoUdVjKB1MZt6aA2TmCffYyif3 r75kl/VnrhA8BgG2hSaLao8eLp5NVSB05oeoRAtH3Ihg1oD3Prs2u+TfZlAxa/tAqS+NUbEp2tr48c zWUXBJXPA6CBD+InglqErOPIokC1bYUX4B8zrszOm04+MWWFVwHHNyAQ81LXctDwofckcu/XDFOYVg zWXa9fVrGWo3xzHFwXi6s2wmVGfwoHO82cH+ZIk/Z73l+so0GgscIkOaRUt0T7PsgStttC0CCxYBYl JDjycZUlwUA7bGRdCcsWeiMYuUuplqYkIbj4spMC7TIhgRjE13n8QTklhFlA6cfQLyq+jXqw+jstdN +767zQnvbl3Litrhx7i4I4UpuOQxMl919VqKmJrB4aFHEaFW6iZpVe7aEffQ== X-Developer-Key: i=keescook@chromium.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Since the commits starting with c37495d6254c ("slab: add __alloc_size attributes for better bounds checking"), the compilers have runtime allocation size hints available in some places. This was immediately available to CONFIG_UBSAN_BOUNDS, but CONFIG_FORTIFY_SOURCE needed updating to explicitly make use the hints via the associated __builtin_dynamic_object_size() helper. Detect and use the builtin when it is available, increasing the accuracy of the mitigation. When runtime sizes are not available, __builtin_dynamic_object_size() falls back to __builtin_object_size(), leaving the existing bounds checking unchanged. Additionally update the VMALLOC_LINEAR_OVERFLOW LKDTM test to make the hint invisible, otherwise the architectural defense is not exercised (the buffer overflow is detected in the memset() rather than when it crosses the edge of the allocation). Cc: Miguel Ojeda Cc: Siddhesh Poyarekar Cc: Arnd Bergmann Cc: Nick Desaulniers Cc: Nathan Chancellor Cc: Tom Rix Cc: linux-hardening@vger.kernel.org Cc: llvm@lists.linux.dev Signed-off-by: Kees Cook Reviewed-by: Miguel Ojeda Reviewed-by: Siddhesh Poyarekar Tested-by: Niklas Cassel --- drivers/misc/lkdtm/heap.c | 1 + include/linux/compiler_attributes.h | 5 +++++ include/linux/fortify-string.h | 7 +++++++ 3 files changed, 13 insertions(+) diff --git a/drivers/misc/lkdtm/heap.c b/drivers/misc/lkdtm/heap.c index 62516078a619..0ce4cbf6abda 100644 --- a/drivers/misc/lkdtm/heap.c +++ b/drivers/misc/lkdtm/heap.c @@ -31,6 +31,7 @@ static void lkdtm_VMALLOC_LINEAR_OVERFLOW(void) char *one, *two; =20 one =3D vzalloc(PAGE_SIZE); + OPTIMIZER_HIDE_VAR(one); two =3D vzalloc(PAGE_SIZE); =20 pr_info("Attempting vmalloc linear overflow ...\n"); diff --git a/include/linux/compiler_attributes.h b/include/linux/compiler_a= ttributes.h index 445e80517cab..9a9907fad6fd 100644 --- a/include/linux/compiler_attributes.h +++ b/include/linux/compiler_attributes.h @@ -296,6 +296,11 @@ * * clang: https://clang.llvm.org/docs/AttributeReference.html#pass-object-= size-pass-dynamic-object-size */ +#if __has_attribute(__pass_dynamic_object_size__) +# define __pass_dynamic_object_size(type) __attribute__((__pass_dynamic_ob= ject_size__(type))) +#else +# define __pass_dynamic_object_size(type) +#endif #if __has_attribute(__pass_object_size__) # define __pass_object_size(type) __attribute__((__pass_object_size__(type= ))) #else diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h index 3f1178584d7b..dd7f85d74ade 100644 --- a/include/linux/fortify-string.h +++ b/include/linux/fortify-string.h @@ -77,10 +77,17 @@ extern char *__underlying_strncpy(char *p, const char *= q, __kernel_size_t size) * size, rather than struct size), but there remain some stragglers using * type 0 that will be converted in the future. */ +#if __has_builtin(__builtin_dynamic_object_size) +#define POS __pass_dynamic_object_size(1) +#define POS0 __pass_dynamic_object_size(0) +#define __struct_size(p) __builtin_dynamic_object_size(p, 0) +#define __member_size(p) __builtin_dynamic_object_size(p, 1) +#else #define POS __pass_object_size(1) #define POS0 __pass_object_size(0) #define __struct_size(p) __builtin_object_size(p, 0) #define __member_size(p) __builtin_object_size(p, 1) +#endif =20 #define __compiletime_lessthan(bounds, length) ( \ __builtin_constant_p(length) && \ --=20 2.34.1