keyctl.c (41f9d29f09ca0b22c3631e8a39676e74cda9bcc0) keyctl.c (67d1214551e800f9fe7dc7c47a346d2df0fafed5)
1/* Userspace key control operations
2 *
3 * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version

--- 1442 unchanged lines hidden (view full) ---

1451 * The keyring will be emplaced on the parent when it next resumes userspace.
1452 *
1453 * If successful, 0 will be returned.
1454 */
1455long keyctl_session_to_parent(void)
1456{
1457 struct task_struct *me, *parent;
1458 const struct cred *mycred, *pcred;
1/* Userspace key control operations
2 *
3 * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version

--- 1442 unchanged lines hidden (view full) ---

1451 * The keyring will be emplaced on the parent when it next resumes userspace.
1452 *
1453 * If successful, 0 will be returned.
1454 */
1455long keyctl_session_to_parent(void)
1456{
1457 struct task_struct *me, *parent;
1458 const struct cred *mycred, *pcred;
1459 struct kludge *newwork;
1460 struct task_work *oldwork;
1459 struct callback_head *newwork, *oldwork;
1461 key_ref_t keyring_r;
1462 struct cred *cred;
1463 int ret;
1464
1465 keyring_r = lookup_user_key(KEY_SPEC_SESSION_KEYRING, 0, KEY_LINK);
1466 if (IS_ERR(keyring_r))
1467 return PTR_ERR(keyring_r);
1468
1469 ret = -ENOMEM;
1460 key_ref_t keyring_r;
1461 struct cred *cred;
1462 int ret;
1463
1464 keyring_r = lookup_user_key(KEY_SPEC_SESSION_KEYRING, 0, KEY_LINK);
1465 if (IS_ERR(keyring_r))
1466 return PTR_ERR(keyring_r);
1467
1468 ret = -ENOMEM;
1470 newwork = kmalloc(sizeof(struct kludge), GFP_KERNEL);
1471 if (!newwork)
1472 goto error_keyring;
1473
1474 /* 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
1476 * our parent */
1477 cred = cred_alloc_blank();
1478 if (!cred)
1469
1470 /* our parent is going to need a new cred struct, a new tgcred struct
1471 * and new security data, so we allocate them here to prevent ENOMEM in
1472 * our parent */
1473 cred = cred_alloc_blank();
1474 if (!cred)
1479 goto error_newwork;
1475 goto error_keyring;
1476 newwork = &cred->rcu;
1480
1481 cred->tgcred->session_keyring = key_ref_to_ptr(keyring_r);
1477
1478 cred->tgcred->session_keyring = key_ref_to_ptr(keyring_r);
1482 init_task_work(&newwork->twork, key_change_session_keyring);
1483 newwork->cred = cred;
1479 init_task_work(newwork, key_change_session_keyring);
1484
1485 me = current;
1486 rcu_read_lock();
1487 write_lock_irq(&tasklist_lock);
1488
1489 ret = -EPERM;
1490 oldwork = NULL;
1491 parent = me->real_parent;

--- 32 unchanged lines hidden (view full) ---

1524 mycred->tgcred->session_keyring->uid != mycred->euid)
1525 goto unlock;
1526
1527 /* cancel an already pending keyring replacement */
1528 oldwork = task_work_cancel(parent, key_change_session_keyring);
1529
1530 /* the replacement session keyring is applied just prior to userspace
1531 * restarting */
1480
1481 me = current;
1482 rcu_read_lock();
1483 write_lock_irq(&tasklist_lock);
1484
1485 ret = -EPERM;
1486 oldwork = NULL;
1487 parent = me->real_parent;

--- 32 unchanged lines hidden (view full) ---

1520 mycred->tgcred->session_keyring->uid != mycred->euid)
1521 goto unlock;
1522
1523 /* cancel an already pending keyring replacement */
1524 oldwork = task_work_cancel(parent, key_change_session_keyring);
1525
1526 /* the replacement session keyring is applied just prior to userspace
1527 * restarting */
1532 ret = task_work_add(parent, &newwork->twork, true);
1528 ret = task_work_add(parent, newwork, true);
1533 if (!ret)
1534 newwork = NULL;
1535unlock:
1536 write_unlock_irq(&tasklist_lock);
1537 rcu_read_unlock();
1529 if (!ret)
1530 newwork = NULL;
1531unlock:
1532 write_unlock_irq(&tasklist_lock);
1533 rcu_read_unlock();
1538 if (oldwork) {
1539 put_cred(container_of(oldwork, struct kludge, twork)->cred);
1540 kfree(oldwork);
1541 }
1542 if (newwork) {
1543 put_cred(newwork->cred);
1544 kfree(newwork);
1545 }
1534 if (oldwork)
1535 put_cred(container_of(oldwork, struct cred, rcu));
1536 if (newwork)
1537 put_cred(cred);
1546 return ret;
1547
1538 return ret;
1539
1548error_newwork:
1549 kfree(newwork);
1550error_keyring:
1551 key_ref_put(keyring_r);
1552 return ret;
1553}
1554
1555/*
1556 * The key control system call
1557 */

--- 104 unchanged lines hidden ---
1540error_keyring:
1541 key_ref_put(keyring_r);
1542 return ret;
1543}
1544
1545/*
1546 * The key control system call
1547 */

--- 104 unchanged lines hidden ---