From: Greg Kroah-Hartman Date: Thu, 2 Oct 2014 23:48:25 +0000 (-0700) Subject: 3.10-stable patches X-Git-Tag: v3.16.4~55 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8323415c876cf1db9d46ce266c4ccf3af4f17650;p=thirdparty%2Fkernel%2Fstable-queue.git 3.10-stable patches added patches: nfsv4-fix-another-bug-in-the-close-open_downgrade-code.patch nfsv4-nfs4_state_manager-vs.-nfs_server_remove_lists.patch --- diff --git a/queue-3.10/nfsv4-fix-another-bug-in-the-close-open_downgrade-code.patch b/queue-3.10/nfsv4-fix-another-bug-in-the-close-open_downgrade-code.patch new file mode 100644 index 00000000000..2a6230ecabd --- /dev/null +++ b/queue-3.10/nfsv4-fix-another-bug-in-the-close-open_downgrade-code.patch @@ -0,0 +1,65 @@ +From cd9288ffaea4359d5cfe2b8d264911506aed26a4 Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Thu, 18 Sep 2014 11:51:32 -0400 +Subject: NFSv4: Fix another bug in the close/open_downgrade code + +From: Trond Myklebust + +commit cd9288ffaea4359d5cfe2b8d264911506aed26a4 upstream. + +James Drew reports another bug whereby the NFS client is now sending +an OPEN_DOWNGRADE in a situation where it should really have sent a +CLOSE: the client is opening the file for O_RDWR, but then trying to +do a downgrade to O_RDONLY, which is not allowed by the NFSv4 spec. + +Reported-by: James Drews +Link: http://lkml.kernel.org/r/541AD7E5.8020409@engr.wisc.edu +Fixes: aee7af356e15 (NFSv4: Fix problems with close in the presence...) +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/nfs4proc.c | 30 +++++++++++++++--------------- + 1 file changed, 15 insertions(+), 15 deletions(-) + +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -2299,23 +2299,23 @@ static void nfs4_close_prepare(struct rp + is_rdwr = test_bit(NFS_O_RDWR_STATE, &state->flags); + is_rdonly = test_bit(NFS_O_RDONLY_STATE, &state->flags); + is_wronly = test_bit(NFS_O_WRONLY_STATE, &state->flags); +- /* Calculate the current open share mode */ +- calldata->arg.fmode = 0; +- if (is_rdonly || is_rdwr) +- calldata->arg.fmode |= FMODE_READ; +- if (is_wronly || is_rdwr) +- calldata->arg.fmode |= FMODE_WRITE; + /* Calculate the change in open mode */ ++ calldata->arg.fmode = 0; + if (state->n_rdwr == 0) { +- if (state->n_rdonly == 0) { +- call_close |= is_rdonly || is_rdwr; +- calldata->arg.fmode &= ~FMODE_READ; +- } +- if (state->n_wronly == 0) { +- call_close |= is_wronly || is_rdwr; +- calldata->arg.fmode &= ~FMODE_WRITE; +- } +- } ++ if (state->n_rdonly == 0) ++ call_close |= is_rdonly; ++ else if (is_rdonly) ++ calldata->arg.fmode |= FMODE_READ; ++ if (state->n_wronly == 0) ++ call_close |= is_wronly; ++ else if (is_wronly) ++ calldata->arg.fmode |= FMODE_WRITE; ++ } else if (is_rdwr) ++ calldata->arg.fmode |= FMODE_READ|FMODE_WRITE; ++ ++ if (calldata->arg.fmode == 0) ++ call_close |= is_rdwr; ++ + if (!nfs4_valid_open_stateid(state)) + call_close = 0; + spin_unlock(&state->owner->so_lock); diff --git a/queue-3.10/nfsv4-nfs4_state_manager-vs.-nfs_server_remove_lists.patch b/queue-3.10/nfsv4-nfs4_state_manager-vs.-nfs_server_remove_lists.patch new file mode 100644 index 00000000000..3421cab0c8b --- /dev/null +++ b/queue-3.10/nfsv4-nfs4_state_manager-vs.-nfs_server_remove_lists.patch @@ -0,0 +1,101 @@ +From 080af20cc945d110f9912d01cf6b66f94a375b8d Mon Sep 17 00:00:00 2001 +From: Steve Dickson +Date: Thu, 18 Sep 2014 09:13:17 -0400 +Subject: NFSv4: nfs4_state_manager() vs. nfs_server_remove_lists() + +From: Steve Dickson + +commit 080af20cc945d110f9912d01cf6b66f94a375b8d upstream. + +There is a race between nfs4_state_manager() and +nfs_server_remove_lists() that happens during a nfsv3 mount. + +The v3 mount notices there is already a supper block so +nfs_server_remove_lists() called which uses the nfs_client_lock +spin lock to synchronize access to the client list. + +At the same time nfs4_state_manager() is running through +the client list looking for work to do, using the same +lock. When nfs4_state_manager() wins the race to the +list, a v3 client pointer is found and not ignored +properly which causes the panic. + +Moving some protocol checks before the state checking +avoids the panic. + +Signed-off-by: Steve Dickson +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/nfs4client.c | 38 ++++++++++++++++++++------------------ + 1 file changed, 20 insertions(+), 18 deletions(-) + +--- a/fs/nfs/nfs4client.c ++++ b/fs/nfs/nfs4client.c +@@ -311,6 +311,16 @@ int nfs40_walk_client_list(struct nfs_cl + + spin_lock(&nn->nfs_client_lock); + list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) { ++ ++ if (pos->rpc_ops != new->rpc_ops) ++ continue; ++ ++ if (pos->cl_proto != new->cl_proto) ++ continue; ++ ++ if (pos->cl_minorversion != new->cl_minorversion) ++ continue; ++ + /* If "pos" isn't marked ready, we can't trust the + * remaining fields in "pos" */ + if (pos->cl_cons_state > NFS_CS_READY) { +@@ -330,15 +340,6 @@ int nfs40_walk_client_list(struct nfs_cl + if (pos->cl_cons_state != NFS_CS_READY) + continue; + +- if (pos->rpc_ops != new->rpc_ops) +- continue; +- +- if (pos->cl_proto != new->cl_proto) +- continue; +- +- if (pos->cl_minorversion != new->cl_minorversion) +- continue; +- + if (pos->cl_clientid != new->cl_clientid) + continue; + +@@ -444,6 +445,16 @@ int nfs41_walk_client_list(struct nfs_cl + + spin_lock(&nn->nfs_client_lock); + list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) { ++ ++ if (pos->rpc_ops != new->rpc_ops) ++ continue; ++ ++ if (pos->cl_proto != new->cl_proto) ++ continue; ++ ++ if (pos->cl_minorversion != new->cl_minorversion) ++ continue; ++ + /* If "pos" isn't marked ready, we can't trust the + * remaining fields in "pos", especially the client + * ID and serverowner fields. Wait for CREATE_SESSION +@@ -469,15 +480,6 @@ int nfs41_walk_client_list(struct nfs_cl + if (pos->cl_cons_state != NFS_CS_READY) + continue; + +- if (pos->rpc_ops != new->rpc_ops) +- continue; +- +- if (pos->cl_proto != new->cl_proto) +- continue; +- +- if (pos->cl_minorversion != new->cl_minorversion) +- continue; +- + if (!nfs4_match_clientids(pos, new)) + continue; + diff --git a/queue-3.10/series b/queue-3.10/series index b53b7c37977..385cfc1f5c0 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -59,3 +59,5 @@ usb-storage-add-quirks-for-entrega-xircom-usb-to-scsi-converters.patch usb-ehci-unlink-qhs-even-after-the-controller-has-stopped.patch usb-dwc3-omap-fix-ordering-for-runtime-pm-calls.patch usb-hub-set-hub-change_bits-when-over-current-happens.patch +nfsv4-nfs4_state_manager-vs.-nfs_server_remove_lists.patch +nfsv4-fix-another-bug-in-the-close-open_downgrade-code.patch