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.c33
1 files changed, 22 insertions, 11 deletions
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 3364fbf46807..6d9d0c747525 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 */
@@ -1112,12 +1122,12 @@ long keyctl_instantiate_key_iov(key_serial_t id,
1112 ret = rw_copy_check_uvector(WRITE, _payload_iov, ioc, 1122 ret = rw_copy_check_uvector(WRITE, _payload_iov, ioc,
1113 ARRAY_SIZE(iovstack), iovstack, &iov); 1123 ARRAY_SIZE(iovstack), iovstack, &iov);
1114 if (ret < 0) 1124 if (ret < 0)
1115 return ret; 1125 goto err;
1116 if (ret == 0) 1126 if (ret == 0)
1117 goto no_payload_free; 1127 goto no_payload_free;
1118 1128
1119 ret = keyctl_instantiate_key_common(id, iov, ioc, ret, ringid); 1129 ret = keyctl_instantiate_key_common(id, iov, ioc, ret, ringid);
1120 1130err:
1121 if (iov != iovstack) 1131 if (iov != iovstack)
1122 kfree(iov); 1132 kfree(iov);
1123 return ret; 1133 return ret;
@@ -1475,7 +1485,8 @@ long keyctl_session_to_parent(void)
1475 goto error_keyring; 1485 goto error_keyring;
1476 newwork = &cred->rcu; 1486 newwork = &cred->rcu;
1477 1487
1478 cred->tgcred->session_keyring = key_ref_to_ptr(keyring_r); 1488 cred->session_keyring = key_ref_to_ptr(keyring_r);
1489 keyring_r = NULL;
1479 init_task_work(newwork, key_change_session_keyring); 1490 init_task_work(newwork, key_change_session_keyring);
1480 1491
1481 me = current; 1492 me = current;
@@ -1500,7 +1511,7 @@ long keyctl_session_to_parent(void)
1500 mycred = current_cred(); 1511 mycred = current_cred();
1501 pcred = __task_cred(parent); 1512 pcred = __task_cred(parent);
1502 if (mycred == pcred || 1513 if (mycred == pcred ||
1503 mycred->tgcred->session_keyring == pcred->tgcred->session_keyring) { 1514 mycred->session_keyring == pcred->session_keyring) {
1504 ret = 0; 1515 ret = 0;
1505 goto unlock; 1516 goto unlock;
1506 } 1517 }
@@ -1516,9 +1527,9 @@ long keyctl_session_to_parent(void)
1516 goto unlock; 1527 goto unlock;
1517 1528
1518 /* the keyrings must have the same UID */ 1529 /* the keyrings must have the same UID */
1519 if ((pcred->tgcred->session_keyring && 1530 if ((pcred->session_keyring &&
1520 pcred->tgcred->session_keyring->uid != mycred->euid) || 1531 pcred->session_keyring->uid != mycred->euid) ||
1521 mycred->tgcred->session_keyring->uid != mycred->euid) 1532 mycred->session_keyring->uid != mycred->euid)
1522 goto unlock; 1533 goto unlock;
1523 1534
1524 /* cancel an already pending keyring replacement */ 1535 /* cancel an already pending keyring replacement */