From: Greg Kroah-Hartman Date: Thu, 21 Mar 2019 08:49:45 +0000 (+0100) Subject: 3.18-stable patches X-Git-Tag: v3.18.137~27 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b24fffd467f83a59c6c9c78204b7e192d35fed7c;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches added patches: nfsd-fix-memory-corruption-caused-by-readdir.patch nfsd-fix-wrong-check-in-write_v4_end_grace.patch --- diff --git a/queue-3.18/nfsd-fix-memory-corruption-caused-by-readdir.patch b/queue-3.18/nfsd-fix-memory-corruption-caused-by-readdir.patch new file mode 100644 index 00000000000..001d8772d24 --- /dev/null +++ b/queue-3.18/nfsd-fix-memory-corruption-caused-by-readdir.patch @@ -0,0 +1,98 @@ +From b602345da6cbb135ba68cf042df8ec9a73da7981 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Mon, 4 Mar 2019 14:08:22 +1100 +Subject: nfsd: fix memory corruption caused by readdir + +From: NeilBrown + +commit b602345da6cbb135ba68cf042df8ec9a73da7981 upstream. + +If the result of an NFSv3 readdir{,plus} request results in the +"offset" on one entry having to be split across 2 pages, and is sized +so that the next directory entry doesn't fit in the requested size, +then memory corruption can happen. + +When encode_entry() is called after encoding the last entry that fits, +it notices that ->offset and ->offset1 are set, and so stores the +offset value in the two pages as required. It clears ->offset1 but +*does not* clear ->offset. + +Normally this omission doesn't matter as encode_entry_baggage() will +be called, and will set ->offset to a suitable value (not on a page +boundary). +But in the case where cd->buflen < elen and nfserr_toosmall is +returned, ->offset is not reset. + +This means that nfsd3proc_readdirplus will see ->offset with a value 4 +bytes before the end of a page, and ->offset1 set to NULL. +It will try to write 8bytes to ->offset. +If we are lucky, the next page will be read-only, and the system will + BUG: unable to handle kernel paging request at... + +If we are unlucky, some innocent page will have the first 4 bytes +corrupted. + +nfsd3proc_readdir() doesn't even check for ->offset1, it just blindly +writes 8 bytes to the offset wherever it is. + +Fix this by clearing ->offset after it is used, and copying the +->offset handling code from nfsd3_proc_readdirplus into +nfsd3_proc_readdir. + +(Note that the commit hash in the Fixes tag is from the 'history' + tree - this bug predates git). + +Fixes: 0b1d57cf7654 ("[PATCH] kNFSd: Fix nfs3 dentry encoding") +Fixes-URL: https://git.kernel.org/pub/scm/linux/kernel/git/history/history.git/commit/?id=0b1d57cf7654 +Cc: stable@vger.kernel.org (v2.6.12+) +Signed-off-by: NeilBrown +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfsd/nfs3proc.c | 16 ++++++++++++++-- + fs/nfsd/nfs3xdr.c | 1 + + 2 files changed, 15 insertions(+), 2 deletions(-) + +--- a/fs/nfsd/nfs3proc.c ++++ b/fs/nfsd/nfs3proc.c +@@ -430,8 +430,19 @@ nfsd3_proc_readdir(struct svc_rqst *rqst + &resp->common, nfs3svc_encode_entry); + memcpy(resp->verf, argp->verf, 8); + resp->count = resp->buffer - argp->buffer; +- if (resp->offset) +- xdr_encode_hyper(resp->offset, argp->cookie); ++ if (resp->offset) { ++ loff_t offset = argp->cookie; ++ ++ if (unlikely(resp->offset1)) { ++ /* we ended up with offset on a page boundary */ ++ *resp->offset = htonl(offset >> 32); ++ *resp->offset1 = htonl(offset & 0xffffffff); ++ resp->offset1 = NULL; ++ } else { ++ xdr_encode_hyper(resp->offset, offset); ++ } ++ resp->offset = NULL; ++ } + + RETURN_STATUS(nfserr); + } +@@ -499,6 +510,7 @@ nfsd3_proc_readdirplus(struct svc_rqst * + } else { + xdr_encode_hyper(resp->offset, offset); + } ++ resp->offset = NULL; + } + + RETURN_STATUS(nfserr); +--- a/fs/nfsd/nfs3xdr.c ++++ b/fs/nfsd/nfs3xdr.c +@@ -892,6 +892,7 @@ encode_entry(struct readdir_cd *ccd, con + } else { + xdr_encode_hyper(cd->offset, offset64); + } ++ cd->offset = NULL; + } + + /* diff --git a/queue-3.18/nfsd-fix-wrong-check-in-write_v4_end_grace.patch b/queue-3.18/nfsd-fix-wrong-check-in-write_v4_end_grace.patch new file mode 100644 index 00000000000..445debe55d9 --- /dev/null +++ b/queue-3.18/nfsd-fix-wrong-check-in-write_v4_end_grace.patch @@ -0,0 +1,35 @@ +From dd838821f0a29781b185cd8fb8e48d5c177bd838 Mon Sep 17 00:00:00 2001 +From: Yihao Wu +Date: Wed, 6 Mar 2019 21:03:50 +0800 +Subject: nfsd: fix wrong check in write_v4_end_grace() + +From: Yihao Wu + +commit dd838821f0a29781b185cd8fb8e48d5c177bd838 upstream. + +Commit 62a063b8e7d1 "nfsd4: fix crash on writing v4_end_grace before +nfsd startup" is trying to fix a NULL dereference issue, but it +mistakenly checks if the nfsd server is started. So fix it. + +Fixes: 62a063b8e7d1 "nfsd4: fix crash on writing v4_end_grace before nfsd startup" +Cc: stable@vger.kernel.org +Reviewed-by: Joseph Qi +Signed-off-by: Yihao Wu +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfsd/nfsctl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/nfsd/nfsctl.c ++++ b/fs/nfsd/nfsctl.c +@@ -1110,7 +1110,7 @@ static ssize_t write_v4_end_grace(struct + case 'Y': + case 'y': + case '1': +- if (nn->nfsd_serv) ++ if (!nn->nfsd_serv) + return -EBUSY; + nfsd4_end_grace(nn); + break; diff --git a/queue-3.18/series b/queue-3.18/series index e47fd2aaadf..115f0846513 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -128,3 +128,5 @@ powerpc-wii-properly-disable-use-of-bats-when-requested.patch powerpc-powernv-make-opal-log-only-readable-by-root.patch powerpc-83xx-also-save-restore-sprg4-7-during-suspend.patch arm-s3c24xx-fix-boolean-expressions-in-osiris_dvs_notify.patch +nfsd-fix-memory-corruption-caused-by-readdir.patch +nfsd-fix-wrong-check-in-write_v4_end_grace.patch