From patchwork Tue May 10 20:57:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 12845530 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 kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id D9C4EC433F5 for ; Tue, 10 May 2022 20:57:35 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 3D3866B0071; Tue, 10 May 2022 16:57:35 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 382C76B0072; Tue, 10 May 2022 16:57:35 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 223F16B0073; Tue, 10 May 2022 16:57:35 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0012.hostedemail.com [216.40.44.12]) by kanga.kvack.org (Postfix) with ESMTP id 13B876B0071 for ; Tue, 10 May 2022 16:57:35 -0400 (EDT) Received: from smtpin13.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay13.hostedemail.com (Postfix) with ESMTP id E0E5D612E2 for ; Tue, 10 May 2022 20:57:34 +0000 (UTC) X-FDA: 79451044428.13.6603645 Received: from mail-pj1-f41.google.com (mail-pj1-f41.google.com [209.85.216.41]) by imf06.hostedemail.com (Postfix) with ESMTP id 2EA141800A7 for ; Tue, 10 May 2022 20:57:32 +0000 (UTC) Received: by mail-pj1-f41.google.com with SMTP id fv2so294296pjb.4 for ; Tue, 10 May 2022 13:57:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=qEwSLaBnufvf0B/G9DnjVyMhvQQtp6PRHTVxLgDlPK8=; b=JZZc8nkB/4Su4yIh1M5akAXPXMXUy7OMtkUi17Z4U6q8imKFEnTV2ldgRsbBiWHbOc OXkC8mulfoTXZNJgg7dy8ejG6nYNpAntJzw/UJ+ZREiXKr9wDqUzvSrnqoqdQxyFobaM R+HM0meqwbmtR1sWL0MDTYxA0VK0lzS8IXVh8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=qEwSLaBnufvf0B/G9DnjVyMhvQQtp6PRHTVxLgDlPK8=; b=qMlMjAzI3CM2Yw67S+J5OCwJTFkhL9PSiOsX3nDl/B1HXqSwcgqYHpded0pCUY3FG6 yyJYqszP1SQUAwoohO03LmPznUxIyyHN72WNItzY+ammFzKjMXv2ie8P5erOtTvmZYxW XNSom/8g8iFNiOIDVN6ulEGSRwnHfn8OW40bpEzv9FMTlwKdNf7rGj7HpZJZTIdBdFvu IXjDd2QtZH8LAFhvf714NOm5N+yRS/dBWz/M2h3+7SO22rudhbgPWEawBfeqKCWDl4WO 5n16GhaAcwkz/3zasEU96SiEdWHfD0F82ywGTGrkM79v17tLI+/ZyzAq9jqjIlfMj2wr cKzw== X-Gm-Message-State: AOAM532VRC6HaSUGqFy7TEyoeUkjoDYKVWW3VyQtZ+PtSL+jAtMqHKnb hkBfbTfNSbik/Ooe/xP0uFtubg== X-Google-Smtp-Source: ABdhPJzq6QFou00wiYYBUDT4UWIfcPJViSah6uRx1sl8Xa88lUVgHIvT844SOrOHnYuyyCgBDE0x7w== X-Received: by 2002:a17:902:a583:b0:15d:197b:9259 with SMTP id az3-20020a170902a58300b0015d197b9259mr22529041plb.51.1652216253338; Tue, 10 May 2022 13:57:33 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id u3-20020a170903108300b0015ee9bb2a38sm72477pld.72.2022.05.10.13.57.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 May 2022 13:57:33 -0700 (PDT) From: Kees Cook To: "Matthew Wilcox (Oracle)" Cc: Kees Cook , Christoph Hellwig , "David S. Miller" , Jakub Kicinski , Paolo Abeni , Du Cheng , Christophe JAILLET , Vlastimil Babka , William Kucharski , Arnd Bergmann , Nathan Chancellor , netdev@vger.kernel.org, linux-mm@kvack.org, linux-hardening@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] niu: Silence randstruct warnings Date: Tue, 10 May 2022 13:57:29 -0700 Message-Id: <20220510205729.3574400-1-keescook@chromium.org> X-Mailer: git-send-email 2.32.0 MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=6424; h=from:subject; bh=qjuk20AT1lvrR1lDg81FqCODCnq2+tj+/Y7wwEnRQa8=; b=owEBbQKS/ZANAwAKAYly9N/cbcAmAcsmYgBietG4dsJ9H5fxphZwsMR3iDSJzvX3mPa4VHlCGvUH hideMGiJAjMEAAEKAB0WIQSlw/aPIp3WD3I+bhOJcvTf3G3AJgUCYnrRuAAKCRCJcvTf3G3AJtleD/ 9zyb+fsiOw5Yfe5VTpCrrjyUdaIkIJl/vUPO3MSulEMU1Unng7KrEqQmJgAJM5WTUcAh7cTjNpY1q7 8+KeeGAO0KfG+t8kYQEEZRsOTCpFxnS4/oaFATHvLKVmZr83K0Yev/T2Ks6sActMbiWmsoo1mWhbJP ZMxlvaAFuKNEW9EjhNwKggoufIHyZcrx55WZFm5FF5HWQpa8sHQswEfZEQdK9raFdLCfMrBUfEEYbu UvlGalUlLC0Eg3kxD8/3HoqiKYvY9oQLdo8jnYGX7iqtwpQdXs9Y45aRQXDg7N55W9cOSut7I2kIMZ luOU+ygvT7MzXWj4Lo2ixe8ZwX7v+Hff8CLqdCpozXqoYiUYH6RzrJbX2ltMwpR4NNhsUsi7YznAT9 2Q0DKZZAjkGQq6c13DiqXaBQjRDAXhpPiUY0jNRi6l6FzxS3jqz9Zxrx2W7QYHGga4BpIc1LVgb5aT Kd04io55f66UaqZWMPDUw6dt02EdrN21KLLjlJUYMBus1KJR5LomjDBIhtphXZSh6+fD5cmFPZO8ZM k8JpuL3zTs+wcdSc4JdrsoELDqoR1K2PmCqX5eiS5GGfDobMFeJkx0lD8QY13R9yGukQrPhbcIcSG8 m7ViudNhHRmgfEdMjUJn0Ws8ouESfaGkchCFruYPxZ8TwyMWXHnsMqOb/7dw== X-Developer-Key: i=keescook@chromium.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 X-Rspamd-Queue-Id: 2EA141800A7 X-Stat-Signature: ccxfx4fr8xwukcu3jbhjq3cahuco31fg Authentication-Results: imf06.hostedemail.com; dkim=pass header.d=chromium.org header.s=google header.b=JZZc8nkB; dmarc=pass (policy=none) header.from=chromium.org; spf=pass (imf06.hostedemail.com: domain of keescook@chromium.org designates 209.85.216.41 as permitted sender) smtp.mailfrom=keescook@chromium.org X-Rspam-User: X-Rspamd-Server: rspam08 X-HE-Tag: 1652216252-489020 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Clang randstruct gets upset when it sees struct addresspace (which is randomized) being assigned to a struct page (which is not randomized): drivers/net/ethernet/sun/niu.c:3385:12: error: casting from randomized structure pointer type 'struct address_space *' to 'struct page *' *link = (struct page *) page->mapping; ^ It looks like niu.c is looking for an in-line place to chain its allocated pages together and is overloading the "mapping" member, as it is unused. This is very non-standard, and is expected to be cleaned up in the future[1], but there is no "correct" way to handle it today. No meaningful machine code changes result after this change, and source readability is improved. Drop the randstruct exception now that there is no "confusing" cross-type assignment. [1] https://lore.kernel.org/lkml/YnqgjVoMDu5v9PNG@casper.infradead.org/ Cc: "Matthew Wilcox (Oracle)" Cc: Christoph Hellwig Cc: "David S. Miller" Cc: Jakub Kicinski Cc: Paolo Abeni Cc: Du Cheng Cc: Christophe JAILLET Cc: Vlastimil Babka Cc: William Kucharski Cc: Arnd Bergmann Cc: Nathan Chancellor Cc: netdev@vger.kernel.org Cc: linux-mm@kvack.org Cc: linux-hardening@vger.kernel.org Signed-off-by: Kees Cook Acked-by: Jakub Kicinski --- earlier version: https://lore.kernel.org/lkml/20220509222334.3544344-1-keescook@chromium.org/ --- drivers/net/ethernet/sun/niu.c | 41 ++++++++++++++----- scripts/gcc-plugins/randomize_layout_plugin.c | 2 - 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c index 42460c0885fc..df70df29deea 100644 --- a/drivers/net/ethernet/sun/niu.c +++ b/drivers/net/ethernet/sun/niu.c @@ -35,6 +35,25 @@ #include "niu.h" +/* This driver wants to store a link to a "next page" within the + * page struct itself by overloading the content of the "mapping" + * member. This is not expected by the page API, but does currently + * work. However, the randstruct plugin gets very bothered by this + * case because "mapping" (struct address_space) is randomized, so + * casts to/from it trigger warnings. Hide this by way of a union, + * to create a typed alias of "mapping", since that's how it is + * actually being used here. + */ +union niu_page { + struct page page; + struct { + unsigned long __flags; /* unused alias of "flags" */ + struct list_head __lru; /* unused alias of "lru" */ + struct page *next; /* alias of "mapping" */ + }; +}; +#define niu_next_page(p) container_of(p, union niu_page, page)->next + #define DRV_MODULE_NAME "niu" #define DRV_MODULE_VERSION "1.1" #define DRV_MODULE_RELDATE "Apr 22, 2010" @@ -3283,7 +3302,7 @@ static struct page *niu_find_rxpage(struct rx_ring_info *rp, u64 addr, addr &= PAGE_MASK; pp = &rp->rxhash[h]; - for (; (p = *pp) != NULL; pp = (struct page **) &p->mapping) { + for (; (p = *pp) != NULL; pp = &niu_next_page(p)) { if (p->index == addr) { *link = pp; goto found; @@ -3300,7 +3319,7 @@ static void niu_hash_page(struct rx_ring_info *rp, struct page *page, u64 base) unsigned int h = niu_hash_rxaddr(rp, base); page->index = base; - page->mapping = (struct address_space *) rp->rxhash[h]; + niu_next_page(page) = rp->rxhash[h]; rp->rxhash[h] = page; } @@ -3382,11 +3401,11 @@ static int niu_rx_pkt_ignore(struct niu *np, struct rx_ring_info *rp) rcr_size = rp->rbr_sizes[(val & RCR_ENTRY_PKTBUFSZ) >> RCR_ENTRY_PKTBUFSZ_SHIFT]; if ((page->index + PAGE_SIZE) - rcr_size == addr) { - *link = (struct page *) page->mapping; + *link = niu_next_page(page); np->ops->unmap_page(np->device, page->index, PAGE_SIZE, DMA_FROM_DEVICE); page->index = 0; - page->mapping = NULL; + niu_next_page(page) = NULL; __free_page(page); rp->rbr_refill_pending++; } @@ -3451,11 +3470,11 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np, niu_rx_skb_append(skb, page, off, append_size, rcr_size); if ((page->index + rp->rbr_block_size) - rcr_size == addr) { - *link = (struct page *) page->mapping; + *link = niu_next_page(page); np->ops->unmap_page(np->device, page->index, PAGE_SIZE, DMA_FROM_DEVICE); page->index = 0; - page->mapping = NULL; + niu_next_page(page) = NULL; rp->rbr_refill_pending++; } else get_page(page); @@ -3518,13 +3537,13 @@ static void niu_rbr_free(struct niu *np, struct rx_ring_info *rp) page = rp->rxhash[i]; while (page) { - struct page *next = (struct page *) page->mapping; + struct page *next = niu_next_page(page); u64 base = page->index; np->ops->unmap_page(np->device, base, PAGE_SIZE, DMA_FROM_DEVICE); page->index = 0; - page->mapping = NULL; + niu_next_page(page) = NULL; __free_page(page); @@ -6440,8 +6459,7 @@ static void niu_reset_buffers(struct niu *np) page = rp->rxhash[j]; while (page) { - struct page *next = - (struct page *) page->mapping; + struct page *next = niu_next_page(page); u64 base = page->index; base = base >> RBR_DESCR_ADDR_SHIFT; rp->rbr[k++] = cpu_to_le32(base); @@ -10176,6 +10194,9 @@ static int __init niu_init(void) BUILD_BUG_ON(PAGE_SIZE < 4 * 1024); + BUILD_BUG_ON(offsetof(struct page, mapping) != + offsetof(union niu_page, next)); + niu_debug = netif_msg_init(debug, NIU_MSG_DEFAULT); #ifdef CONFIG_SPARC64 diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c index 727512eebb3b..38a8cf90f611 100644 --- a/scripts/gcc-plugins/randomize_layout_plugin.c +++ b/scripts/gcc-plugins/randomize_layout_plugin.c @@ -46,8 +46,6 @@ struct whitelist_entry { }; static const struct whitelist_entry whitelist[] = { - /* NIU overloads mapping with page struct */ - { "drivers/net/ethernet/sun/niu.c", "page", "address_space" }, /* unix_skb_parms via UNIXCB() buffer */ { "net/unix/af_unix.c", "unix_skb_parms", "char" }, { }