Skip to content

Commit 53dbb93

Browse files
chucklevergregkh
authored andcommitted
svcrdma: Fix trace point use-after-free race
commit e28b4fc upstream. I hit this while testing nfsd-5.7 with kernel memory debugging enabled on my server: Mar 30 13:21:45 klimt kernel: BUG: unable to handle page fault for address: ffff8887e6c279a8 Mar 30 13:21:45 klimt kernel: #PF: supervisor read access in kernel mode Mar 30 13:21:45 klimt kernel: #PF: error_code(0x0000) - not-present page Mar 30 13:21:45 klimt kernel: PGD 3601067 P4D 3601067 PUD 87c519067 PMD 87c3e2067 PTE 800ffff8193d8060 Mar 30 13:21:45 klimt kernel: Oops: 0000 [#1] SMP DEBUG_PAGEALLOC PTI Mar 30 13:21:45 klimt kernel: CPU: 2 PID: 1933 Comm: nfsd Not tainted 5.6.0-rc6-00040-g881e87a3c6f9 #1591 Mar 30 13:21:45 klimt kernel: Hardware name: Supermicro Super Server/X10SRL-F, BIOS 1.0c 09/09/2015 Mar 30 13:21:45 klimt kernel: RIP: 0010:svc_rdma_post_chunk_ctxt+0xab/0x284 [rpcrdma] Mar 30 13:21:45 klimt kernel: Code: c1 83 34 02 00 00 29 d0 85 c0 7e 72 48 8b bb a0 02 00 00 48 8d 54 24 08 4c 89 e6 48 8b 07 48 8b 40 20 e8 5a 5c 2b e1 41 89 c6 <8b> 45 20 89 44 24 04 8b 05 02 e9 01 00 85 c0 7e 33 e9 5e 01 00 00 Mar 30 13:21:45 klimt kernel: RSP: 0018:ffffc90000dfbdd8 EFLAGS: 00010286 Mar 30 13:21:45 klimt kernel: RAX: 0000000000000000 RBX: ffff8887db8db400 RCX: 0000000000000030 Mar 30 13:21:45 klimt kernel: RDX: 0000000000000040 RSI: 0000000000000000 RDI: 0000000000000246 Mar 30 13:21:45 klimt kernel: RBP: ffff8887e6c27988 R08: 0000000000000000 R09: 0000000000000004 Mar 30 13:21:45 klimt kernel: R10: ffffc90000dfbdd8 R11: 00c068ef00000000 R12: ffff8887eb4e4a80 Mar 30 13:21:45 klimt kernel: R13: ffff8887db8db634 R14: 0000000000000000 R15: ffff8887fc931000 Mar 30 13:21:45 klimt kernel: FS: 0000000000000000(0000) GS:ffff88885bd00000(0000) knlGS:0000000000000000 Mar 30 13:21:45 klimt kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 Mar 30 13:21:45 klimt kernel: CR2: ffff8887e6c279a8 CR3: 000000081b72e002 CR4: 00000000001606e0 Mar 30 13:21:45 klimt kernel: Call Trace: Mar 30 13:21:45 klimt kernel: ? svc_rdma_vec_to_sg+0x7f/0x7f [rpcrdma] Mar 30 13:21:45 klimt kernel: svc_rdma_send_write_chunk+0x59/0xce [rpcrdma] Mar 30 13:21:45 klimt kernel: svc_rdma_sendto+0xf9/0x3ae [rpcrdma] Mar 30 13:21:45 klimt kernel: ? nfsd_destroy+0x51/0x51 [nfsd] Mar 30 13:21:45 klimt kernel: svc_send+0x105/0x1e3 [sunrpc] Mar 30 13:21:45 klimt kernel: nfsd+0xf2/0x149 [nfsd] Mar 30 13:21:45 klimt kernel: kthread+0xf6/0xfb Mar 30 13:21:45 klimt kernel: ? kthread_queue_delayed_work+0x74/0x74 Mar 30 13:21:45 klimt kernel: ret_from_fork+0x3a/0x50 Mar 30 13:21:45 klimt kernel: Modules linked in: ocfs2_dlmfs ocfs2_stack_o2cb ocfs2_dlm ocfs2_nodemanager ocfs2_stackglue ib_umad ib_ipoib mlx4_ib sb_edac x86_pkg_temp_thermal iTCO_wdt iTCO_vendor_support coretemp kvm_intel kvm irqbypass crct10dif_pclmul crc32_pclmul ghash_clmulni_intel aesni_intel glue_helper crypto_simd cryptd pcspkr rpcrdma i2c_i801 rdma_ucm lpc_ich mfd_core ib_iser rdma_cm iw_cm ib_cm mei_me raid0 libiscsi mei sg scsi_transport_iscsi ioatdma wmi ipmi_si ipmi_devintf ipmi_msghandler acpi_power_meter nfsd nfs_acl lockd auth_rpcgss grace sunrpc ip_tables xfs libcrc32c mlx4_en sd_mod sr_mod cdrom mlx4_core crc32c_intel igb nvme i2c_algo_bit ahci i2c_core libahci nvme_core dca libata t10_pi qedr dm_mirror dm_region_hash dm_log dm_mod dax qede qed crc8 ib_uverbs ib_core Mar 30 13:21:45 klimt kernel: CR2: ffff8887e6c279a8 Mar 30 13:21:45 klimt kernel: ---[ end trace 87971d2ad3429424 ]--- It's absolutely not safe to use resources pointed to by the @send_wr argument of ib_post_send() _after_ that function returns. Those resources are typically freed by the Send completion handler, which can run before ib_post_send() returns. Thus the trace points currently around ib_post_send() in the server's RPC/RDMA transport are a hazard, even when they are disabled. Rearrange them so that they touch the Work Request only _before_ ib_post_send() is invoked. Fixes: bd2abef ("svcrdma: Trace key RDMA API events") Fixes: 4201c74 ("svcrdma: Introduce svc_rdma_send_ctxt") Signed-off-by: Chuck Lever <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent ccd3b4b commit 53dbb93

File tree

3 files changed

+46
-23
lines changed

3 files changed

+46
-23
lines changed

include/trace/events/rpcrdma.h

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1638,30 +1638,27 @@ DECLARE_EVENT_CLASS(svcrdma_sendcomp_event,
16381638

16391639
TRACE_EVENT(svcrdma_post_send,
16401640
TP_PROTO(
1641-
const struct ib_send_wr *wr,
1642-
int status
1641+
const struct ib_send_wr *wr
16431642
),
16441643

1645-
TP_ARGS(wr, status),
1644+
TP_ARGS(wr),
16461645

16471646
TP_STRUCT__entry(
16481647
__field(const void *, cqe)
16491648
__field(unsigned int, num_sge)
16501649
__field(u32, inv_rkey)
1651-
__field(int, status)
16521650
),
16531651

16541652
TP_fast_assign(
16551653
__entry->cqe = wr->wr_cqe;
16561654
__entry->num_sge = wr->num_sge;
16571655
__entry->inv_rkey = (wr->opcode == IB_WR_SEND_WITH_INV) ?
16581656
wr->ex.invalidate_rkey : 0;
1659-
__entry->status = status;
16601657
),
16611658

1662-
TP_printk("cqe=%p num_sge=%u inv_rkey=0x%08x status=%d",
1659+
TP_printk("cqe=%p num_sge=%u inv_rkey=0x%08x",
16631660
__entry->cqe, __entry->num_sge,
1664-
__entry->inv_rkey, __entry->status
1661+
__entry->inv_rkey
16651662
)
16661663
);
16671664

@@ -1726,26 +1723,23 @@ TRACE_EVENT(svcrdma_wc_receive,
17261723
TRACE_EVENT(svcrdma_post_rw,
17271724
TP_PROTO(
17281725
const void *cqe,
1729-
int sqecount,
1730-
int status
1726+
int sqecount
17311727
),
17321728

1733-
TP_ARGS(cqe, sqecount, status),
1729+
TP_ARGS(cqe, sqecount),
17341730

17351731
TP_STRUCT__entry(
17361732
__field(const void *, cqe)
17371733
__field(int, sqecount)
1738-
__field(int, status)
17391734
),
17401735

17411736
TP_fast_assign(
17421737
__entry->cqe = cqe;
17431738
__entry->sqecount = sqecount;
1744-
__entry->status = status;
17451739
),
17461740

1747-
TP_printk("cqe=%p sqecount=%d status=%d",
1748-
__entry->cqe, __entry->sqecount, __entry->status
1741+
TP_printk("cqe=%p sqecount=%d",
1742+
__entry->cqe, __entry->sqecount
17491743
)
17501744
);
17511745

@@ -1841,6 +1835,34 @@ DECLARE_EVENT_CLASS(svcrdma_sendqueue_event,
18411835
DEFINE_SQ_EVENT(full);
18421836
DEFINE_SQ_EVENT(retry);
18431837

1838+
TRACE_EVENT(svcrdma_sq_post_err,
1839+
TP_PROTO(
1840+
const struct svcxprt_rdma *rdma,
1841+
int status
1842+
),
1843+
1844+
TP_ARGS(rdma, status),
1845+
1846+
TP_STRUCT__entry(
1847+
__field(int, avail)
1848+
__field(int, depth)
1849+
__field(int, status)
1850+
__string(addr, rdma->sc_xprt.xpt_remotebuf)
1851+
),
1852+
1853+
TP_fast_assign(
1854+
__entry->avail = atomic_read(&rdma->sc_sq_avail);
1855+
__entry->depth = rdma->sc_sq_depth;
1856+
__entry->status = status;
1857+
__assign_str(addr, rdma->sc_xprt.xpt_remotebuf);
1858+
),
1859+
1860+
TP_printk("addr=%s sc_sq_avail=%d/%d status=%d",
1861+
__get_str(addr), __entry->avail, __entry->depth,
1862+
__entry->status
1863+
)
1864+
);
1865+
18441866
#endif /* _TRACE_RPCRDMA_H */
18451867

18461868
#include <trace/define_trace.h>

net/sunrpc/xprtrdma/svc_rdma_rw.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,8 +323,6 @@ static int svc_rdma_post_chunk_ctxt(struct svc_rdma_chunk_ctxt *cc)
323323
if (atomic_sub_return(cc->cc_sqecount,
324324
&rdma->sc_sq_avail) > 0) {
325325
ret = ib_post_send(rdma->sc_qp, first_wr, &bad_wr);
326-
trace_svcrdma_post_rw(&cc->cc_cqe,
327-
cc->cc_sqecount, ret);
328326
if (ret)
329327
break;
330328
return 0;
@@ -337,6 +335,7 @@ static int svc_rdma_post_chunk_ctxt(struct svc_rdma_chunk_ctxt *cc)
337335
trace_svcrdma_sq_retry(rdma);
338336
} while (1);
339337

338+
trace_svcrdma_sq_post_err(rdma, ret);
340339
set_bit(XPT_CLOSE, &xprt->xpt_flags);
341340

342341
/* If even one was posted, there will be a completion. */

net/sunrpc/xprtrdma/svc_rdma_sendto.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -306,15 +306,17 @@ int svc_rdma_send(struct svcxprt_rdma *rdma, struct ib_send_wr *wr)
306306
}
307307

308308
svc_xprt_get(&rdma->sc_xprt);
309+
trace_svcrdma_post_send(wr);
309310
ret = ib_post_send(rdma->sc_qp, wr, NULL);
310-
trace_svcrdma_post_send(wr, ret);
311-
if (ret) {
312-
set_bit(XPT_CLOSE, &rdma->sc_xprt.xpt_flags);
313-
svc_xprt_put(&rdma->sc_xprt);
314-
wake_up(&rdma->sc_send_wait);
315-
}
316-
break;
311+
if (ret)
312+
break;
313+
return 0;
317314
}
315+
316+
trace_svcrdma_sq_post_err(rdma, ret);
317+
set_bit(XPT_CLOSE, &rdma->sc_xprt.xpt_flags);
318+
svc_xprt_put(&rdma->sc_xprt);
319+
wake_up(&rdma->sc_send_wait);
318320
return ret;
319321
}
320322

0 commit comments

Comments
 (0)