diff options
-rw-r--r-- | CVE-2017-7645.patch | 180 | ||||
-rw-r--r-- | gitrev | 2 | ||||
-rw-r--r-- | kernel.spec | 16 | ||||
-rw-r--r-- | sources | 1 |
4 files changed, 196 insertions, 3 deletions
diff --git a/CVE-2017-7645.patch b/CVE-2017-7645.patch new file mode 100644 index 000000000..0be019cc3 --- /dev/null +++ b/CVE-2017-7645.patch @@ -0,0 +1,180 @@ +From: "J. Bruce Fields" <bfields@redhat.com> +Date: 2017-04-14 15:04:40 +Subject: [PATCH] nfsd: check for oversized NFSv2/v3 arguments + +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. + +So, insist that the argument not be any longer than we expect. + +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. + +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. + +Reported-by: Tuomas Haanpää <thaan@synopsys.com> +Reported-by: Ari Kauppi <ari@synopsys.com> +Cc: stable@vger.kernel.org +Signed-off-by: J. Bruce Fields <bfields@redhat.com> +--- + fs/nfsd/nfs3xdr.c | 23 +++++++++++++++++------ + fs/nfsd/nfsxdr.c | 13 ++++++++++--- + include/linux/sunrpc/svc.h | 3 +-- + 3 files changed, 28 insertions(+), 11 deletions(-) + +diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c +index dba2ff8eaa68..be66bcadfaea 100644 +--- a/fs/nfsd/nfs3xdr.c ++++ b/fs/nfsd/nfs3xdr.c +@@ -334,8 +334,11 @@ nfs3svc_decode_readargs(struct svc_rqst *rqstp, __be32 *p, + if (!p) + return 0; + p = xdr_decode_hyper(p, &args->offset); +- + args->count = ntohl(*p++); ++ ++ if (!xdr_argsize_check(rqstp, p)) ++ return 0; ++ + len = min(args->count, max_blocksize); + + /* set up the kvec */ +@@ -349,7 +352,7 @@ nfs3svc_decode_readargs(struct svc_rqst *rqstp, __be32 *p, + v++; + } + args->vlen = v; +- return xdr_argsize_check(rqstp, p); ++ return 1; + } + + int +@@ -536,9 +539,11 @@ nfs3svc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p, + p = decode_fh(p, &args->fh); + if (!p) + return 0; ++ if (!xdr_argsize_check(rqstp, p)) ++ return 0; + args->buffer = page_address(*(rqstp->rq_next_page++)); + +- return xdr_argsize_check(rqstp, p); ++ return 1; + } + + int +@@ -564,10 +569,14 @@ nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p, + args->verf = p; p += 2; + args->dircount = ~0; + args->count = ntohl(*p++); ++ ++ if (!xdr_argsize_check(rqstp, p)) ++ return 0; ++ + args->count = min_t(u32, args->count, PAGE_SIZE); + args->buffer = page_address(*(rqstp->rq_next_page++)); + +- return xdr_argsize_check(rqstp, p); ++ return 1; + } + + int +@@ -585,6 +594,9 @@ nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p, + args->dircount = ntohl(*p++); + args->count = ntohl(*p++); + ++ if (!xdr_argsize_check(rqstp, p)) ++ return 0; ++ + len = args->count = min(args->count, max_blocksize); + while (len > 0) { + struct page *p = *(rqstp->rq_next_page++); +@@ -592,8 +604,7 @@ nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p, + args->buffer = page_address(p); + len -= PAGE_SIZE; + } +- +- return xdr_argsize_check(rqstp, p); ++ return 1; + } + + int +diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c +index 41b468a6a90f..79268369f7b3 100644 +--- a/fs/nfsd/nfsxdr.c ++++ b/fs/nfsd/nfsxdr.c +@@ -257,6 +257,9 @@ nfssvc_decode_readargs(struct svc_rqst *rqstp, __be32 *p, + len = args->count = ntohl(*p++); + p++; /* totalcount - unused */ + ++ if (!xdr_argsize_check(rqstp, p)) ++ return 0; ++ + len = min_t(unsigned int, len, NFSSVC_MAXBLKSIZE_V2); + + /* set up somewhere to store response. +@@ -272,7 +275,7 @@ nfssvc_decode_readargs(struct svc_rqst *rqstp, __be32 *p, + v++; + } + args->vlen = v; +- return xdr_argsize_check(rqstp, p); ++ return 1; + } + + int +@@ -360,9 +363,11 @@ nfssvc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd_readli + p = decode_fh(p, &args->fh); + if (!p) + return 0; ++ if (!xdr_argsize_check(rqstp, p)) ++ return 0; + args->buffer = page_address(*(rqstp->rq_next_page++)); + +- return xdr_argsize_check(rqstp, p); ++ return 1; + } + + int +@@ -400,9 +405,11 @@ nfssvc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p, + args->cookie = ntohl(*p++); + args->count = ntohl(*p++); + args->count = min_t(u32, args->count, PAGE_SIZE); ++ if (!xdr_argsize_check(rqstp, p)) ++ return 0; + args->buffer = page_address(*(rqstp->rq_next_page++)); + +- return xdr_argsize_check(rqstp, p); ++ return 1; + } + + /* +diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h +index e770abeed32d..6ef19cf658b4 100644 +--- a/include/linux/sunrpc/svc.h ++++ b/include/linux/sunrpc/svc.h +@@ -336,8 +336,7 @@ xdr_argsize_check(struct svc_rqst *rqstp, __be32 *p) + { + char *cp = (char *)p; + struct kvec *vec = &rqstp->rq_arg.head[0]; +- return cp >= (char*)vec->iov_base +- && cp <= (char*)vec->iov_base + vec->iov_len; ++ return cp == (char *)vec->iov_base + vec->iov_len; + } + + static inline int +-- +2.9.3 + +-- +To unsubscribe from this list: send the line "unsubscribe linux-nfs" in +the body of a message to majordomo@vger.kernel.org +More majordomo info at http://vger.kernel.org/majordomo-info.html @@ -1 +1 @@ -ee921c762cf90652add60ebacb5b90636ac108df +005882e53d62f25dae10351a8d3f13326051e8f5 diff --git a/kernel.spec b/kernel.spec index 9c09ec30b..1ee8357de 100644 --- a/kernel.spec +++ b/kernel.spec @@ -77,7 +77,7 @@ Summary: The Linux kernel # The rc snapshot level %global rcrev 7 # The git snapshot level -%define gitrev 0 +%define gitrev 1 # Set rpm version accordingly %define rpmversion 4.%{upstream_sublevel}.0 %endif @@ -133,7 +133,7 @@ Summary: The Linux kernel # Set debugbuildsenabled to 1 for production (build separate debug kernels) # and 0 for rawhide (all kernels are debug kernels). # See also 'make debug' and 'make release'. -%define debugbuildsenabled 1 +%define debugbuildsenabled 0 # Want to build a vanilla kernel build without any non-upstream patches? %define with_vanilla %{?_without_vanilla: 0} %{?!_without_vanilla: 1} @@ -628,6 +628,9 @@ Patch665: netfilter-x_tables-deal-with-bogus-nextoffset-values.patch #rhbz 1435154 Patch666: powerpc-prom-Increase-RMA-size-to-512MB.patch +# CVE-2017-7645 rhbz 1443615 1443617 +Patch667: CVE-2017-7645.patch + # END OF PATCH DEFINITIONS %endif @@ -2195,6 +2198,15 @@ fi # # %changelog +* Wed Apr 19 2017 Justin M. Forbes <jforbes@fedoraproject.org> +- Fix CVE-2017-7645 (rhbz 1443615 1443617) + +* Wed Apr 19 2017 Laura Abbott <labbott@redhat.com> - 4.11.0-0.rc7.git1.1 +- Linux v4.11-rc7-29-g005882e53d62 + +* Wed Apr 19 2017 Laura Abbott <labbott@redhat.com> +- Reenable debugging options. + * Mon Apr 17 2017 Laura Abbott <labbott@fedoraproject.org> - 4.11.0-0.rc7.git0.1 - Linux v4.11-rc7 @@ -1,3 +1,4 @@ SHA512 (linux-4.10.tar.xz) = c3690125a8402df638095bd98a613fcf1a257b81de7611c84711d315cd11e2634ab4636302b3742aedf1e3ba9ce0fea53fe8c7d48e37865d8ee5db3565220d90 SHA512 (perf-man-4.10.tar.gz) = 2c830e06f47211d70a8330961487af73a8bc01073019475e6b6131d3bb8c95658b77ca0ae5f1b44371accf103658bc5a3a4366b3e017a4088a8fd408dd6867e8 SHA512 (patch-4.11-rc7.xz) = 01abe7a1d4cf5779479f4289734dd74ac202012e2b8058c2451cfa8b355a58ea2397c7f5c29bd5e3ba5a83cbc22bfc4738cd2b6f8caf4baa9e7495bc88340b6d +SHA512 (patch-4.11-rc7-git1.xz) = 69e4aa1435636f74db363302e3b9d29930874950ae5cfc31383c375329c7565706eb6e90ba6f9ed636c62e66827b2b5a46a435826f19209e0de595cfe489dd2c |