]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 25 Nov 2013 21:31:46 +0000 (13:31 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 25 Nov 2013 21:31:46 +0000 (13:31 -0800)
added patches:
sunrpc-don-t-map-ekeyexpired-to-eacces-in-call_refreshresult.patch
sunrpc-handle-ekeyexpired-in-call_refreshresult.patch

queue-3.4/series
queue-3.4/sunrpc-don-t-map-ekeyexpired-to-eacces-in-call_refreshresult.patch [new file with mode: 0644]
queue-3.4/sunrpc-handle-ekeyexpired-in-call_refreshresult.patch [new file with mode: 0644]

index f38b14ff9d3b219af22cf2d5a5c1403d7f5c3dd5..44529cb7f720512469c5df2b6847e2db17147a2b 100644 (file)
@@ -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 (file)
index 0000000..2f7ca96
--- /dev/null
@@ -0,0 +1,35 @@
+From f1ff0c27fd9987c59d707cd1a6b6c1fc3ae0a250 Mon Sep 17 00:00:00 2001
+From: Andy Adamson <andros@netapp.com>
+Date: Wed, 14 Aug 2013 11:59:13 -0400
+Subject: SUNRPC: don't map EKEYEXPIRED to EACCES in call_refreshresult
+
+From: Andy Adamson <andros@netapp.com>
+
+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 <andros@netapp.com>
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..32126d9
--- /dev/null
@@ -0,0 +1,266 @@
+From eb96d5c97b0825d542e9c4ba5e0a22b519355166 Mon Sep 17 00:00:00 2001
+From: Andy Adamson <andros@netapp.com>
+Date: Tue, 27 Nov 2012 10:34:19 -0500
+Subject: SUNRPC handle EKEYEXPIRED in call_refreshresult
+
+From: Andy Adamson <andros@netapp.com>
+
+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 <andros@netapp.com>
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+[bwh: Backported to 3.2:
+ - Adjust context
+ - Drop change to nfs4_handle_reclaim_lease_error()]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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)