Skip to content

Commit 2dcfe9e

Browse files
committed
niu: Silence randstruct warnings
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/[email protected]/ Cc: "Matthew Wilcox (Oracle)" <[email protected]> Cc: Christoph Hellwig <[email protected]> Cc: "David S. Miller" <[email protected]> Cc: Jakub Kicinski <[email protected]> Cc: Paolo Abeni <[email protected]> Cc: Du Cheng <[email protected]> Cc: Christophe JAILLET <[email protected]> Cc: Vlastimil Babka <[email protected]> Cc: William Kucharski <[email protected]> Cc: Arnd Bergmann <[email protected]> Cc: Nathan Chancellor <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Acked-by: Jakub Kicinski <[email protected]> Link: https://lore.kernel.org/lkml/[email protected] Signed-off-by: Kees Cook <[email protected]>
1 parent c1298a3 commit 2dcfe9e

File tree

2 files changed

+31
-12
lines changed

2 files changed

+31
-12
lines changed

drivers/net/ethernet/sun/niu.c

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,25 @@
3535

3636
#include "niu.h"
3737

38+
/* This driver wants to store a link to a "next page" within the
39+
* page struct itself by overloading the content of the "mapping"
40+
* member. This is not expected by the page API, but does currently
41+
* work. However, the randstruct plugin gets very bothered by this
42+
* case because "mapping" (struct address_space) is randomized, so
43+
* casts to/from it trigger warnings. Hide this by way of a union,
44+
* to create a typed alias of "mapping", since that's how it is
45+
* actually being used here.
46+
*/
47+
union niu_page {
48+
struct page page;
49+
struct {
50+
unsigned long __flags; /* unused alias of "flags" */
51+
struct list_head __lru; /* unused alias of "lru" */
52+
struct page *next; /* alias of "mapping" */
53+
};
54+
};
55+
#define niu_next_page(p) container_of(p, union niu_page, page)->next
56+
3857
#define DRV_MODULE_NAME "niu"
3958
#define DRV_MODULE_VERSION "1.1"
4059
#define DRV_MODULE_RELDATE "Apr 22, 2010"
@@ -3283,7 +3302,7 @@ static struct page *niu_find_rxpage(struct rx_ring_info *rp, u64 addr,
32833302

32843303
addr &= PAGE_MASK;
32853304
pp = &rp->rxhash[h];
3286-
for (; (p = *pp) != NULL; pp = (struct page **) &p->mapping) {
3305+
for (; (p = *pp) != NULL; pp = &niu_next_page(p)) {
32873306
if (p->index == addr) {
32883307
*link = pp;
32893308
goto found;
@@ -3300,7 +3319,7 @@ static void niu_hash_page(struct rx_ring_info *rp, struct page *page, u64 base)
33003319
unsigned int h = niu_hash_rxaddr(rp, base);
33013320

33023321
page->index = base;
3303-
page->mapping = (struct address_space *) rp->rxhash[h];
3322+
niu_next_page(page) = rp->rxhash[h];
33043323
rp->rxhash[h] = page;
33053324
}
33063325

@@ -3382,11 +3401,11 @@ static int niu_rx_pkt_ignore(struct niu *np, struct rx_ring_info *rp)
33823401
rcr_size = rp->rbr_sizes[(val & RCR_ENTRY_PKTBUFSZ) >>
33833402
RCR_ENTRY_PKTBUFSZ_SHIFT];
33843403
if ((page->index + PAGE_SIZE) - rcr_size == addr) {
3385-
*link = (struct page *) page->mapping;
3404+
*link = niu_next_page(page);
33863405
np->ops->unmap_page(np->device, page->index,
33873406
PAGE_SIZE, DMA_FROM_DEVICE);
33883407
page->index = 0;
3389-
page->mapping = NULL;
3408+
niu_next_page(page) = NULL;
33903409
__free_page(page);
33913410
rp->rbr_refill_pending++;
33923411
}
@@ -3451,11 +3470,11 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np,
34513470

34523471
niu_rx_skb_append(skb, page, off, append_size, rcr_size);
34533472
if ((page->index + rp->rbr_block_size) - rcr_size == addr) {
3454-
*link = (struct page *) page->mapping;
3473+
*link = niu_next_page(page);
34553474
np->ops->unmap_page(np->device, page->index,
34563475
PAGE_SIZE, DMA_FROM_DEVICE);
34573476
page->index = 0;
3458-
page->mapping = NULL;
3477+
niu_next_page(page) = NULL;
34593478
rp->rbr_refill_pending++;
34603479
} else
34613480
get_page(page);
@@ -3518,13 +3537,13 @@ static void niu_rbr_free(struct niu *np, struct rx_ring_info *rp)
35183537

35193538
page = rp->rxhash[i];
35203539
while (page) {
3521-
struct page *next = (struct page *) page->mapping;
3540+
struct page *next = niu_next_page(page);
35223541
u64 base = page->index;
35233542

35243543
np->ops->unmap_page(np->device, base, PAGE_SIZE,
35253544
DMA_FROM_DEVICE);
35263545
page->index = 0;
3527-
page->mapping = NULL;
3546+
niu_next_page(page) = NULL;
35283547

35293548
__free_page(page);
35303549

@@ -6440,8 +6459,7 @@ static void niu_reset_buffers(struct niu *np)
64406459

64416460
page = rp->rxhash[j];
64426461
while (page) {
6443-
struct page *next =
6444-
(struct page *) page->mapping;
6462+
struct page *next = niu_next_page(page);
64456463
u64 base = page->index;
64466464
base = base >> RBR_DESCR_ADDR_SHIFT;
64476465
rp->rbr[k++] = cpu_to_le32(base);
@@ -10176,6 +10194,9 @@ static int __init niu_init(void)
1017610194

1017710195
BUILD_BUG_ON(PAGE_SIZE < 4 * 1024);
1017810196

10197+
BUILD_BUG_ON(offsetof(struct page, mapping) !=
10198+
offsetof(union niu_page, next));
10199+
1017910200
niu_debug = netif_msg_init(debug, NIU_MSG_DEFAULT);
1018010201

1018110202
#ifdef CONFIG_SPARC64

scripts/gcc-plugins/randomize_layout_plugin.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,6 @@ struct whitelist_entry {
4646
};
4747

4848
static const struct whitelist_entry whitelist[] = {
49-
/* NIU overloads mapping with page struct */
50-
{ "drivers/net/ethernet/sun/niu.c", "page", "address_space" },
5149
/* unix_skb_parms via UNIXCB() buffer */
5250
{ "net/unix/af_unix.c", "unix_skb_parms", "char" },
5351
{ }

0 commit comments

Comments
 (0)