aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/keyctl.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-06-27 03:07:19 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-07-22 15:57:56 -0400
commit67d1214551e800f9fe7dc7c47a346d2df0fafed5 (patch)
treeffcc93af9390339adda36668255e617073b724a1 /security/keys/keyctl.c
parent158e1645e07f3e9f7e4962d7a0997f5c3b98311b (diff)
merge task_work and rcu_head, get rid of separate allocation for keyring case
task_work and rcu_head are identical now; merge them (calling the result struct callback_head, rcu_head #define'd to it), kill separate allocation in security/keys since we can just use cred->rcu now. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'security/keys/keyctl.c')
-rw-r--r--security/keys/keyctl.c28
1 files changed, 9 insertions, 19 deletions
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 26723caaad05..0291b3f9397c 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -1456,8 +1456,7 @@ long keyctl_session_to_parent(void)
1456{ 1456{
1457 struct task_struct *me, *parent; 1457 struct task_struct *me, *parent;
1458 const struct cred *mycred, *pcred; 1458 const struct cred *mycred, *pcred;
1459 struct kludge *newwork; 1459 struct callback_head *newwork, *oldwork;
1460 struct task_work *oldwork;
1461 key_ref_t keyring_r; 1460 key_ref_t keyring_r;
1462 struct cred *cred; 1461 struct cred *cred;
1463 int ret; 1462 int ret;
@@ -1467,20 +1466,17 @@ long keyctl_session_to_parent(void)
1467 return PTR_ERR(keyring_r); 1466 return PTR_ERR(keyring_r);
1468 1467
1469 ret = -ENOMEM; 1468 ret = -ENOMEM;
1470 newwork = kmalloc(sizeof(struct kludge), GFP_KERNEL);
1471 if (!newwork)
1472 goto error_keyring;
1473 1469
1474 /* our parent is going to need a new cred struct, a new tgcred struct 1470 /* our parent is going to need a new cred struct, a new tgcred struct
1475 * and new security data, so we allocate them here to prevent ENOMEM in 1471 * and new security data, so we allocate them here to prevent ENOMEM in
1476 * our parent */ 1472 * our parent */
1477 cred = cred_alloc_blank(); 1473 cred = cred_alloc_blank();
1478 if (!cred) 1474 if (!cred)
1479 goto error_newwork; 1475 goto error_keyring;
1476 newwork = &cred->rcu;
1480 1477
1481 cred->tgcred->session_keyring = key_ref_to_ptr(keyring_r); 1478 cred->tgcred->session_keyring = key_ref_to_ptr(keyring_r);
1482 init_task_work(&newwork->twork, key_change_session_keyring); 1479 init_task_work(newwork, key_change_session_keyring);
1483 newwork->cred = cred;
1484 1480
1485 me = current; 1481 me = current;
1486 rcu_read_lock(); 1482 rcu_read_lock();
@@ -1529,24 +1525,18 @@ long keyctl_session_to_parent(void)
1529 1525
1530 /* the replacement session keyring is applied just prior to userspace 1526 /* the replacement session keyring is applied just prior to userspace
1531 * restarting */ 1527 * restarting */
1532 ret = task_work_add(parent, &newwork->twork, true); 1528 ret = task_work_add(parent, newwork, true);
1533 if (!ret) 1529 if (!ret)
1534 newwork = NULL; 1530 newwork = NULL;
1535unlock: 1531unlock:
1536 write_unlock_irq(&tasklist_lock); 1532 write_unlock_irq(&tasklist_lock);
1537 rcu_read_unlock(); 1533 rcu_read_unlock();
1538 if (oldwork) { 1534 if (oldwork)
1539 put_cred(container_of(oldwork, struct kludge, twork)->cred); 1535 put_cred(container_of(oldwork, struct cred, rcu));
1540 kfree(oldwork); 1536 if (newwork)
1541 } 1537 put_cred(cred);
1542 if (newwork) {
1543 put_cred(newwork->cred);
1544 kfree(newwork);
1545 }
1546 return ret; 1538 return ret;
1547 1539
1548error_newwork:
1549 kfree(newwork);
1550error_keyring: 1540error_keyring:
1551 key_ref_put(keyring_r); 1541 key_ref_put(keyring_r);
1552 return ret; 1542 return ret;