mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	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 #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: f7a22071db ("net/smc: implement DMB-related operations of loopback-ism")
Reviewed-by: Mahanta Jambigi <mjambigi@linux.ibm.com>
Signed-off-by: Sidraya Jayagond <sidraya@linux.ibm.com>
Link: https://patch.msgid.link/20250917184220.801066-1-sidraya@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
			
			
This commit is contained in:
		
							parent
							
								
									1091860a16
								
							
						
					
					
						commit
						a35c04de25
					
				
					 1 changed files with 9 additions and 5 deletions
				
			
		|  | @ -56,6 +56,7 @@ static int smc_lo_register_dmb(struct smcd_dev *smcd, struct smcd_dmb *dmb, | ||||||
| { | { | ||||||
| 	struct smc_lo_dmb_node *dmb_node, *tmp_node; | 	struct smc_lo_dmb_node *dmb_node, *tmp_node; | ||||||
| 	struct smc_lo_dev *ldev = smcd->priv; | 	struct smc_lo_dev *ldev = smcd->priv; | ||||||
|  | 	struct folio *folio; | ||||||
| 	int sba_idx, rc; | 	int sba_idx, rc; | ||||||
| 
 | 
 | ||||||
| 	/* check space for new dmb */ | 	/* check space for new dmb */ | ||||||
|  | @ -74,13 +75,16 @@ static int smc_lo_register_dmb(struct smcd_dev *smcd, struct smcd_dmb *dmb, | ||||||
| 
 | 
 | ||||||
| 	dmb_node->sba_idx = sba_idx; | 	dmb_node->sba_idx = sba_idx; | ||||||
| 	dmb_node->len = dmb->dmb_len; | 	dmb_node->len = dmb->dmb_len; | ||||||
| 	dmb_node->cpu_addr = kzalloc(dmb_node->len, GFP_KERNEL | | 
 | ||||||
| 				     __GFP_NOWARN | __GFP_NORETRY | | 	/* not critical; fail under memory pressure and fallback to TCP */ | ||||||
| 				     __GFP_NOMEMALLOC); | 	folio = folio_alloc(GFP_KERNEL | __GFP_NOWARN | __GFP_NOMEMALLOC | | ||||||
| 	if (!dmb_node->cpu_addr) { | 			    __GFP_NORETRY | __GFP_ZERO, | ||||||
|  | 			    get_order(dmb_node->len)); | ||||||
|  | 	if (!folio) { | ||||||
| 		rc = -ENOMEM; | 		rc = -ENOMEM; | ||||||
| 		goto err_node; | 		goto err_node; | ||||||
| 	} | 	} | ||||||
|  | 	dmb_node->cpu_addr = folio_address(folio); | ||||||
| 	dmb_node->dma_addr = SMC_DMA_ADDR_INVALID; | 	dmb_node->dma_addr = SMC_DMA_ADDR_INVALID; | ||||||
| 	refcount_set(&dmb_node->refcnt, 1); | 	refcount_set(&dmb_node->refcnt, 1); | ||||||
| 
 | 
 | ||||||
|  | @ -122,7 +126,7 @@ static void __smc_lo_unregister_dmb(struct smc_lo_dev *ldev, | ||||||
| 	write_unlock_bh(&ldev->dmb_ht_lock); | 	write_unlock_bh(&ldev->dmb_ht_lock); | ||||||
| 
 | 
 | ||||||
| 	clear_bit(dmb_node->sba_idx, ldev->sba_idx_mask); | 	clear_bit(dmb_node->sba_idx, ldev->sba_idx_mask); | ||||||
| 	kvfree(dmb_node->cpu_addr); | 	folio_put(virt_to_folio(dmb_node->cpu_addr)); | ||||||
| 	kfree(dmb_node); | 	kfree(dmb_node); | ||||||
| 
 | 
 | ||||||
| 	if (atomic_dec_and_test(&ldev->dmb_cnt)) | 	if (atomic_dec_and_test(&ldev->dmb_cnt)) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Sidraya Jayagond
						Sidraya Jayagond