aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/keyctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/keys/keyctl.c')
-rw-r--r--security/keys/keyctl.c70
1 files changed, 44 insertions, 26 deletions
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 3364fbf46807..5d34b4e827d6 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -46,6 +46,9 @@ static int key_get_type_from_user(char *type,
46 * Extract the description of a new key from userspace and either add it as a 46 * Extract the description of a new key from userspace and either add it as a
47 * new key to the specified keyring or update a matching key in that keyring. 47 * new key to the specified keyring or update a matching key in that keyring.
48 * 48 *
49 * If the description is NULL or an empty string, the key type is asked to
50 * generate one from the payload.
51 *
49 * The keyring must be writable so that we can attach the key to it. 52 * The keyring must be writable so that we can attach the key to it.
50 * 53 *
51 * If successful, the new key's serial number is returned, otherwise an error 54 * If successful, the new key's serial number is returned, otherwise an error
@@ -72,10 +75,17 @@ SYSCALL_DEFINE5(add_key, const char __user *, _type,
72 if (ret < 0) 75 if (ret < 0)
73 goto error; 76 goto error;
74 77
75 description = strndup_user(_description, PAGE_SIZE); 78 description = NULL;
76 if (IS_ERR(description)) { 79 if (_description) {
77 ret = PTR_ERR(description); 80 description = strndup_user(_description, PAGE_SIZE);
78 goto error; 81 if (IS_ERR(description)) {
82 ret = PTR_ERR(description);
83 goto error;
84 }
85 if (!*description) {
86 kfree(description);
87 description = NULL;
88 }
79 } 89 }
80 90
81 /* pull the payload in if one was supplied */ 91 /* pull the payload in if one was supplied */
@@ -569,8 +579,8 @@ okay:
569 ret = snprintf(tmpbuf, PAGE_SIZE - 1, 579 ret = snprintf(tmpbuf, PAGE_SIZE - 1,
570 "%s;%d;%d;%08x;%s", 580 "%s;%d;%d;%08x;%s",
571 key->type->name, 581 key->type->name,
572 key->uid, 582 from_kuid_munged(current_user_ns(), key->uid),
573 key->gid, 583 from_kgid_munged(current_user_ns(), key->gid),
574 key->perm, 584 key->perm,
575 key->description ?: ""); 585 key->description ?: "");
576 586
@@ -766,15 +776,25 @@ error:
766 * 776 *
767 * If successful, 0 will be returned. 777 * If successful, 0 will be returned.
768 */ 778 */
769long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid) 779long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group)
770{ 780{
771 struct key_user *newowner, *zapowner = NULL; 781 struct key_user *newowner, *zapowner = NULL;
772 struct key *key; 782 struct key *key;
773 key_ref_t key_ref; 783 key_ref_t key_ref;
774 long ret; 784 long ret;
785 kuid_t uid;
786 kgid_t gid;
787
788 uid = make_kuid(current_user_ns(), user);
789 gid = make_kgid(current_user_ns(), group);
790 ret = -EINVAL;
791 if ((user != (uid_t) -1) && !uid_valid(uid))
792 goto error;
793 if ((group != (gid_t) -1) && !gid_valid(gid))
794 goto error;
775 795
776 ret = 0; 796 ret = 0;
777 if (uid == (uid_t) -1 && gid == (gid_t) -1) 797 if (user == (uid_t) -1 && group == (gid_t) -1)
778 goto error; 798 goto error;
779 799
780 key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL, 800 key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL,
@@ -792,27 +812,27 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid)
792 812
793 if (!capable(CAP_SYS_ADMIN)) { 813 if (!capable(CAP_SYS_ADMIN)) {
794 /* only the sysadmin can chown a key to some other UID */ 814 /* only the sysadmin can chown a key to some other UID */
795 if (uid != (uid_t) -1 && key->uid != uid) 815 if (user != (uid_t) -1 && !uid_eq(key->uid, uid))
796 goto error_put; 816 goto error_put;
797 817
798 /* only the sysadmin can set the key's GID to a group other 818 /* only the sysadmin can set the key's GID to a group other
799 * than one of those that the current process subscribes to */ 819 * than one of those that the current process subscribes to */
800 if (gid != (gid_t) -1 && gid != key->gid && !in_group_p(gid)) 820 if (group != (gid_t) -1 && !gid_eq(gid, key->gid) && !in_group_p(gid))
801 goto error_put; 821 goto error_put;
802 } 822 }
803 823
804 /* change the UID */ 824 /* change the UID */
805 if (uid != (uid_t) -1 && uid != key->uid) { 825 if (user != (uid_t) -1 && !uid_eq(uid, key->uid)) {
806 ret = -ENOMEM; 826 ret = -ENOMEM;
807 newowner = key_user_lookup(uid, current_user_ns()); 827 newowner = key_user_lookup(uid);
808 if (!newowner) 828 if (!newowner)
809 goto error_put; 829 goto error_put;
810 830
811 /* transfer the quota burden to the new user */ 831 /* transfer the quota burden to the new user */
812 if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) { 832 if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
813 unsigned maxkeys = (uid == 0) ? 833 unsigned maxkeys = uid_eq(uid, GLOBAL_ROOT_UID) ?
814 key_quota_root_maxkeys : key_quota_maxkeys; 834 key_quota_root_maxkeys : key_quota_maxkeys;
815 unsigned maxbytes = (uid == 0) ? 835 unsigned maxbytes = uid_eq(uid, GLOBAL_ROOT_UID) ?
816 key_quota_root_maxbytes : key_quota_maxbytes; 836 key_quota_root_maxbytes : key_quota_maxbytes;
817 837
818 spin_lock(&newowner->lock); 838 spin_lock(&newowner->lock);
@@ -846,7 +866,7 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid)
846 } 866 }
847 867
848 /* change the GID */ 868 /* change the GID */
849 if (gid != (gid_t) -1) 869 if (group != (gid_t) -1)
850 key->gid = gid; 870 key->gid = gid;
851 871
852 ret = 0; 872 ret = 0;
@@ -897,7 +917,7 @@ long keyctl_setperm_key(key_serial_t id, key_perm_t perm)
897 down_write(&key->sem); 917 down_write(&key->sem);
898 918
899 /* if we're not the sysadmin, we can only change a key that we own */ 919 /* if we're not the sysadmin, we can only change a key that we own */
900 if (capable(CAP_SYS_ADMIN) || key->uid == current_fsuid()) { 920 if (capable(CAP_SYS_ADMIN) || uid_eq(key->uid, current_fsuid())) {
901 key->perm = perm; 921 key->perm = perm;
902 ret = 0; 922 ret = 0;
903 } 923 }
@@ -1486,7 +1506,6 @@ long keyctl_session_to_parent(void)
1486 oldwork = NULL; 1506 oldwork = NULL;
1487 parent = me->real_parent; 1507 parent = me->real_parent;
1488 1508
1489 task_lock(parent);
1490 /* the parent mustn't be init and mustn't be a kernel thread */ 1509 /* the parent mustn't be init and mustn't be a kernel thread */
1491 if (parent->pid <= 1 || !parent->mm) 1510 if (parent->pid <= 1 || !parent->mm)
1492 goto unlock; 1511 goto unlock;
@@ -1507,18 +1526,18 @@ long keyctl_session_to_parent(void)
1507 1526
1508 /* the parent must have the same effective ownership and mustn't be 1527 /* the parent must have the same effective ownership and mustn't be
1509 * SUID/SGID */ 1528 * SUID/SGID */
1510 if (pcred->uid != mycred->euid || 1529 if (!uid_eq(pcred->uid, mycred->euid) ||
1511 pcred->euid != mycred->euid || 1530 !uid_eq(pcred->euid, mycred->euid) ||
1512 pcred->suid != mycred->euid || 1531 !uid_eq(pcred->suid, mycred->euid) ||
1513 pcred->gid != mycred->egid || 1532 !gid_eq(pcred->gid, mycred->egid) ||
1514 pcred->egid != mycred->egid || 1533 !gid_eq(pcred->egid, mycred->egid) ||
1515 pcred->sgid != mycred->egid) 1534 !gid_eq(pcred->sgid, mycred->egid))
1516 goto unlock; 1535 goto unlock;
1517 1536
1518 /* the keyrings must have the same UID */ 1537 /* the keyrings must have the same UID */
1519 if ((pcred->tgcred->session_keyring && 1538 if ((pcred->tgcred->session_keyring &&
1520 pcred->tgcred->session_keyring->uid != mycred->euid) || 1539 !uid_eq(pcred->tgcred->session_keyring->uid, mycred->euid)) ||
1521 mycred->tgcred->session_keyring->uid != mycred->euid) 1540 !uid_eq(mycred->tgcred->session_keyring->uid, mycred->euid))
1522 goto unlock; 1541 goto unlock;
1523 1542
1524 /* cancel an already pending keyring replacement */ 1543 /* cancel an already pending keyring replacement */
@@ -1530,7 +1549,6 @@ long keyctl_session_to_parent(void)
1530 if (!ret) 1549 if (!ret)
1531 newwork = NULL; 1550 newwork = NULL;
1532unlock: 1551unlock:
1533 task_unlock(parent);
1534 write_unlock_irq(&tasklist_lock); 1552 write_unlock_irq(&tasklist_lock);
1535 rcu_read_unlock(); 1553 rcu_read_unlock();
1536 if (oldwork) 1554 if (oldwork)