|
|
661362 |
From 9b4bc5423447796134efeabaf76fbd669428a028 Mon Sep 17 00:00:00 2001
|
|
|
661362 |
From: Yannick Cote <ycote@redhat.com>
|
|
|
661362 |
Date: Fri, 2 Dec 2022 12:58:38 -0500
|
|
|
661362 |
Subject: [KPATCH CVE-2022-43945] kpatch fixes for CVE-2022-43945
|
|
|
661362 |
|
|
|
661362 |
Kernels:
|
|
|
661362 |
4.18.0-425.3.1.el8
|
|
|
661362 |
4.18.0-425.10.1.el8_7
|
|
|
661362 |
|
|
|
661362 |
|
|
|
661362 |
Kpatch-MR: https://gitlab.com/redhat/prdsc/rhel/src/kpatch/rhel-8/-/merge_requests/76
|
|
|
661362 |
Approved-by: Joe Lawrence (@joe.lawrence)
|
|
|
661362 |
Changes since last build:
|
|
|
661362 |
arches: x86_64 ppc64le
|
|
|
661362 |
callback_xdr.o: changed function: nfs_callback_dispatch
|
|
|
661362 |
mremap.o: changed function: move_page_tables
|
|
|
661362 |
nfs3proc.o: changed function: nfsd3_init_dirlist_pages
|
|
|
661362 |
nfs3proc.o: changed function: nfsd3_proc_read
|
|
|
661362 |
nfsproc.o: changed function: nfsd_proc_read
|
|
|
661362 |
nfsproc.o: changed function: nfsd_proc_readdir
|
|
|
661362 |
nfssvc.o: changed function: nfsd_dispatch
|
|
|
661362 |
svc.o: changed function: nlmsvc_dispatch
|
|
|
661362 |
---------------------------
|
|
|
661362 |
|
|
|
661362 |
Modifications:
|
|
|
661362 |
- Take out modifications to header routines and roll new kpatch versions
|
|
|
661362 |
of them to be included at all call sites.
|
|
|
661362 |
- Wrapped new routines: svcxdr_init_decode(), svcxdr_init_encode()
|
|
|
661362 |
|
|
|
661362 |
commit e608b2dbbb132ebed6b63967b0915159cdf52ce4
|
|
|
661362 |
Author: Scott Mayhew <smayhew@redhat.com>
|
|
|
661362 |
Date: Thu Nov 10 13:46:47 2022 -0500
|
|
|
661362 |
|
|
|
661362 |
SUNRPC: Fix svcxdr_init_decode's end-of-buffer calculation
|
|
|
661362 |
|
|
|
661362 |
Bugzilla: https://bugzilla.redhat.com/2143172
|
|
|
661362 |
CVE: CVE-2022-43945
|
|
|
661362 |
Y-Commit: 804daece339d51a00b7b466cc648139009b1c0fb
|
|
|
661362 |
|
|
|
661362 |
O-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2141774
|
|
|
661362 |
O-CVE: CVE-2022-43945
|
|
|
661362 |
|
|
|
661362 |
commit 90bfc37b5ab91c1a6165e3e5cfc49bf04571b762
|
|
|
661362 |
Author: Chuck Lever <chuck.lever@oracle.com>
|
|
|
661362 |
Date: Thu Sep 1 15:09:53 2022 -0400
|
|
|
661362 |
|
|
|
661362 |
SUNRPC: Fix svcxdr_init_decode's end-of-buffer calculation
|
|
|
661362 |
|
|
|
661362 |
Ensure that stream-based argument decoding can't go past the actual
|
|
|
661362 |
end of the receive buffer. xdr_init_decode's calculation of the
|
|
|
661362 |
value of xdr->end over-estimates the end of the buffer because the
|
|
|
661362 |
Linux kernel RPC server code does not remove the size of the RPC
|
|
|
661362 |
header from rqstp->rq_arg before calling the upper layer's
|
|
|
661362 |
dispatcher.
|
|
|
661362 |
|
|
|
661362 |
The server-side still uses the svc_getnl() macros to decode the
|
|
|
661362 |
RPC call header. These macros reduce the length of the head iov
|
|
|
661362 |
but do not update the total length of the message in the buffer
|
|
|
661362 |
(buf->len).
|
|
|
661362 |
|
|
|
661362 |
A proper fix for this would be to replace the use of svc_getnl() and
|
|
|
661362 |
friends in the RPC header decoder, but that would be a large and
|
|
|
661362 |
invasive change that would be difficult to backport.
|
|
|
661362 |
|
|
|
661362 |
Fixes: 5191955d6fc6 ("SUNRPC: Prepare for xdr_stream-style decoding on the server-side")
|
|
|
661362 |
Reviewed-by: Jeff Layton <jlayton@kernel.org>
|
|
|
661362 |
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
661362 |
|
|
|
661362 |
Signed-off-by: Scott Mayhew <smayhew@redhat.com>
|
|
|
661362 |
Signed-off-by: Jarod Wilson <jarod@redhat.com>
|
|
|
661362 |
|
|
|
661362 |
commit c43d2ebcf1b3893e044ee76490cbc225212dcd09
|
|
|
661362 |
Author: Scott Mayhew <smayhew@redhat.com>
|
|
|
661362 |
Date: Thu Nov 10 13:46:47 2022 -0500
|
|
|
661362 |
|
|
|
661362 |
SUNRPC: Fix svcxdr_init_encode's buflen calculation
|
|
|
661362 |
|
|
|
661362 |
Bugzilla: https://bugzilla.redhat.com/2143172
|
|
|
661362 |
CVE: CVE-2022-43945
|
|
|
661362 |
Y-Commit: 0dfe425436b4e11f1cd68ed8cbf4a8c4276d47c6
|
|
|
661362 |
|
|
|
661362 |
O-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2141774
|
|
|
661362 |
O-CVE: CVE-2022-43945
|
|
|
661362 |
|
|
|
661362 |
commit 1242a87da0d8cd2a428e96ca68e7ea899b0f4624
|
|
|
661362 |
Author: Chuck Lever <chuck.lever@oracle.com>
|
|
|
661362 |
Date: Thu Sep 1 15:09:59 2022 -0400
|
|
|
661362 |
|
|
|
661362 |
SUNRPC: Fix svcxdr_init_encode's buflen calculation
|
|
|
661362 |
|
|
|
661362 |
Commit 2825a7f90753 ("nfsd4: allow encoding across page boundaries")
|
|
|
661362 |
added an explicit computation of the remaining length in the rq_res
|
|
|
661362 |
XDR buffer.
|
|
|
661362 |
|
|
|
661362 |
The computation appears to suffer from an "off-by-one" bug. Because
|
|
|
661362 |
buflen is too large by one page, XDR encoding can run off the end of
|
|
|
661362 |
the send buffer by eventually trying to use the struct page address
|
|
|
661362 |
in rq_page_end, which always contains NULL.
|
|
|
661362 |
|
|
|
661362 |
Fixes: bddfdbcddbe2 ("NFSD: Extract the svcxdr_init_encode() helper")
|
|
|
661362 |
Reviewed-by: Jeff Layton <jlayton@kernel.org>
|
|
|
661362 |
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
661362 |
|
|
|
661362 |
Signed-off-by: Scott Mayhew <smayhew@redhat.com>
|
|
|
661362 |
Signed-off-by: Jarod Wilson <jarod@redhat.com>
|
|
|
661362 |
|
|
|
661362 |
commit 2c36509ef08d24a538bca8369ec0e88420813c3b
|
|
|
661362 |
Author: Scott Mayhew <smayhew@redhat.com>
|
|
|
661362 |
Date: Thu Nov 10 13:46:47 2022 -0500
|
|
|
661362 |
|
|
|
661362 |
NFSD: Protect against send buffer overflow in NFSv2 READDIR
|
|
|
661362 |
|
|
|
661362 |
Bugzilla: https://bugzilla.redhat.com/2143172
|
|
|
661362 |
CVE: CVE-2022-43945
|
|
|
661362 |
Y-Commit: f4e8bb36f1ddd7d2111db324154793c7c6d3cad1
|
|
|
661362 |
|
|
|
661362 |
O-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2141774
|
|
|
661362 |
O-CVE: CVE-2022-43945
|
|
|
661362 |
|
|
|
661362 |
commit 00b4492686e0497fdb924a9d4c8f6f99377e176c
|
|
|
661362 |
Author: Chuck Lever <chuck.lever@oracle.com>
|
|
|
661362 |
Date: Thu Sep 1 15:10:05 2022 -0400
|
|
|
661362 |
|
|
|
661362 |
NFSD: Protect against send buffer overflow in NFSv2 READDIR
|
|
|
661362 |
|
|
|
661362 |
Restore the previous limit on the @count argument to prevent a
|
|
|
661362 |
buffer overflow attack.
|
|
|
661362 |
|
|
|
661362 |
Fixes: 53b1119a6e50 ("NFSD: Fix READDIR buffer overflow")
|
|
|
661362 |
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
661362 |
Reviewed-by: Jeff Layton <jlayton@kernel.org>
|
|
|
661362 |
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
661362 |
|
|
|
661362 |
Signed-off-by: Scott Mayhew <smayhew@redhat.com>
|
|
|
661362 |
Signed-off-by: Jarod Wilson <jarod@redhat.com>
|
|
|
661362 |
|
|
|
661362 |
commit e7f5ff9960dd6667538bf642a42168473e1d987d
|
|
|
661362 |
Author: Scott Mayhew <smayhew@redhat.com>
|
|
|
661362 |
Date: Thu Nov 10 13:46:47 2022 -0500
|
|
|
661362 |
|
|
|
661362 |
NFSD: Protect against send buffer overflow in NFSv3 READDIR
|
|
|
661362 |
|
|
|
661362 |
Bugzilla: https://bugzilla.redhat.com/2143172
|
|
|
661362 |
CVE: CVE-2022-43945
|
|
|
661362 |
Y-Commit: c33579e1e26c423888888482a0e1ca9a0980f292
|
|
|
661362 |
|
|
|
661362 |
O-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2141774
|
|
|
661362 |
O-CVE: CVE-2022-43945
|
|
|
661362 |
|
|
|
661362 |
commit 640f87c190e0d1b2a0fcb2ecf6d2cd53b1c41991
|
|
|
661362 |
Author: Chuck Lever <chuck.lever@oracle.com>
|
|
|
661362 |
Date: Thu Sep 1 15:10:12 2022 -0400
|
|
|
661362 |
|
|
|
661362 |
NFSD: Protect against send buffer overflow in NFSv3 READDIR
|
|
|
661362 |
|
|
|
661362 |
Since before the git era, NFSD has conserved the number of pages
|
|
|
661362 |
held by each nfsd thread by combining the RPC receive and send
|
|
|
661362 |
buffers into a single array of pages. This works because there are
|
|
|
661362 |
no cases where an operation needs a large RPC Call message and a
|
|
|
661362 |
large RPC Reply message at the same time.
|
|
|
661362 |
|
|
|
661362 |
Once an RPC Call has been received, svc_process() updates
|
|
|
661362 |
svc_rqst::rq_res to describe the part of rq_pages that can be
|
|
|
661362 |
used for constructing the Reply. This means that the send buffer
|
|
|
661362 |
(rq_res) shrinks when the received RPC record containing the RPC
|
|
|
661362 |
Call is large.
|
|
|
661362 |
|
|
|
661362 |
A client can force this shrinkage on TCP by sending a correctly-
|
|
|
661362 |
formed RPC Call header contained in an RPC record that is
|
|
|
661362 |
excessively large. The full maximum payload size cannot be
|
|
|
661362 |
constructed in that case.
|
|
|
661362 |
|
|
|
661362 |
Thanks to Aleksi Illikainen and Kari Hulkko for uncovering this
|
|
|
661362 |
issue.
|
|
|
661362 |
|
|
|
661362 |
Reported-by: Ben Ronallo <Benjamin.Ronallo@synopsys.com>
|
|
|
661362 |
Cc: <stable@vger.kernel.org>
|
|
|
661362 |
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
661362 |
Reviewed-by: Jeff Layton <jlayton@kernel.org>
|
|
|
661362 |
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
661362 |
|
|
|
661362 |
Signed-off-by: Scott Mayhew <smayhew@redhat.com>
|
|
|
661362 |
Signed-off-by: Jarod Wilson <jarod@redhat.com>
|
|
|
661362 |
|
|
|
661362 |
commit be58a0f8fe047e3cbc9891133b34cd323d01f8e3
|
|
|
661362 |
Author: Scott Mayhew <smayhew@redhat.com>
|
|
|
661362 |
Date: Thu Nov 10 13:46:47 2022 -0500
|
|
|
661362 |
|
|
|
661362 |
NFSD: Protect against send buffer overflow in NFSv2 READ
|
|
|
661362 |
|
|
|
661362 |
Bugzilla: https://bugzilla.redhat.com/2143172
|
|
|
661362 |
CVE: CVE-2022-43945
|
|
|
661362 |
Y-Commit: 436325d0734d253f50a547b842a95ed4bb752ae3
|
|
|
661362 |
|
|
|
661362 |
O-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2141774
|
|
|
661362 |
O-CVE: CVE-2022-43945
|
|
|
661362 |
|
|
|
661362 |
commit 401bc1f90874280a80b93f23be33a0e7e2d1f912
|
|
|
661362 |
Author: Chuck Lever <chuck.lever@oracle.com>
|
|
|
661362 |
Date: Thu Sep 1 15:10:18 2022 -0400
|
|
|
661362 |
|
|
|
661362 |
NFSD: Protect against send buffer overflow in NFSv2 READ
|
|
|
661362 |
|
|
|
661362 |
Since before the git era, NFSD has conserved the number of pages
|
|
|
661362 |
held by each nfsd thread by combining the RPC receive and send
|
|
|
661362 |
buffers into a single array of pages. This works because there are
|
|
|
661362 |
no cases where an operation needs a large RPC Call message and a
|
|
|
661362 |
large RPC Reply at the same time.
|
|
|
661362 |
|
|
|
661362 |
Once an RPC Call has been received, svc_process() updates
|
|
|
661362 |
svc_rqst::rq_res to describe the part of rq_pages that can be
|
|
|
661362 |
used for constructing the Reply. This means that the send buffer
|
|
|
661362 |
(rq_res) shrinks when the received RPC record containing the RPC
|
|
|
661362 |
Call is large.
|
|
|
661362 |
|
|
|
661362 |
A client can force this shrinkage on TCP by sending a correctly-
|
|
|
661362 |
formed RPC Call header contained in an RPC record that is
|
|
|
661362 |
excessively large. The full maximum payload size cannot be
|
|
|
661362 |
constructed in that case.
|
|
|
661362 |
|
|
|
661362 |
Cc: <stable@vger.kernel.org>
|
|
|
661362 |
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
661362 |
Reviewed-by: Jeff Layton <jlayton@kernel.org>
|
|
|
661362 |
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
661362 |
|
|
|
661362 |
Signed-off-by: Scott Mayhew <smayhew@redhat.com>
|
|
|
661362 |
Signed-off-by: Jarod Wilson <jarod@redhat.com>
|
|
|
661362 |
|
|
|
661362 |
commit b0be04c547fb3f2c98bda81f9f93e68dfdcad398
|
|
|
661362 |
Author: Scott Mayhew <smayhew@redhat.com>
|
|
|
661362 |
Date: Thu Nov 10 13:46:46 2022 -0500
|
|
|
661362 |
|
|
|
661362 |
NFSD: Protect against send buffer overflow in NFSv3 READ
|
|
|
661362 |
|
|
|
661362 |
Bugzilla: https://bugzilla.redhat.com/2143172
|
|
|
661362 |
CVE: CVE-2022-43945
|
|
|
661362 |
Y-Commit: cc970cde839098c5dd3d1dd013620ca972d4c9db
|
|
|
661362 |
|
|
|
661362 |
O-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2141774
|
|
|
661362 |
O-CVE: CVE-2022-43945
|
|
|
661362 |
|
|
|
661362 |
commit fa6be9cc6e80ec79892ddf08a8c10cabab9baf38
|
|
|
661362 |
Author: Chuck Lever <chuck.lever@oracle.com>
|
|
|
661362 |
Date: Thu Sep 1 15:10:24 2022 -0400
|
|
|
661362 |
|
|
|
661362 |
NFSD: Protect against send buffer overflow in NFSv3 READ
|
|
|
661362 |
|
|
|
661362 |
Since before the git era, NFSD has conserved the number of pages
|
|
|
661362 |
held by each nfsd thread by combining the RPC receive and send
|
|
|
661362 |
buffers into a single array of pages. This works because there are
|
|
|
661362 |
no cases where an operation needs a large RPC Call message and a
|
|
|
661362 |
large RPC Reply at the same time.
|
|
|
661362 |
|
|
|
661362 |
Once an RPC Call has been received, svc_process() updates
|
|
|
661362 |
svc_rqst::rq_res to describe the part of rq_pages that can be
|
|
|
661362 |
used for constructing the Reply. This means that the send buffer
|
|
|
661362 |
(rq_res) shrinks when the received RPC record containing the RPC
|
|
|
661362 |
Call is large.
|
|
|
661362 |
|
|
|
661362 |
A client can force this shrinkage on TCP by sending a correctly-
|
|
|
661362 |
formed RPC Call header contained in an RPC record that is
|
|
|
661362 |
excessively large. The full maximum payload size cannot be
|
|
|
661362 |
constructed in that case.
|
|
|
661362 |
|
|
|
661362 |
Cc: <stable@vger.kernel.org>
|
|
|
661362 |
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
661362 |
Reviewed-by: Jeff Layton <jlayton@kernel.org>
|
|
|
661362 |
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
661362 |
|
|
|
661362 |
Signed-off-by: Scott Mayhew <smayhew@redhat.com>
|
|
|
661362 |
Signed-off-by: Jarod Wilson <jarod@redhat.com>
|
|
|
661362 |
|
|
|
661362 |
Signed-off-by: Yannick Cote <ycote@redhat.com>
|
|
|
661362 |
---
|
|
|
661362 |
fs/lockd/svc.c | 6 ++-
|
|
|
661362 |
fs/nfs/callback_xdr.c | 6 ++-
|
|
|
661362 |
fs/nfsd/nfs3proc.c | 11 +++---
|
|
|
661362 |
fs/nfsd/nfsproc.c | 6 +--
|
|
|
661362 |
fs/nfsd/nfssvc.c | 6 ++-
|
|
|
661362 |
include/linux/kpatch_cve_2022_43945.h | 53 +++++++++++++++++++++++++++
|
|
|
661362 |
6 files changed, 74 insertions(+), 14 deletions(-)
|
|
|
661362 |
create mode 100644 include/linux/kpatch_cve_2022_43945.h
|
|
|
661362 |
|
|
|
661362 |
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
|
|
|
661362 |
index 31fd841010c2..13f3813b38a8 100644
|
|
|
661362 |
--- a/fs/lockd/svc.c
|
|
|
661362 |
+++ b/fs/lockd/svc.c
|
|
|
661362 |
@@ -767,6 +767,8 @@ static void __exit exit_nlm(void)
|
|
|
661362 |
module_init(init_nlm);
|
|
|
661362 |
module_exit(exit_nlm);
|
|
|
661362 |
|
|
|
661362 |
+#include <linux/kpatch_cve_2022_43945.h>
|
|
|
661362 |
+
|
|
|
661362 |
/**
|
|
|
661362 |
* nlmsvc_dispatch - Process an NLM Request
|
|
|
661362 |
* @rqstp: incoming request
|
|
|
661362 |
@@ -780,7 +782,7 @@ static int nlmsvc_dispatch(struct svc_rqst *rqstp, __be32 *statp)
|
|
|
661362 |
{
|
|
|
661362 |
const struct svc_procedure *procp = rqstp->rq_procinfo;
|
|
|
661362 |
|
|
|
661362 |
- svcxdr_init_decode(rqstp);
|
|
|
661362 |
+ kpatch_cve_2022_43945_svcxdr_init_decode(rqstp);
|
|
|
661362 |
if (!procp->pc_decode(rqstp, &rqstp->rq_arg_stream))
|
|
|
661362 |
goto out_decode_err;
|
|
|
661362 |
|
|
|
661362 |
@@ -790,7 +792,7 @@ static int nlmsvc_dispatch(struct svc_rqst *rqstp, __be32 *statp)
|
|
|
661362 |
if (*statp != rpc_success)
|
|
|
661362 |
return 1;
|
|
|
661362 |
|
|
|
661362 |
- svcxdr_init_encode(rqstp);
|
|
|
661362 |
+ kpatch_cve_2022_43945_svcxdr_init_encode(rqstp);
|
|
|
661362 |
if (!procp->pc_encode(rqstp, &rqstp->rq_res_stream))
|
|
|
661362 |
goto out_encode_err;
|
|
|
661362 |
|
|
|
661362 |
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
|
|
|
661362 |
index a67c41ec545f..9438f91b9c2d 100644
|
|
|
661362 |
--- a/fs/nfs/callback_xdr.c
|
|
|
661362 |
+++ b/fs/nfs/callback_xdr.c
|
|
|
661362 |
@@ -983,13 +983,15 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp)
|
|
|
661362 |
return rpc_success;
|
|
|
661362 |
}
|
|
|
661362 |
|
|
|
661362 |
+#include <linux/kpatch_cve_2022_43945.h>
|
|
|
661362 |
+
|
|
|
661362 |
static int
|
|
|
661362 |
nfs_callback_dispatch(struct svc_rqst *rqstp, __be32 *statp)
|
|
|
661362 |
{
|
|
|
661362 |
const struct svc_procedure *procp = rqstp->rq_procinfo;
|
|
|
661362 |
|
|
|
661362 |
- svcxdr_init_decode(rqstp);
|
|
|
661362 |
- svcxdr_init_encode(rqstp);
|
|
|
661362 |
+ kpatch_cve_2022_43945_svcxdr_init_decode(rqstp);
|
|
|
661362 |
+ kpatch_cve_2022_43945_svcxdr_init_encode(rqstp);
|
|
|
661362 |
|
|
|
661362 |
*statp = procp->pc_func(rqstp);
|
|
|
661362 |
return 1;
|
|
|
661362 |
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
|
|
|
661362 |
index f1d81704d5bd..233f07958b09 100644
|
|
|
661362 |
--- a/fs/nfsd/nfs3proc.c
|
|
|
661362 |
+++ b/fs/nfsd/nfs3proc.c
|
|
|
661362 |
@@ -146,7 +146,6 @@ nfsd3_proc_read(struct svc_rqst *rqstp)
|
|
|
661362 |
{
|
|
|
661362 |
struct nfsd3_readargs *argp = rqstp->rq_argp;
|
|
|
661362 |
struct nfsd3_readres *resp = rqstp->rq_resp;
|
|
|
661362 |
- u32 max_blocksize = svc_max_payload(rqstp);
|
|
|
661362 |
unsigned int len;
|
|
|
661362 |
int v;
|
|
|
661362 |
|
|
|
661362 |
@@ -155,7 +154,8 @@ nfsd3_proc_read(struct svc_rqst *rqstp)
|
|
|
661362 |
(unsigned long) argp->count,
|
|
|
661362 |
(unsigned long long) argp->offset);
|
|
|
661362 |
|
|
|
661362 |
- argp->count = min_t(u32, argp->count, max_blocksize);
|
|
|
661362 |
+ argp->count = min_t(u32, argp->count, svc_max_payload(rqstp));
|
|
|
661362 |
+ argp->count = min_t(u32, argp->count, rqstp->rq_res.buflen);
|
|
|
661362 |
if (argp->offset > (u64)OFFSET_MAX)
|
|
|
661362 |
argp->offset = (u64)OFFSET_MAX;
|
|
|
661362 |
if (argp->offset + argp->count > (u64)OFFSET_MAX)
|
|
|
661362 |
@@ -451,13 +451,14 @@ static void nfsd3_init_dirlist_pages(struct svc_rqst *rqstp,
|
|
|
661362 |
{
|
|
|
661362 |
struct xdr_buf *buf = &resp->dirlist;
|
|
|
661362 |
struct xdr_stream *xdr = &resp->xdr;
|
|
|
661362 |
-
|
|
|
661362 |
- count = clamp(count, (u32)(XDR_UNIT * 2), svc_max_payload(rqstp));
|
|
|
661362 |
+ unsigned int sendbuf = min_t(unsigned int, rqstp->rq_res.buflen,
|
|
|
661362 |
+ svc_max_payload(rqstp));
|
|
|
661362 |
|
|
|
661362 |
memset(buf, 0, sizeof(*buf));
|
|
|
661362 |
|
|
|
661362 |
/* Reserve room for the NULL ptr & eof flag (-2 words) */
|
|
|
661362 |
- buf->buflen = count - XDR_UNIT * 2;
|
|
|
661362 |
+ buf->buflen = clamp(count, (u32)(XDR_UNIT * 2), sendbuf);
|
|
|
661362 |
+ buf->buflen -= XDR_UNIT * 2;
|
|
|
661362 |
buf->pages = rqstp->rq_next_page;
|
|
|
661362 |
rqstp->rq_next_page += (buf->buflen + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
|
|
661362 |
|
|
|
661362 |
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
|
|
|
661362 |
index e4b0e0e6d1bc..87d0c443767c 100644
|
|
|
661362 |
--- a/fs/nfsd/nfsproc.c
|
|
|
661362 |
+++ b/fs/nfsd/nfsproc.c
|
|
|
661362 |
@@ -182,6 +182,7 @@ nfsd_proc_read(struct svc_rqst *rqstp)
|
|
|
661362 |
argp->count, argp->offset);
|
|
|
661362 |
|
|
|
661362 |
argp->count = min_t(u32, argp->count, NFSSVC_MAXBLKSIZE_V2);
|
|
|
661362 |
+ argp->count = min_t(u32, argp->count, rqstp->rq_res.buflen);
|
|
|
661362 |
|
|
|
661362 |
v = 0;
|
|
|
661362 |
len = argp->count;
|
|
|
661362 |
@@ -561,12 +562,11 @@ static void nfsd_init_dirlist_pages(struct svc_rqst *rqstp,
|
|
|
661362 |
struct xdr_buf *buf = &resp->dirlist;
|
|
|
661362 |
struct xdr_stream *xdr = &resp->xdr;
|
|
|
661362 |
|
|
|
661362 |
- count = clamp(count, (u32)(XDR_UNIT * 2), svc_max_payload(rqstp));
|
|
|
661362 |
-
|
|
|
661362 |
memset(buf, 0, sizeof(*buf));
|
|
|
661362 |
|
|
|
661362 |
/* Reserve room for the NULL ptr & eof flag (-2 words) */
|
|
|
661362 |
- buf->buflen = count - XDR_UNIT * 2;
|
|
|
661362 |
+ buf->buflen = clamp(count, (u32)(XDR_UNIT * 2), (u32)PAGE_SIZE);
|
|
|
661362 |
+ buf->buflen -= XDR_UNIT * 2;
|
|
|
661362 |
buf->pages = rqstp->rq_next_page;
|
|
|
661362 |
rqstp->rq_next_page++;
|
|
|
661362 |
|
|
|
661362 |
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
|
|
|
661362 |
index c3c5613c29a8..b9aaf205ec0f 100644
|
|
|
661362 |
--- a/fs/nfsd/nfssvc.c
|
|
|
661362 |
+++ b/fs/nfsd/nfssvc.c
|
|
|
661362 |
@@ -985,6 +985,8 @@ nfsd(void *vrqstp)
|
|
|
661362 |
return 0;
|
|
|
661362 |
}
|
|
|
661362 |
|
|
|
661362 |
+#include <linux/kpatch_cve_2022_43945.h>
|
|
|
661362 |
+
|
|
|
661362 |
/**
|
|
|
661362 |
* nfsd_dispatch - Process an NFS or NFSACL Request
|
|
|
661362 |
* @rqstp: incoming request
|
|
|
661362 |
@@ -1006,7 +1008,7 @@ int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
|
|
|
661362 |
*/
|
|
|
661362 |
rqstp->rq_cachetype = proc->pc_cachetype;
|
|
|
661362 |
|
|
|
661362 |
- svcxdr_init_decode(rqstp);
|
|
|
661362 |
+ kpatch_cve_2022_43945_svcxdr_init_decode(rqstp);
|
|
|
661362 |
if (!proc->pc_decode(rqstp, &rqstp->rq_arg_stream))
|
|
|
661362 |
goto out_decode_err;
|
|
|
661362 |
|
|
|
661362 |
@@ -1023,7 +1025,7 @@ int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
|
|
|
661362 |
* Need to grab the location to store the status, as
|
|
|
661362 |
* NFSv4 does some encoding while processing
|
|
|
661362 |
*/
|
|
|
661362 |
- svcxdr_init_encode(rqstp);
|
|
|
661362 |
+ kpatch_cve_2022_43945_svcxdr_init_encode(rqstp);
|
|
|
661362 |
|
|
|
661362 |
*statp = proc->pc_func(rqstp);
|
|
|
661362 |
if (*statp == rpc_drop_reply || test_bit(RQ_DROPME, &rqstp->rq_flags))
|
|
|
661362 |
diff --git a/include/linux/kpatch_cve_2022_43945.h b/include/linux/kpatch_cve_2022_43945.h
|
|
|
661362 |
new file mode 100644
|
|
|
661362 |
index 000000000000..d52392485a57
|
|
|
661362 |
--- /dev/null
|
|
|
661362 |
+++ b/include/linux/kpatch_cve_2022_43945.h
|
|
|
661362 |
@@ -0,0 +1,53 @@
|
|
|
661362 |
+#ifndef _KPATCH_CVE_2022_43945_H
|
|
|
661362 |
+#define _KPATCH_CVE_2022_43945_H
|
|
|
661362 |
+
|
|
|
661362 |
+/*
|
|
|
661362 |
+ * svcxdr_init_decode - Prepare an xdr_stream for Call decoding
|
|
|
661362 |
+ * @rqstp: controlling server RPC transaction context
|
|
|
661362 |
+ *
|
|
|
661362 |
+ * This function currently assumes the RPC header in rq_arg has
|
|
|
661362 |
+ * already been decoded. Upon return, xdr->p points to the
|
|
|
661362 |
+ * location of the upper layer header.
|
|
|
661362 |
+ */
|
|
|
661362 |
+static inline void kpatch_cve_2022_43945_svcxdr_init_decode(struct svc_rqst *rqstp)
|
|
|
661362 |
+{
|
|
|
661362 |
+ struct xdr_stream *xdr = &rqstp->rq_arg_stream;
|
|
|
661362 |
+ struct xdr_buf *buf = &rqstp->rq_arg;
|
|
|
661362 |
+ struct kvec *argv = buf->head;
|
|
|
661362 |
+
|
|
|
661362 |
+ /*
|
|
|
661362 |
+ * svc_getnl() and friends do not keep the xdr_buf's ::len
|
|
|
661362 |
+ * field up to date. Refresh that field before initializing
|
|
|
661362 |
+ * the argument decoding stream.
|
|
|
661362 |
+ */
|
|
|
661362 |
+ buf->len = buf->head->iov_len + buf->page_len + buf->tail->iov_len;
|
|
|
661362 |
+
|
|
|
661362 |
+ xdr_init_decode(xdr, buf, argv->iov_base, NULL);
|
|
|
661362 |
+ xdr_set_scratch_page(xdr, rqstp->rq_scratch_page);
|
|
|
661362 |
+}
|
|
|
661362 |
+
|
|
|
661362 |
+/*
|
|
|
661362 |
+ * svcxdr_init_encode - Prepare an xdr_stream for svc Reply encoding
|
|
|
661362 |
+ * @rqstp: controlling server RPC transaction context
|
|
|
661362 |
+ *
|
|
|
661362 |
+ */
|
|
|
661362 |
+static inline void kpatch_cve_2022_43945_svcxdr_init_encode(struct svc_rqst *rqstp)
|
|
|
661362 |
+{
|
|
|
661362 |
+ struct xdr_stream *xdr = &rqstp->rq_res_stream;
|
|
|
661362 |
+ struct xdr_buf *buf = &rqstp->rq_res;
|
|
|
661362 |
+ struct kvec *resv = buf->head;
|
|
|
661362 |
+
|
|
|
661362 |
+ xdr_reset_scratch_buffer(xdr);
|
|
|
661362 |
+
|
|
|
661362 |
+ xdr->buf = buf;
|
|
|
661362 |
+ xdr->iov = resv;
|
|
|
661362 |
+ xdr->p = resv->iov_base + resv->iov_len;
|
|
|
661362 |
+ xdr->end = resv->iov_base + PAGE_SIZE - rqstp->rq_auth_slack;
|
|
|
661362 |
+ buf->len = resv->iov_len;
|
|
|
661362 |
+ xdr->page_ptr = buf->pages - 1;
|
|
|
661362 |
+ buf->buflen = PAGE_SIZE * (rqstp->rq_page_end - buf->pages);
|
|
|
661362 |
+ buf->buflen -= rqstp->rq_auth_slack;
|
|
|
661362 |
+ xdr->rqst = NULL;
|
|
|
661362 |
+}
|
|
|
661362 |
+
|
|
|
661362 |
+#endif /* _KPATCH_CVE_2022_43945_H */
|
|
|
661362 |
--
|
|
|
661362 |
2.39.1
|
|
|
661362 |
|
|
|
661362 |
|