diff options
Diffstat (limited to 'kernels/linux-libre-grsec/0001-SUNRPC-Ensure-that-gss_auth-isn-t-freed-before-its-u.patch')
-rw-r--r-- | kernels/linux-libre-grsec/0001-SUNRPC-Ensure-that-gss_auth-isn-t-freed-before-its-u.patch | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/kernels/linux-libre-grsec/0001-SUNRPC-Ensure-that-gss_auth-isn-t-freed-before-its-u.patch b/kernels/linux-libre-grsec/0001-SUNRPC-Ensure-that-gss_auth-isn-t-freed-before-its-u.patch new file mode 100644 index 000000000..93803d2e6 --- /dev/null +++ b/kernels/linux-libre-grsec/0001-SUNRPC-Ensure-that-gss_auth-isn-t-freed-before-its-u.patch @@ -0,0 +1,82 @@ +From 2bd7c7b5f011b3d57e4f5625b561a6f3f2f34a81 Mon Sep 17 00:00:00 2001 +From: Trond Myklebust <trond.myklebust@primarydata.com> +Date: Sun, 16 Feb 2014 12:14:13 -0500 +Subject: [PATCH] SUNRPC: Ensure that gss_auth isn't freed before its upcall + messages + +Fix a race in which the RPC client is shutting down while the +gss daemon is processing a downcall. If the RPC client manages to +shut down before the gss daemon is done, then the struct gss_auth +used in gss_release_msg() may have already been freed. + +Link: http://lkml.kernel.org/r/1392494917.71728.YahooMailNeo@web140002.mail.bf1.yahoo.com +Reported-by: John <da_audiophile@yahoo.com> +Reported-by: Borislav Petkov <bp@alien8.de> +Cc: stable@vger.kernel.org # 3.12+ +Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> +--- + net/sunrpc/auth_gss/auth_gss.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c +index 42fdfc6..a642fd616 100644 +--- a/net/sunrpc/auth_gss/auth_gss.c ++++ b/net/sunrpc/auth_gss/auth_gss.c +@@ -108,6 +108,7 @@ struct gss_auth { + static DEFINE_SPINLOCK(pipe_version_lock); + static struct rpc_wait_queue pipe_version_rpc_waitqueue; + static DECLARE_WAIT_QUEUE_HEAD(pipe_version_waitqueue); ++static void gss_put_auth(struct gss_auth *gss_auth); + + static void gss_free_ctx(struct gss_cl_ctx *); + static const struct rpc_pipe_ops gss_upcall_ops_v0; +@@ -320,6 +321,7 @@ gss_release_msg(struct gss_upcall_msg *gss_msg) + if (gss_msg->ctx != NULL) + gss_put_ctx(gss_msg->ctx); + rpc_destroy_wait_queue(&gss_msg->rpc_waitqueue); ++ gss_put_auth(gss_msg->auth); + kfree(gss_msg); + } + +@@ -500,6 +502,7 @@ gss_alloc_msg(struct gss_auth *gss_auth, + if (err) + goto err_free_msg; + }; ++ kref_get(&gss_auth->kref); + return gss_msg; + err_free_msg: + kfree(gss_msg); +@@ -1071,6 +1074,12 @@ gss_free_callback(struct kref *kref) + } + + static void ++gss_put_auth(struct gss_auth *gss_auth) ++{ ++ kref_put(&gss_auth->kref, gss_free_callback); ++} ++ ++static void + gss_destroy(struct rpc_auth *auth) + { + struct gss_auth *gss_auth = container_of(auth, +@@ -1091,7 +1100,7 @@ gss_destroy(struct rpc_auth *auth) + gss_auth->gss_pipe[1] = NULL; + rpcauth_destroy_credcache(auth); + +- kref_put(&gss_auth->kref, gss_free_callback); ++ gss_put_auth(gss_auth); + } + + /* +@@ -1262,7 +1271,7 @@ gss_destroy_nullcred(struct rpc_cred *cred) + call_rcu(&cred->cr_rcu, gss_free_cred_callback); + if (ctx) + gss_put_ctx(ctx); +- kref_put(&gss_auth->kref, gss_free_callback); ++ gss_put_auth(gss_auth); + } + + static void +-- +1.9.0 + |