public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Vasily Averin <vvs@virtuozzo.com>,
	"J. Bruce Fields" <bfields@redhat.com>
Subject: [PATCH 4.19 45/50] sunrpc: use-after-free in svc_process_common()
Date: Tue, 15 Jan 2019 17:36:21 +0100	[thread overview]
Message-ID: <20190115154912.527086979@linuxfoundation.org> (raw)
In-Reply-To: <20190115154909.933241945@linuxfoundation.org>

4.19-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Vasily Averin <vvs@virtuozzo.com>

commit d4b09acf924b84bae77cad090a9d108e70b43643 upstream.

if node have NFSv41+ mounts inside several net namespaces
it can lead to use-after-free in svc_process_common()

svc_process_common()
        /* Setup reply header */
        rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp); <<< HERE

svc_process_common() can use incorrect rqstp->rq_xprt,
its caller function bc_svc_process() takes it from serv->sv_bc_xprt.
The problem is that serv is global structure but sv_bc_xprt
is assigned per-netnamespace.

According to Trond, the whole "let's set up rqstp->rq_xprt
for the back channel" is nothing but a giant hack in order
to work around the fact that svc_process_common() uses it
to find the xpt_ops, and perform a couple of (meaningless
for the back channel) tests of xpt_flags.

All we really need in svc_process_common() is to be able to run
rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr()

Bruce J Fields points that this xpo_prep_reply_hdr() call
is an awfully roundabout way just to do "svc_putnl(resv, 0);"
in the tcp case.

This patch does not initialiuze rqstp->rq_xprt in bc_svc_process(),
now it calls svc_process_common() with rqstp->rq_xprt = NULL.

To adjust reply header svc_process_common() just check
rqstp->rq_prot and calls svc_tcp_prep_reply_hdr() for tcp case.

To handle rqstp->rq_xprt = NULL case in functions called from
svc_process_common() patch intruduces net namespace pointer
svc_rqst->rq_bc_net and adjust SVC_NET() definition.
Some other function was also adopted to properly handle described case.

Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
Cc: stable@vger.kernel.org
Fixes: 23c20ecd4475 ("NFS: callback up - users counting cleanup")
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
v2: added lost extern svc_tcp_prep_reply_hdr()
Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 include/linux/sunrpc/svc.h    |    5 ++++-
 include/trace/events/sunrpc.h |    6 ++++--
 net/sunrpc/svc.c              |   11 +++++++----
 net/sunrpc/svc_xprt.c         |    5 +++--
 net/sunrpc/svcsock.c          |    2 +-
 5 files changed, 19 insertions(+), 10 deletions(-)

--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -295,9 +295,12 @@ struct svc_rqst {
 	struct svc_cacherep *	rq_cacherep;	/* cache info */
 	struct task_struct	*rq_task;	/* service thread */
 	spinlock_t		rq_lock;	/* per-request lock */
+	struct net		*rq_bc_net;	/* pointer to backchannel's
+						 * net namespace
+						 */
 };
 
-#define SVC_NET(svc_rqst)	(svc_rqst->rq_xprt->xpt_net)
+#define SVC_NET(rqst) (rqst->rq_xprt ? rqst->rq_xprt->xpt_net : rqst->rq_bc_net)
 
 /*
  * Rigorous type checking on sockaddr type conversions
--- a/include/trace/events/sunrpc.h
+++ b/include/trace/events/sunrpc.h
@@ -582,7 +582,8 @@ TRACE_EVENT(svc_process,
 		__field(u32, vers)
 		__field(u32, proc)
 		__string(service, name)
-		__string(addr, rqst->rq_xprt->xpt_remotebuf)
+		__string(addr, rqst->rq_xprt ?
+			 rqst->rq_xprt->xpt_remotebuf : "(null)")
 	),
 
 	TP_fast_assign(
@@ -590,7 +591,8 @@ TRACE_EVENT(svc_process,
 		__entry->vers = rqst->rq_vers;
 		__entry->proc = rqst->rq_proc;
 		__assign_str(service, name);
-		__assign_str(addr, rqst->rq_xprt->xpt_remotebuf);
+		__assign_str(addr, rqst->rq_xprt ?
+			     rqst->rq_xprt->xpt_remotebuf : "(null)");
 	),
 
 	TP_printk("addr=%s xid=0x%08x service=%s vers=%u proc=%u",
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -1144,6 +1144,8 @@ void svc_printk(struct svc_rqst *rqstp,
 static __printf(2,3) void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...) {}
 #endif
 
+extern void svc_tcp_prep_reply_hdr(struct svc_rqst *);
+
 /*
  * Common routine for processing the RPC request.
  */
@@ -1172,7 +1174,8 @@ svc_process_common(struct svc_rqst *rqst
 	clear_bit(RQ_DROPME, &rqstp->rq_flags);
 
 	/* Setup reply header */
-	rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp);
+	if (rqstp->rq_prot == IPPROTO_TCP)
+		svc_tcp_prep_reply_hdr(rqstp);
 
 	svc_putu32(resv, rqstp->rq_xid);
 
@@ -1244,7 +1247,7 @@ svc_process_common(struct svc_rqst *rqst
 	 * for lower versions. RPC_PROG_MISMATCH seems to be the closest
 	 * fit.
 	 */
-	if (versp->vs_need_cong_ctrl &&
+	if (versp->vs_need_cong_ctrl && rqstp->rq_xprt &&
 	    !test_bit(XPT_CONG_CTRL, &rqstp->rq_xprt->xpt_flags))
 		goto err_bad_vers;
 
@@ -1336,7 +1339,7 @@ svc_process_common(struct svc_rqst *rqst
 	return 0;
 
  close:
-	if (test_bit(XPT_TEMP, &rqstp->rq_xprt->xpt_flags))
+	if (rqstp->rq_xprt && test_bit(XPT_TEMP, &rqstp->rq_xprt->xpt_flags))
 		svc_close_xprt(rqstp->rq_xprt);
 	dprintk("svc: svc_process close\n");
 	return 0;
@@ -1459,10 +1462,10 @@ bc_svc_process(struct svc_serv *serv, st
 	dprintk("svc: %s(%p)\n", __func__, req);
 
 	/* Build the svc_rqst used by the common processing routine */
-	rqstp->rq_xprt = serv->sv_bc_xprt;
 	rqstp->rq_xid = req->rq_xid;
 	rqstp->rq_prot = req->rq_xprt->prot;
 	rqstp->rq_server = serv;
+	rqstp->rq_bc_net = req->rq_xprt->xprt_net;
 
 	rqstp->rq_addrlen = sizeof(req->rq_xprt->addr);
 	memcpy(&rqstp->rq_addr, &req->rq_xprt->addr, rqstp->rq_addrlen);
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -469,10 +469,11 @@ out:
  */
 void svc_reserve(struct svc_rqst *rqstp, int space)
 {
+	struct svc_xprt *xprt = rqstp->rq_xprt;
+
 	space += rqstp->rq_res.head[0].iov_len;
 
-	if (space < rqstp->rq_reserved) {
-		struct svc_xprt *xprt = rqstp->rq_xprt;
+	if (xprt && space < rqstp->rq_reserved) {
 		atomic_sub((rqstp->rq_reserved - space), &xprt->xpt_reserved);
 		rqstp->rq_reserved = space;
 
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -1198,7 +1198,7 @@ static int svc_tcp_sendto(struct svc_rqs
 /*
  * Setup response header. TCP has a 4B record length field.
  */
-static void svc_tcp_prep_reply_hdr(struct svc_rqst *rqstp)
+void svc_tcp_prep_reply_hdr(struct svc_rqst *rqstp)
 {
 	struct kvec *resv = &rqstp->rq_res.head[0];
 



  parent reply	other threads:[~2019-01-15 16:54 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-15 16:35 [PATCH 4.19 00/50] 4.19.16-stable review Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.19 01/50] Btrfs: fix deadlock when using free space tree due to block group creation Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.19 02/50] staging: rtl8188eu: Fix module loading from tasklet for CCMP encryption Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.19 03/50] staging: rtl8188eu: Fix module loading from tasklet for WEP encryption Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.19 04/50] cpufreq: scmi: Fix frequency invariance in slow path Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.19 05/50] x86, modpost: Replace last remnants of RETPOLINE with CONFIG_RETPOLINE Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.19 06/50] ALSA: hda/realtek - Support Dell headset mode for New AIO platform Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.19 07/50] ALSA: hda/realtek - Add unplug function into unplug state of Headset Mode for ALC225 Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.19 08/50] ALSA: hda/realtek - Disable headset Mic VREF for headset mode of ALC225 Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.19 09/50] CIFS: Fix adjustment of credits for MTU requests Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.19 10/50] CIFS: Do not set credits to 1 if the server didnt grant anything Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.19 11/50] CIFS: Do not hide EINTR after sending network packets Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.19 12/50] CIFS: Fix credit computation for compounded requests Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.19 13/50] cifs: Fix potential OOB access of lock element array Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.19 14/50] usb: cdc-acm: send ZLP for Telit 3G Intel based modems Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.19 15/50] USB: storage: dont insert sane sense for SPC3+ when bad sense specified Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.19 16/50] USB: storage: add quirk for SMI SM3350 Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.19 17/50] USB: Add USB_QUIRK_DELAY_CTRL_MSG quirk for Corsair K70 RGB Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.19 18/50] slab: alien caches must not be initialized if the allocation of the alien cache failed Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.19 19/50] mm/usercopy.c: no check page span for stack objects Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.19 20/50] mm, memcg: fix reclaim deadlock with writeback Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.19 21/50] ACPI: power: Skip duplicate power resource references in _PRx Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.19 22/50] ACPI / PMIC: xpower: Fix TS-pin current-source handling Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.19 23/50] ACPI/IORT: Fix rc_dma_get_range() Greg Kroah-Hartman
2019-01-15 16:36 ` [PATCH 4.19 24/50] i2c: dev: prevent adapter retries and timeout being set as minus value Greg Kroah-Hartman
2019-01-15 16:36 ` [PATCH 4.19 25/50] mtd: rawnand: qcom: fix memory corruption that causes panic Greg Kroah-Hartman
2019-01-15 16:36 ` [PATCH 4.19 26/50] vfio/type1: Fix unmap overflow off-by-one Greg Kroah-Hartman
2019-01-15 16:36 ` [PATCH 4.19 27/50] drm/amdgpu: Add new VegaM pci id Greg Kroah-Hartman
2019-01-15 16:36 ` [PATCH 4.19 28/50] PCI: dwc: Use interrupt masking instead of disabling Greg Kroah-Hartman
2019-01-15 16:36 ` [PATCH 4.19 29/50] PCI: dwc: Take lock when ACKing an interrupt Greg Kroah-Hartman
2019-01-15 16:36 ` [PATCH 4.19 30/50] PCI: dwc: Move interrupt acking into the proper callback Greg Kroah-Hartman
2019-01-15 16:36 ` [PATCH 4.19 31/50] drm/amd/display: Fix MST dp_blank REG_WAIT timeout Greg Kroah-Hartman
2019-01-15 16:36 ` [PATCH 4.19 32/50] drm/fb_helper: Allow leaking fbdev smem_start Greg Kroah-Hartman
2019-01-15 16:36 ` [PATCH 4.19 33/50] drm/fb-helper: Partially bring back workaround for bugs of SDL 1.2 Greg Kroah-Hartman
2019-01-15 16:36 ` [PATCH 4.19 34/50] drm/i915: Unwind failure on pinning the gen7 ppgtt Greg Kroah-Hartman
2019-01-15 16:36 ` [PATCH 4.19 35/50] drm/amdgpu: Dont ignore rc from drm_dp_mst_topology_mgr_resume() Greg Kroah-Hartman
2019-01-15 16:36 ` [PATCH 4.19 36/50] drm/amdgpu: Dont fail resume process if resuming atomic state fails Greg Kroah-Hartman
2019-01-15 16:36 ` [PATCH 4.19 37/50] rbd: dont return 0 on unmap if RBD_DEV_FLAG_REMOVING is set Greg Kroah-Hartman
2019-01-15 16:36 ` [PATCH 4.19 38/50] ext4: make sure enough credits are reserved for dioread_nolock writes Greg Kroah-Hartman
2019-01-15 16:36 ` [PATCH 4.19 39/50] ext4: fix a potential fiemap/page fault deadlock w/ inline_data Greg Kroah-Hartman
2019-01-15 16:36 ` [PATCH 4.19 40/50] ext4: avoid kernel warning when writing the superblock to a dead device Greg Kroah-Hartman
2019-01-15 16:36 ` [PATCH 4.19 41/50] ext4: use ext4_write_inode() when fsyncing w/o a journal Greg Kroah-Hartman
2019-01-15 16:36 ` [PATCH 4.19 42/50] ext4: track writeback errors using the generic tracking infrastructure Greg Kroah-Hartman
2019-01-15 16:36 ` [PATCH 4.19 43/50] ext4: fix special inode number checks in __ext4_iget() Greg Kroah-Hartman
2019-01-15 16:36 ` [PATCH 4.19 44/50] mm: page_mapped: dont assume compound page is huge or THP Greg Kroah-Hartman
2019-01-15 16:36 ` Greg Kroah-Hartman [this message]
2019-01-15 16:36 ` [PATCH 4.19 46/50] KVM: arm/arm64: Fix VMID alloc race by reverting to lock-less Greg Kroah-Hartman
2019-01-15 16:36 ` [PATCH 4.19 47/50] arm64: compat: Dont pull syscall number from regs in arm_compat_syscall Greg Kroah-Hartman
2019-01-15 16:36 ` [PATCH 4.19 48/50] Btrfs: fix access to available allocation bits when starting balance Greg Kroah-Hartman
2019-01-15 16:36 ` [PATCH 4.19 49/50] Btrfs: fix deadlock when enabling quotas due to concurrent snapshot creation Greg Kroah-Hartman
2019-01-15 16:36 ` [PATCH 4.19 50/50] Btrfs: use nofs context when initializing security xattrs to avoid deadlock Greg Kroah-Hartman
2019-01-16  2:00 ` [PATCH 4.19 00/50] 4.19.16-stable review shuah
2019-01-16 11:49 ` Naresh Kamboju
2019-01-16 20:38 ` Guenter Roeck

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190115154912.527086979@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=bfields@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=vvs@virtuozzo.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox