diff options
author | Sona Sarmadi <sona.sarmadi@enea.com> | 2017-09-26 10:49:41 +0200 |
---|---|---|
committer | Adrian Dudau <adrian.dudau@enea.com> | 2017-09-26 15:36:46 +0200 |
commit | 3b0e97b92f7e66158b7a5ac9461d0705d04f8b3a (patch) | |
tree | 4d6a4d152af835e7e0263b12d4b58b000d33a5d1 | |
parent | 7eddd2b6da1b1ed574e90e19c96b9497e3f59c14 (diff) | |
download | meta-enea-bsp-arm-3b0e97b92f7e66158b7a5ac9461d0705d04f8b3a.tar.gz |
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 <sona.sarmadi@enea.com>
Signed-off-by: Adrian Dudau <adrian.dudau@enea.com>
-rw-r--r-- | recipes-kernel/linux/linux-cavium/CVE-2017-7645.patch | 109 | ||||
-rw-r--r-- | recipes-kernel/linux/linux-cavium_4.9.inc | 1 |
2 files changed, 110 insertions, 0 deletions
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 @@ | |||
1 | From fc6445df466f37291a70937642068bda78802a5b Mon Sep 17 00:00:00 2001 | ||
2 | From: "J. Bruce Fields" <bfields@redhat.com> | ||
3 | Date: Fri, 21 Apr 2017 16:10:18 -0400 | ||
4 | Subject: [PATCH] nfsd: check for oversized NFSv2/v3 arguments | ||
5 | MIME-Version: 1.0 | ||
6 | Content-Type: text/plain; charset=UTF-8 | ||
7 | Content-Transfer-Encoding: 8bit | ||
8 | |||
9 | commit e6838a29ecb484c97e4efef9429643b9851fba6e upstream. | ||
10 | |||
11 | A client can append random data to the end of an NFSv2 or NFSv3 RPC call | ||
12 | without our complaining; we'll just stop parsing at the end of the | ||
13 | expected data and ignore the rest. | ||
14 | |||
15 | Encoded arguments and replies are stored together in an array of pages, | ||
16 | and if a call is too large it could leave inadequate space for the | ||
17 | reply. This is normally OK because NFS RPC's typically have either | ||
18 | short arguments and long replies (like READ) or long arguments and short | ||
19 | replies (like WRITE). But a client that sends an incorrectly long reply | ||
20 | can violate those assumptions. This was observed to cause crashes. | ||
21 | |||
22 | Also, several operations increment rq_next_page in the decode routine | ||
23 | before checking the argument size, which can leave rq_next_page pointing | ||
24 | well past the end of the page array, causing trouble later in | ||
25 | svc_free_pages. | ||
26 | |||
27 | So, following a suggestion from Neil Brown, add a central check to | ||
28 | enforce our expectation that no NFSv2/v3 call has both a large call and | ||
29 | a large reply. | ||
30 | |||
31 | As followup we may also want to rewrite the encoding routines to check | ||
32 | more carefully that they aren't running off the end of the page array. | ||
33 | |||
34 | We may also consider rejecting calls that have any extra garbage | ||
35 | appended. That would be safer, and within our rights by spec, but given | ||
36 | the age of our server and the NFS protocol, and the fact that we've | ||
37 | never enforced this before, we may need to balance that against the | ||
38 | possibility of breaking some oddball client. | ||
39 | |||
40 | CVE: CVE-2017-7645 | ||
41 | 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] | ||
42 | |||
43 | Reported-by: Tuomas Haanpää <thaan@synopsys.com> | ||
44 | Reported-by: Ari Kauppi <ari@synopsys.com> | ||
45 | Reviewed-by: NeilBrown <neilb@suse.com> | ||
46 | Signed-off-by: J. Bruce Fields <bfields@redhat.com> | ||
47 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||
48 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
49 | --- | ||
50 | fs/nfsd/nfssvc.c | 36 ++++++++++++++++++++++++++++++++++++ | ||
51 | 1 file changed, 36 insertions(+) | ||
52 | |||
53 | diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c | ||
54 | index a2b65fc..1645b97 100644 | ||
55 | --- a/fs/nfsd/nfssvc.c | ||
56 | +++ b/fs/nfsd/nfssvc.c | ||
57 | @@ -733,6 +733,37 @@ static __be32 map_new_errors(u32 vers, __be32 nfserr) | ||
58 | return nfserr; | ||
59 | } | ||
60 | |||
61 | +/* | ||
62 | + * A write procedure can have a large argument, and a read procedure can | ||
63 | + * have a large reply, but no NFSv2 or NFSv3 procedure has argument and | ||
64 | + * reply that can both be larger than a page. The xdr code has taken | ||
65 | + * advantage of this assumption to be a sloppy about bounds checking in | ||
66 | + * some cases. Pending a rewrite of the NFSv2/v3 xdr code to fix that | ||
67 | + * problem, we enforce these assumptions here: | ||
68 | + */ | ||
69 | +static bool nfs_request_too_big(struct svc_rqst *rqstp, | ||
70 | + struct svc_procedure *proc) | ||
71 | +{ | ||
72 | + /* | ||
73 | + * The ACL code has more careful bounds-checking and is not | ||
74 | + * susceptible to this problem: | ||
75 | + */ | ||
76 | + if (rqstp->rq_prog != NFS_PROGRAM) | ||
77 | + return false; | ||
78 | + /* | ||
79 | + * Ditto NFSv4 (which can in theory have argument and reply both | ||
80 | + * more than a page): | ||
81 | + */ | ||
82 | + if (rqstp->rq_vers >= 4) | ||
83 | + return false; | ||
84 | + /* The reply will be small, we're OK: */ | ||
85 | + if (proc->pc_xdrressize > 0 && | ||
86 | + proc->pc_xdrressize < XDR_QUADLEN(PAGE_SIZE)) | ||
87 | + return false; | ||
88 | + | ||
89 | + return rqstp->rq_arg.len > PAGE_SIZE; | ||
90 | +} | ||
91 | + | ||
92 | int | ||
93 | nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) | ||
94 | { | ||
95 | @@ -745,6 +776,11 @@ static __be32 map_new_errors(u32 vers, __be32 nfserr) | ||
96 | rqstp->rq_vers, rqstp->rq_proc); | ||
97 | proc = rqstp->rq_procinfo; | ||
98 | |||
99 | + if (nfs_request_too_big(rqstp, proc)) { | ||
100 | + dprintk("nfsd: NFSv%d argument too large\n", rqstp->rq_vers); | ||
101 | + *statp = rpc_garbage_args; | ||
102 | + return 1; | ||
103 | + } | ||
104 | /* | ||
105 | * Give the xdr decoder a chance to change this if it wants | ||
106 | * (necessary in the NFSv4.0 compound case) | ||
107 | -- | ||
108 | 1.9.1 | ||
109 | |||
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 | |||
24 | file://CVE-2017-8068.patch \ | 24 | file://CVE-2017-8068.patch \ |
25 | file://CVE-2017-8069.patch \ | 25 | file://CVE-2017-8069.patch \ |
26 | file://CVE-2017-7618.patch \ | 26 | file://CVE-2017-7618.patch \ |
27 | file://CVE-2017-7645.patch \ | ||
27 | " | 28 | " |
28 | 29 | ||
29 | LINUX_KERNEL_TYPE = "tiny" | 30 | LINUX_KERNEL_TYPE = "tiny" |