aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-06-26 14:10:04 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-07-22 15:57:54 -0400
commit41f9d29f09ca0b22c3631e8a39676e74cda9bcc0 (patch)
tree7ab5ed25f14466471fb55536e1cf71c514fb7fe9 /security/keys
parent7266702805f9d824f92ce5c4069eca65d0f21d28 (diff)
trimming task_work: kill ->data
get rid of the only user of ->data; this is _not_ the final variant - in the end we'll have task_work and rcu_head identical and just use cred->rcu, at which point the separate allocation will be gone completely. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'security/keys')
-rw-r--r--security/keys/internal.h4
-rw-r--r--security/keys/keyctl.c14
-rw-r--r--security/keys/process_keys.c5
3 files changed, 15 insertions, 8 deletions
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 3dcbf86b0d31..b510a316874a 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -148,6 +148,10 @@ extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags,
148#define KEY_LOOKUP_PARTIAL 0x02 148#define KEY_LOOKUP_PARTIAL 0x02
149#define KEY_LOOKUP_FOR_UNLINK 0x04 149#define KEY_LOOKUP_FOR_UNLINK 0x04
150 150
151struct kludge { /* this will die off very soon */
152 struct task_work twork;
153 struct cred *cred;
154};
151extern long join_session_keyring(const char *name); 155extern long join_session_keyring(const char *name);
152extern void key_change_session_keyring(struct task_work *twork); 156extern void key_change_session_keyring(struct task_work *twork);
153 157
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 0f5b3f027299..26723caaad05 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -1456,7 +1456,8 @@ 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 task_work *newwork, *oldwork; 1459 struct kludge *newwork;
1460 struct task_work *oldwork;
1460 key_ref_t keyring_r; 1461 key_ref_t keyring_r;
1461 struct cred *cred; 1462 struct cred *cred;
1462 int ret; 1463 int ret;
@@ -1466,7 +1467,7 @@ long keyctl_session_to_parent(void)
1466 return PTR_ERR(keyring_r); 1467 return PTR_ERR(keyring_r);
1467 1468
1468 ret = -ENOMEM; 1469 ret = -ENOMEM;
1469 newwork = kmalloc(sizeof(struct task_work), GFP_KERNEL); 1470 newwork = kmalloc(sizeof(struct kludge), GFP_KERNEL);
1470 if (!newwork) 1471 if (!newwork)
1471 goto error_keyring; 1472 goto error_keyring;
1472 1473
@@ -1478,7 +1479,8 @@ long keyctl_session_to_parent(void)
1478 goto error_newwork; 1479 goto error_newwork;
1479 1480
1480 cred->tgcred->session_keyring = key_ref_to_ptr(keyring_r); 1481 cred->tgcred->session_keyring = key_ref_to_ptr(keyring_r);
1481 init_task_work(newwork, key_change_session_keyring, cred); 1482 init_task_work(&newwork->twork, key_change_session_keyring);
1483 newwork->cred = cred;
1482 1484
1483 me = current; 1485 me = current;
1484 rcu_read_lock(); 1486 rcu_read_lock();
@@ -1527,18 +1529,18 @@ long keyctl_session_to_parent(void)
1527 1529
1528 /* the replacement session keyring is applied just prior to userspace 1530 /* the replacement session keyring is applied just prior to userspace
1529 * restarting */ 1531 * restarting */
1530 ret = task_work_add(parent, newwork, true); 1532 ret = task_work_add(parent, &newwork->twork, true);
1531 if (!ret) 1533 if (!ret)
1532 newwork = NULL; 1534 newwork = NULL;
1533unlock: 1535unlock:
1534 write_unlock_irq(&tasklist_lock); 1536 write_unlock_irq(&tasklist_lock);
1535 rcu_read_unlock(); 1537 rcu_read_unlock();
1536 if (oldwork) { 1538 if (oldwork) {
1537 put_cred(oldwork->data); 1539 put_cred(container_of(oldwork, struct kludge, twork)->cred);
1538 kfree(oldwork); 1540 kfree(oldwork);
1539 } 1541 }
1540 if (newwork) { 1542 if (newwork) {
1541 put_cred(newwork->data); 1543 put_cred(newwork->cred);
1542 kfree(newwork); 1544 kfree(newwork);
1543 } 1545 }
1544 return ret; 1546 return ret;
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 4ad54eea1ea4..c9b07c97d7f2 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -837,9 +837,10 @@ error:
837void key_change_session_keyring(struct task_work *twork) 837void key_change_session_keyring(struct task_work *twork)
838{ 838{
839 const struct cred *old = current_cred(); 839 const struct cred *old = current_cred();
840 struct cred *new = twork->data; 840 struct kludge *p = container_of(twork, struct kludge, twork);
841 struct cred *new = p->cred;
841 842
842 kfree(twork); 843 kfree(p);
843 if (unlikely(current->flags & PF_EXITING)) { 844 if (unlikely(current->flags & PF_EXITING)) {
844 put_cred(new); 845 put_cred(new);
845 return; 846 return;