From 3b0e97b92f7e66158b7a5ac9461d0705d04f8b3a Mon Sep 17 00:00:00 2001 From: Sona Sarmadi Date: Tue, 26 Sep 2017 10:49:41 +0200 Subject: linux-cavium: CVE-2017-7645 nfsd: Incorrect handling of long RPC replies Reference: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-7645 Signed-off-by: Sona Sarmadi Signed-off-by: Adrian Dudau --- .../linux/linux-cavium/CVE-2017-7645.patch | 109 +++++++++++++++++++++ recipes-kernel/linux/linux-cavium_4.9.inc | 1 + 2 files changed, 110 insertions(+) create mode 100644 recipes-kernel/linux/linux-cavium/CVE-2017-7645.patch diff --git a/recipes-kernel/linux/linux-cavium/CVE-2017-7645.patch b/recipes-kernel/linux/linux-cavium/CVE-2017-7645.patch new file mode 100644 index 0000000..2852f41 --- /dev/null +++ b/recipes-kernel/linux/linux-cavium/CVE-2017-7645.patch @@ -0,0 +1,109 @@ +From fc6445df466f37291a70937642068bda78802a5b Mon Sep 17 00:00:00 2001 +From: "J. Bruce Fields" +Date: Fri, 21 Apr 2017 16:10:18 -0400 +Subject: [PATCH] nfsd: check for oversized NFSv2/v3 arguments +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit e6838a29ecb484c97e4efef9429643b9851fba6e upstream. + +A client can append random data to the end of an NFSv2 or NFSv3 RPC call +without our complaining; we'll just stop parsing at the end of the +expected data and ignore the rest. + +Encoded arguments and replies are stored together in an array of pages, +and if a call is too large it could leave inadequate space for the +reply. This is normally OK because NFS RPC's typically have either +short arguments and long replies (like READ) or long arguments and short +replies (like WRITE). But a client that sends an incorrectly long reply +can violate those assumptions. This was observed to cause crashes. + +Also, several operations increment rq_next_page in the decode routine +before checking the argument size, which can leave rq_next_page pointing +well past the end of the page array, causing trouble later in +svc_free_pages. + +So, following a suggestion from Neil Brown, add a central check to +enforce our expectation that no NFSv2/v3 call has both a large call and +a large reply. + +As followup we may also want to rewrite the encoding routines to check +more carefully that they aren't running off the end of the page array. + +We may also consider rejecting calls that have any extra garbage +appended. That would be safer, and within our rights by spec, but given +the age of our server and the NFS protocol, and the fact that we've +never enforced this before, we may need to balance that against the +possibility of breaking some oddball client. + +CVE: CVE-2017-7645 +Upstream-Status: Backport [backport from: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/commit/?h=v4.9.51&id=fc6445df466f37291a70937642068bda78802a5b] + +Reported-by: Tuomas Haanpää +Reported-by: Ari Kauppi +Reviewed-by: NeilBrown +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sona Sarmadi +--- + fs/nfsd/nfssvc.c | 36 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c +index a2b65fc..1645b97 100644 +--- a/fs/nfsd/nfssvc.c ++++ b/fs/nfsd/nfssvc.c +@@ -733,6 +733,37 @@ static __be32 map_new_errors(u32 vers, __be32 nfserr) + return nfserr; + } + ++/* ++ * A write procedure can have a large argument, and a read procedure can ++ * have a large reply, but no NFSv2 or NFSv3 procedure has argument and ++ * reply that can both be larger than a page. The xdr code has taken ++ * advantage of this assumption to be a sloppy about bounds checking in ++ * some cases. Pending a rewrite of the NFSv2/v3 xdr code to fix that ++ * problem, we enforce these assumptions here: ++ */ ++static bool nfs_request_too_big(struct svc_rqst *rqstp, ++ struct svc_procedure *proc) ++{ ++ /* ++ * The ACL code has more careful bounds-checking and is not ++ * susceptible to this problem: ++ */ ++ if (rqstp->rq_prog != NFS_PROGRAM) ++ return false; ++ /* ++ * Ditto NFSv4 (which can in theory have argument and reply both ++ * more than a page): ++ */ ++ if (rqstp->rq_vers >= 4) ++ return false; ++ /* The reply will be small, we're OK: */ ++ if (proc->pc_xdrressize > 0 && ++ proc->pc_xdrressize < XDR_QUADLEN(PAGE_SIZE)) ++ return false; ++ ++ return rqstp->rq_arg.len > PAGE_SIZE; ++} ++ + int + nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) + { +@@ -745,6 +776,11 @@ static __be32 map_new_errors(u32 vers, __be32 nfserr) + rqstp->rq_vers, rqstp->rq_proc); + proc = rqstp->rq_procinfo; + ++ if (nfs_request_too_big(rqstp, proc)) { ++ dprintk("nfsd: NFSv%d argument too large\n", rqstp->rq_vers); ++ *statp = rpc_garbage_args; ++ return 1; ++ } + /* + * Give the xdr decoder a chance to change this if it wants + * (necessary in the NFSv4.0 compound case) +-- +1.9.1 + diff --git a/recipes-kernel/linux/linux-cavium_4.9.inc b/recipes-kernel/linux/linux-cavium_4.9.inc index aea3477..a3eab1a 100644 --- a/recipes-kernel/linux/linux-cavium_4.9.inc +++ b/recipes-kernel/linux/linux-cavium_4.9.inc @@ -24,6 +24,7 @@ SRC_URI = "git://git@git.enea.com/linux/linux-cavium.git;protocol=ssh;name=machi file://CVE-2017-8068.patch \ file://CVE-2017-8069.patch \ file://CVE-2017-7618.patch \ + file://CVE-2017-7645.patch \ " LINUX_KERNEL_TYPE = "tiny" -- cgit v1.2.3-54-g00ecf