Skip to content

Commit cb5c4df

Browse files
Sidraya JayagondNipaLocal
authored andcommitted
net/smc: fix warning in smc_rx_splice() when calling get_page()
smc_lo_register_dmb() allocates DMB buffers with kzalloc(), which are later passed to get_page() in smc_rx_splice(). Since kmalloc memory is not page-backed, this triggers WARN_ON_ONCE() in get_page() and prevents holding a refcount on the buffer. This can lead to use-after-free if the memory is released before splice_to_pipe() completes. Use folio_alloc() instead, ensuring DMBs are page-backed and safe for get_page(). WARNING: CPU: 18 PID: 12152 at ./include/linux/mm.h:1330 smc_rx_splice+0xaf8/0xe20 [smc] CPU: 18 UID: 0 PID: 12152 Comm: smcapp Kdump: loaded Not tainted 6.17.0-rc3-11705-g9cf4672ecfee kernel-patches#10 NONE Hardware name: IBM 3931 A01 704 (z/VM 7.4.0) Krnl PSW : 0704e00180000000 000793161032696c (smc_rx_splice+0xafc/0xe20 [smc]) R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:2 PM:0 RI:0 EA:3 Krnl GPRS: 0000000000000000 001cee80007d3001 00077400000000f8 0000000000000005 0000000000000001 001cee80007d3006 0007740000001000 001c000000000000 000000009b0c99e0 0000000000001000 001c0000000000f8 001c000000000000 000003ffcc6f7c88 0007740003e98000 0007931600000005 000792969b2ff7b8 Krnl Code: 0007931610326960: af000000 mc 0,0 0007931610326964: a7f4ff43 brc 15,00079316103267ea #0007931610326968: af000000 mc 0,0 >000793161032696c: a7f4ff3f brc 15,00079316103267ea 0007931610326970: e320f1000004 lg %r2,256(%r15) 0007931610326976: c0e53fd1b5f5 brasl %r14,000793168fd5d560 000793161032697c: a7f4fbb5 brc 15,00079316103260e6 0007931610326980: b904002b lgr %r2,%r11 Call Trace: smc_rx_splice+0xafc/0xe20 [smc] smc_rx_splice+0x756/0xe20 [smc]) smc_rx_recvmsg+0xa74/0xe00 [smc] smc_splice_read+0x1ce/0x3b0 [smc] sock_splice_read+0xa2/0xf0 do_splice_read+0x198/0x240 splice_file_to_pipe+0x7e/0x110 do_splice+0x59e/0xde0 __do_splice+0x11a/0x2d0 __s390x_sys_splice+0x140/0x1f0 __do_syscall+0x122/0x280 system_call+0x6e/0x90 Last Breaking-Event-Address: smc_rx_splice+0x960/0xe20 [smc] ---[ end trace 0000000000000000 ]--- Fixes: f7a2207 ("net/smc: implement DMB-related operations of loopback-ism") Reviewed-by: Mahanta Jambigi <[email protected]> Signed-off-by: Sidraya Jayagond <[email protected]> Signed-off-by: NipaLocal <nipa@local>
1 parent 5aa5f0e commit cb5c4df

File tree

1 file changed

+9
-5
lines changed

1 file changed

+9
-5
lines changed

net/smc/smc_loopback.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ static int smc_lo_register_dmb(struct smcd_dev *smcd, struct smcd_dmb *dmb,
5656
{
5757
struct smc_lo_dmb_node *dmb_node, *tmp_node;
5858
struct smc_lo_dev *ldev = smcd->priv;
59+
struct folio *folio;
5960
int sba_idx, rc;
6061

6162
/* check space for new dmb */
@@ -74,13 +75,16 @@ static int smc_lo_register_dmb(struct smcd_dev *smcd, struct smcd_dmb *dmb,
7475

7576
dmb_node->sba_idx = sba_idx;
7677
dmb_node->len = dmb->dmb_len;
77-
dmb_node->cpu_addr = kzalloc(dmb_node->len, GFP_KERNEL |
78-
__GFP_NOWARN | __GFP_NORETRY |
79-
__GFP_NOMEMALLOC);
80-
if (!dmb_node->cpu_addr) {
78+
79+
/* not critical; fail under memory pressure and fallback to TCP */
80+
folio = folio_alloc(GFP_KERNEL | __GFP_NOWARN | __GFP_NOMEMALLOC |
81+
__GFP_NORETRY | __GFP_ZERO,
82+
get_order(dmb_node->len));
83+
if (!folio) {
8184
rc = -ENOMEM;
8285
goto err_node;
8386
}
87+
dmb_node->cpu_addr = folio_address(folio);
8488
dmb_node->dma_addr = SMC_DMA_ADDR_INVALID;
8589
refcount_set(&dmb_node->refcnt, 1);
8690

@@ -122,7 +126,7 @@ static void __smc_lo_unregister_dmb(struct smc_lo_dev *ldev,
122126
write_unlock_bh(&ldev->dmb_ht_lock);
123127

124128
clear_bit(dmb_node->sba_idx, ldev->sba_idx_mask);
125-
kvfree(dmb_node->cpu_addr);
129+
folio_put(virt_to_folio(dmb_node->cpu_addr));
126130
kfree(dmb_node);
127131

128132
if (atomic_dec_and_test(&ldev->dmb_cnt))

0 commit comments

Comments
 (0)