Patch "SUNRPC: Fix svcxdr_init_decode's end-of-buffer calculation" has been added to the 5.15-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    SUNRPC: Fix svcxdr_init_decode's end-of-buffer calculation

to the 5.15-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     sunrpc-fix-svcxdr_init_decode-s-end-of-buffer-calcul.patch
and it can be found in the queue-5.15 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit b5a535d6ab638ff6fc6b8cb674301d5e50defdcc
Author: Chuck Lever <chuck.lever@xxxxxxxxxx>
Date:   Thu Sep 1 15:09:53 2022 -0400

    SUNRPC: Fix svcxdr_init_decode's end-of-buffer calculation
    
    [ Upstream commit 90bfc37b5ab91c1a6165e3e5cfc49bf04571b762 ]
    
    Ensure that stream-based argument decoding can't go past the actual
    end of the receive buffer. xdr_init_decode's calculation of the
    value of xdr->end over-estimates the end of the buffer because the
    Linux kernel RPC server code does not remove the size of the RPC
    header from rqstp->rq_arg before calling the upper layer's
    dispatcher.
    
    The server-side still uses the svc_getnl() macros to decode the
    RPC call header. These macros reduce the length of the head iov
    but do not update the total length of the message in the buffer
    (buf->len).
    
    A proper fix for this would be to replace the use of svc_getnl() and
    friends in the RPC header decoder, but that would be a large and
    invasive change that would be difficult to backport.
    
    Fixes: 5191955d6fc6 ("SUNRPC: Prepare for xdr_stream-style decoding on the server-side")
    Reviewed-by: Jeff Layton <jlayton@xxxxxxxxxx>
    Signed-off-by: Chuck Lever <chuck.lever@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 01f09adccc63..6be55d0e73fd 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -566,16 +566,27 @@ static inline void svc_reserve_auth(struct svc_rqst *rqstp, int space)
 }
 
 /**
- * svcxdr_init_decode - Prepare an xdr_stream for svc Call decoding
+ * svcxdr_init_decode - Prepare an xdr_stream for Call decoding
  * @rqstp: controlling server RPC transaction context
  *
+ * This function currently assumes the RPC header in rq_arg has
+ * already been decoded. Upon return, xdr->p points to the
+ * location of the upper layer header.
  */
 static inline void svcxdr_init_decode(struct svc_rqst *rqstp)
 {
 	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
-	struct kvec *argv = rqstp->rq_arg.head;
+	struct xdr_buf *buf = &rqstp->rq_arg;
+	struct kvec *argv = buf->head;
 
-	xdr_init_decode(xdr, &rqstp->rq_arg, argv->iov_base, NULL);
+	/*
+	 * svc_getnl() and friends do not keep the xdr_buf's ::len
+	 * field up to date. Refresh that field before initializing
+	 * the argument decoding stream.
+	 */
+	buf->len = buf->head->iov_len + buf->page_len + buf->tail->iov_len;
+
+	xdr_init_decode(xdr, buf, argv->iov_base, NULL);
 	xdr_set_scratch_page(xdr, rqstp->rq_scratch_page);
 }
 



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux