From: Greg Kroah-Hartman Date: Mon, 25 Nov 2013 21:31:46 +0000 (-0800) Subject: 3.4-stable patches X-Git-Tag: v3.11.10~38 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5da21352afdfc2193584bed9d7f7de6eac8cb826;p=thirdparty%2Fkernel%2Fstable-queue.git 3.4-stable patches added patches: sunrpc-don-t-map-ekeyexpired-to-eacces-in-call_refreshresult.patch sunrpc-handle-ekeyexpired-in-call_refreshresult.patch --- diff --git a/queue-3.4/series b/queue-3.4/series index f38b14ff9d3..44529cb7f72 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -11,3 +11,5 @@ crypto-ansi_cprng-fix-off-by-one-error-in-non-block-size-request.patch can-c_can-fix-rx-message-handling-handle-lost-message-before-eob.patch 8139cp-re-enable-interrupts-after-tx-timeout.patch fix-a-few-incorrectly-checked-remap_pfn_range-calls.patch +sunrpc-handle-ekeyexpired-in-call_refreshresult.patch +sunrpc-don-t-map-ekeyexpired-to-eacces-in-call_refreshresult.patch diff --git a/queue-3.4/sunrpc-don-t-map-ekeyexpired-to-eacces-in-call_refreshresult.patch b/queue-3.4/sunrpc-don-t-map-ekeyexpired-to-eacces-in-call_refreshresult.patch new file mode 100644 index 00000000000..2f7ca96e985 --- /dev/null +++ b/queue-3.4/sunrpc-don-t-map-ekeyexpired-to-eacces-in-call_refreshresult.patch @@ -0,0 +1,35 @@ +From f1ff0c27fd9987c59d707cd1a6b6c1fc3ae0a250 Mon Sep 17 00:00:00 2001 +From: Andy Adamson +Date: Wed, 14 Aug 2013 11:59:13 -0400 +Subject: SUNRPC: don't map EKEYEXPIRED to EACCES in call_refreshresult + +From: Andy Adamson + +commit f1ff0c27fd9987c59d707cd1a6b6c1fc3ae0a250 upstream. + +The NFS layer needs to know when a key has expired. +This change also returns -EKEYEXPIRED to the application, and the informative +"Key has expired" error message is displayed. The user then knows that +credential renewal is required. + +Signed-off-by: Andy Adamson +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + net/sunrpc/clnt.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/sunrpc/clnt.c ++++ b/net/sunrpc/clnt.c +@@ -1336,9 +1336,9 @@ call_refreshresult(struct rpc_task *task + return; + case -ETIMEDOUT: + rpc_delay(task, 3*HZ); +- case -EKEYEXPIRED: + case -EAGAIN: + status = -EACCES; ++ case -EKEYEXPIRED: + if (!task->tk_cred_retry) + break; + task->tk_cred_retry--; diff --git a/queue-3.4/sunrpc-handle-ekeyexpired-in-call_refreshresult.patch b/queue-3.4/sunrpc-handle-ekeyexpired-in-call_refreshresult.patch new file mode 100644 index 00000000000..32126d98700 --- /dev/null +++ b/queue-3.4/sunrpc-handle-ekeyexpired-in-call_refreshresult.patch @@ -0,0 +1,266 @@ +From eb96d5c97b0825d542e9c4ba5e0a22b519355166 Mon Sep 17 00:00:00 2001 +From: Andy Adamson +Date: Tue, 27 Nov 2012 10:34:19 -0500 +Subject: SUNRPC handle EKEYEXPIRED in call_refreshresult + +From: Andy Adamson + +commit eb96d5c97b0825d542e9c4ba5e0a22b519355166 upstream. + +Currently, when an RPCSEC_GSS context has expired or is non-existent +and the users (Kerberos) credentials have also expired or are non-existent, +the client receives the -EKEYEXPIRED error and tries to refresh the context +forever. If an application is performing I/O, or other work against the share, +the application hangs, and the user is not prompted to refresh/establish their +credentials. This can result in a denial of service for other users. + +Users are expected to manage their Kerberos credential lifetimes to mitigate +this issue. + +Move the -EKEYEXPIRED handling into the RPC layer. Try tk_cred_retry number +of times to refresh the gss_context, and then return -EACCES to the application. + +Signed-off-by: Andy Adamson +Signed-off-by: Trond Myklebust +[bwh: Backported to 3.2: + - Adjust context + - Drop change to nfs4_handle_reclaim_lease_error()] +Signed-off-by: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/nfs3proc.c | 6 +++--- + fs/nfs/nfs4filelayout.c | 1 - + fs/nfs/nfs4proc.c | 18 ------------------ + fs/nfs/nfs4state.c | 21 --------------------- + fs/nfs/proc.c | 43 ------------------------------------------- + net/sunrpc/clnt.c | 1 + + 6 files changed, 4 insertions(+), 86 deletions(-) + +--- a/fs/nfs/nfs3proc.c ++++ b/fs/nfs/nfs3proc.c +@@ -24,14 +24,14 @@ + + #define NFSDBG_FACILITY NFSDBG_PROC + +-/* A wrapper to handle the EJUKEBOX and EKEYEXPIRED error messages */ ++/* A wrapper to handle the EJUKEBOX error messages */ + static int + nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags) + { + int res; + do { + res = rpc_call_sync(clnt, msg, flags); +- if (res != -EJUKEBOX && res != -EKEYEXPIRED) ++ if (res != -EJUKEBOX) + break; + freezable_schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME); + res = -ERESTARTSYS; +@@ -44,7 +44,7 @@ nfs3_rpc_wrapper(struct rpc_clnt *clnt, + static int + nfs3_async_handle_jukebox(struct rpc_task *task, struct inode *inode) + { +- if (task->tk_status != -EJUKEBOX && task->tk_status != -EKEYEXPIRED) ++ if (task->tk_status != -EJUKEBOX) + return 0; + if (task->tk_status == -EJUKEBOX) + nfs_inc_stats(inode, NFSIOS_DELAY); +--- a/fs/nfs/nfs4filelayout.c ++++ b/fs/nfs/nfs4filelayout.c +@@ -122,7 +122,6 @@ static int filelayout_async_handle_error + break; + case -NFS4ERR_DELAY: + case -NFS4ERR_GRACE: +- case -EKEYEXPIRED: + rpc_delay(task, FILELAYOUT_POLL_RETRY_MAX); + break; + case -NFS4ERR_RETRY_UNCACHED_REP: +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -319,7 +319,6 @@ static int nfs4_handle_exception(struct + } + case -NFS4ERR_GRACE: + case -NFS4ERR_DELAY: +- case -EKEYEXPIRED: + ret = nfs4_delay(server->client, &exception->timeout); + if (ret != 0) + break; +@@ -1352,13 +1351,6 @@ int nfs4_open_delegation_recall(struct n + nfs_inode_find_state_and_recover(state->inode, + stateid); + nfs4_schedule_stateid_recovery(server, state); +- case -EKEYEXPIRED: +- /* +- * User RPCSEC_GSS context has expired. +- * We cannot recover this stateid now, so +- * skip it and allow recovery thread to +- * proceed. +- */ + case -ENOMEM: + err = 0; + goto out; +@@ -3924,7 +3916,6 @@ nfs4_async_handle_error(struct rpc_task + case -NFS4ERR_DELAY: + nfs_inc_server_stats(server, NFSIOS_DELAY); + case -NFS4ERR_GRACE: +- case -EKEYEXPIRED: + rpc_delay(task, NFS4_POLL_RETRY_MAX); + task->tk_status = 0; + return -EAGAIN; +@@ -4871,15 +4862,6 @@ int nfs4_lock_delegation_recall(struct n + nfs4_schedule_stateid_recovery(server, state); + err = 0; + goto out; +- case -EKEYEXPIRED: +- /* +- * User RPCSEC_GSS context has expired. +- * We cannot recover this stateid now, so +- * skip it and allow recovery thread to +- * proceed. +- */ +- err = 0; +- goto out; + case -ENOMEM: + case -NFS4ERR_DENIED: + /* kill_proc(fl->fl_pid, SIGLOST, 1); */ +--- a/fs/nfs/nfs4state.c ++++ b/fs/nfs/nfs4state.c +@@ -1298,14 +1298,6 @@ restart: + /* Mark the file as being 'closed' */ + state->state = 0; + break; +- case -EKEYEXPIRED: +- /* +- * User RPCSEC_GSS context has expired. +- * We cannot recover this stateid now, so +- * skip it and allow recovery thread to +- * proceed. +- */ +- break; + case -NFS4ERR_ADMIN_REVOKED: + case -NFS4ERR_STALE_STATEID: + case -NFS4ERR_BAD_STATEID: +@@ -1458,14 +1450,6 @@ static void nfs4_state_start_reclaim_nog + nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_nograce); + } + +-static void nfs4_warn_keyexpired(const char *s) +-{ +- printk_ratelimited(KERN_WARNING "Error: state manager" +- " encountered RPCSEC_GSS session" +- " expired against NFSv4 server %s.\n", +- s); +-} +- + static int nfs4_recovery_handle_error(struct nfs_client *clp, int error) + { + switch (error) { +@@ -1497,10 +1481,6 @@ static int nfs4_recovery_handle_error(st + set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state); + /* Zero session reset errors */ + break; +- case -EKEYEXPIRED: +- /* Nothing we can do */ +- nfs4_warn_keyexpired(clp->cl_hostname); +- break; + default: + return error; + } +@@ -1745,7 +1725,6 @@ static void nfs4_set_lease_expired(struc + break; + + case -EKEYEXPIRED: +- nfs4_warn_keyexpired(clp->cl_hostname); + case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery + * in nfs4_exchange_id */ + default: +--- a/fs/nfs/proc.c ++++ b/fs/nfs/proc.c +@@ -47,39 +47,6 @@ + #define NFSDBG_FACILITY NFSDBG_PROC + + /* +- * wrapper to handle the -EKEYEXPIRED error message. This should generally +- * only happen if using krb5 auth and a user's TGT expires. NFSv2 doesn't +- * support the NFSERR_JUKEBOX error code, but we handle this situation in the +- * same way that we handle that error with NFSv3. +- */ +-static int +-nfs_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags) +-{ +- int res; +- do { +- res = rpc_call_sync(clnt, msg, flags); +- if (res != -EKEYEXPIRED) +- break; +- freezable_schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME); +- res = -ERESTARTSYS; +- } while (!fatal_signal_pending(current)); +- return res; +-} +- +-#define rpc_call_sync(clnt, msg, flags) nfs_rpc_wrapper(clnt, msg, flags) +- +-static int +-nfs_async_handle_expired_key(struct rpc_task *task) +-{ +- if (task->tk_status != -EKEYEXPIRED) +- return 0; +- task->tk_status = 0; +- rpc_restart_call(task); +- rpc_delay(task, NFS_JUKEBOX_RETRY_TIME); +- return 1; +-} +- +-/* + * Bare-bones access to getattr: this is for nfs_read_super. + */ + static int +@@ -365,8 +332,6 @@ static void nfs_proc_unlink_rpc_prepare( + + static int nfs_proc_unlink_done(struct rpc_task *task, struct inode *dir) + { +- if (nfs_async_handle_expired_key(task)) +- return 0; + nfs_mark_for_revalidate(dir); + return 1; + } +@@ -386,8 +351,6 @@ static int + nfs_proc_rename_done(struct rpc_task *task, struct inode *old_dir, + struct inode *new_dir) + { +- if (nfs_async_handle_expired_key(task)) +- return 0; + nfs_mark_for_revalidate(old_dir); + nfs_mark_for_revalidate(new_dir); + return 1; +@@ -641,9 +604,6 @@ nfs_proc_pathconf(struct nfs_server *ser + + static int nfs_read_done(struct rpc_task *task, struct nfs_read_data *data) + { +- if (nfs_async_handle_expired_key(task)) +- return -EAGAIN; +- + nfs_invalidate_atime(data->inode); + if (task->tk_status >= 0) { + nfs_refresh_inode(data->inode, data->res.fattr); +@@ -668,9 +628,6 @@ static void nfs_proc_read_rpc_prepare(st + + static int nfs_write_done(struct rpc_task *task, struct nfs_write_data *data) + { +- if (nfs_async_handle_expired_key(task)) +- return -EAGAIN; +- + if (task->tk_status >= 0) + nfs_post_op_update_inode_force_wcc(data->inode, data->res.fattr); + return 0; +--- a/net/sunrpc/clnt.c ++++ b/net/sunrpc/clnt.c +@@ -1336,6 +1336,7 @@ call_refreshresult(struct rpc_task *task + return; + case -ETIMEDOUT: + rpc_delay(task, 3*HZ); ++ case -EKEYEXPIRED: + case -EAGAIN: + status = -EACCES; + if (!task->tk_cred_retry)