aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/auth_gss/auth_gss.c
diff options
context:
space:
mode:
authorReshetova, Elena <elena.reshetova@intel.com>2017-07-04 08:53:14 -0400
committerDavid S. Miller <davem@davemloft.net>2017-07-04 17:35:17 -0400
commit7ff139696d74d0d4917bd259347d00e3a4fcc410 (patch)
tree99defe75514e2bf358c299ca21ad39ccff97ca78 /net/sunrpc/auth_gss/auth_gss.c
parent0fa104726b6cc7b1ebb4c60d55cb6abda745f4b6 (diff)
net, sunrpc: convert gss_upcall_msg.count from atomic_t to refcount_t
refcount_t type and corresponding API should be used instead of atomic_t when the variable is used as a reference counter. This allows to avoid accidental refcounter overflows that might lead to use-after-free situations. Signed-off-by: Elena Reshetova <elena.reshetova@intel.com> Signed-off-by: Hans Liljestrand <ishkamiel@gmail.com> Signed-off-by: Kees Cook <keescook@chromium.org> Signed-off-by: David Windsor <dwindsor@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sunrpc/auth_gss/auth_gss.c')
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c22
1 files changed, 11 insertions, 11 deletions
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 72f129c74acd..9463af4b32e8 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -287,7 +287,7 @@ err:
287#define UPCALL_BUF_LEN 128 287#define UPCALL_BUF_LEN 128
288 288
289struct gss_upcall_msg { 289struct gss_upcall_msg {
290 atomic_t count; 290 refcount_t count;
291 kuid_t uid; 291 kuid_t uid;
292 struct rpc_pipe_msg msg; 292 struct rpc_pipe_msg msg;
293 struct list_head list; 293 struct list_head list;
@@ -328,7 +328,7 @@ static void
328gss_release_msg(struct gss_upcall_msg *gss_msg) 328gss_release_msg(struct gss_upcall_msg *gss_msg)
329{ 329{
330 struct net *net = gss_msg->auth->net; 330 struct net *net = gss_msg->auth->net;
331 if (!atomic_dec_and_test(&gss_msg->count)) 331 if (!refcount_dec_and_test(&gss_msg->count))
332 return; 332 return;
333 put_pipe_version(net); 333 put_pipe_version(net);
334 BUG_ON(!list_empty(&gss_msg->list)); 334 BUG_ON(!list_empty(&gss_msg->list));
@@ -348,7 +348,7 @@ __gss_find_upcall(struct rpc_pipe *pipe, kuid_t uid, const struct gss_auth *auth
348 continue; 348 continue;
349 if (auth && pos->auth->service != auth->service) 349 if (auth && pos->auth->service != auth->service)
350 continue; 350 continue;
351 atomic_inc(&pos->count); 351 refcount_inc(&pos->count);
352 dprintk("RPC: %s found msg %p\n", __func__, pos); 352 dprintk("RPC: %s found msg %p\n", __func__, pos);
353 return pos; 353 return pos;
354 } 354 }
@@ -369,7 +369,7 @@ gss_add_msg(struct gss_upcall_msg *gss_msg)
369 spin_lock(&pipe->lock); 369 spin_lock(&pipe->lock);
370 old = __gss_find_upcall(pipe, gss_msg->uid, gss_msg->auth); 370 old = __gss_find_upcall(pipe, gss_msg->uid, gss_msg->auth);
371 if (old == NULL) { 371 if (old == NULL) {
372 atomic_inc(&gss_msg->count); 372 refcount_inc(&gss_msg->count);
373 list_add(&gss_msg->list, &pipe->in_downcall); 373 list_add(&gss_msg->list, &pipe->in_downcall);
374 } else 374 } else
375 gss_msg = old; 375 gss_msg = old;
@@ -383,7 +383,7 @@ __gss_unhash_msg(struct gss_upcall_msg *gss_msg)
383 list_del_init(&gss_msg->list); 383 list_del_init(&gss_msg->list);
384 rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno); 384 rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno);
385 wake_up_all(&gss_msg->waitqueue); 385 wake_up_all(&gss_msg->waitqueue);
386 atomic_dec(&gss_msg->count); 386 refcount_dec(&gss_msg->count);
387} 387}
388 388
389static void 389static void
@@ -506,7 +506,7 @@ gss_alloc_msg(struct gss_auth *gss_auth,
506 INIT_LIST_HEAD(&gss_msg->list); 506 INIT_LIST_HEAD(&gss_msg->list);
507 rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq"); 507 rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq");
508 init_waitqueue_head(&gss_msg->waitqueue); 508 init_waitqueue_head(&gss_msg->waitqueue);
509 atomic_set(&gss_msg->count, 1); 509 refcount_set(&gss_msg->count, 1);
510 gss_msg->uid = uid; 510 gss_msg->uid = uid;
511 gss_msg->auth = gss_auth; 511 gss_msg->auth = gss_auth;
512 switch (vers) { 512 switch (vers) {
@@ -542,11 +542,11 @@ gss_setup_upcall(struct gss_auth *gss_auth, struct rpc_cred *cred)
542 gss_msg = gss_add_msg(gss_new); 542 gss_msg = gss_add_msg(gss_new);
543 if (gss_msg == gss_new) { 543 if (gss_msg == gss_new) {
544 int res; 544 int res;
545 atomic_inc(&gss_msg->count); 545 refcount_inc(&gss_msg->count);
546 res = rpc_queue_upcall(gss_new->pipe, &gss_new->msg); 546 res = rpc_queue_upcall(gss_new->pipe, &gss_new->msg);
547 if (res) { 547 if (res) {
548 gss_unhash_msg(gss_new); 548 gss_unhash_msg(gss_new);
549 atomic_dec(&gss_msg->count); 549 refcount_dec(&gss_msg->count);
550 gss_release_msg(gss_new); 550 gss_release_msg(gss_new);
551 gss_msg = ERR_PTR(res); 551 gss_msg = ERR_PTR(res);
552 } 552 }
@@ -595,7 +595,7 @@ gss_refresh_upcall(struct rpc_task *task)
595 task->tk_timeout = 0; 595 task->tk_timeout = 0;
596 gss_cred->gc_upcall = gss_msg; 596 gss_cred->gc_upcall = gss_msg;
597 /* gss_upcall_callback will release the reference to gss_upcall_msg */ 597 /* gss_upcall_callback will release the reference to gss_upcall_msg */
598 atomic_inc(&gss_msg->count); 598 refcount_inc(&gss_msg->count);
599 rpc_sleep_on(&gss_msg->rpc_waitqueue, task, gss_upcall_callback); 599 rpc_sleep_on(&gss_msg->rpc_waitqueue, task, gss_upcall_callback);
600 } else { 600 } else {
601 gss_handle_downcall_result(gss_cred, gss_msg); 601 gss_handle_downcall_result(gss_cred, gss_msg);
@@ -815,7 +815,7 @@ restart:
815 if (!list_empty(&gss_msg->msg.list)) 815 if (!list_empty(&gss_msg->msg.list))
816 continue; 816 continue;
817 gss_msg->msg.errno = -EPIPE; 817 gss_msg->msg.errno = -EPIPE;
818 atomic_inc(&gss_msg->count); 818 refcount_inc(&gss_msg->count);
819 __gss_unhash_msg(gss_msg); 819 __gss_unhash_msg(gss_msg);
820 spin_unlock(&pipe->lock); 820 spin_unlock(&pipe->lock);
821 gss_release_msg(gss_msg); 821 gss_release_msg(gss_msg);
@@ -834,7 +834,7 @@ gss_pipe_destroy_msg(struct rpc_pipe_msg *msg)
834 if (msg->errno < 0) { 834 if (msg->errno < 0) {
835 dprintk("RPC: %s releasing msg %p\n", 835 dprintk("RPC: %s releasing msg %p\n",
836 __func__, gss_msg); 836 __func__, gss_msg);
837 atomic_inc(&gss_msg->count); 837 refcount_inc(&gss_msg->count);
838 gss_unhash_msg(gss_msg); 838 gss_unhash_msg(gss_msg);
839 if (msg->errno == -ETIMEDOUT) 839 if (msg->errno == -ETIMEDOUT)
840 warn_gssd(); 840 warn_gssd();