diff options
Diffstat (limited to 'security/keys/keyctl.c')
-rw-r--r-- | security/keys/keyctl.c | 33 |
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 | 1130 | err: | |
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 */ |