Introduce SELinux hooks to support the access key retention subsystem within the kernel. Incorporate new flask headers from a modified version of the SELinux reference policy, with support for the new security class representing retained keys. Extend the "key_alloc" security hook with a task parameter representing the intended ownership context for the key being allocated. Attach security information to root's default keyrings within the SELinux initialization routine. Has passed David's testsuite.
Showing the changes to security/keys (5 of 16 files). Show all
Unified · Split
| @@ -247,8 +247,8 @@ static inline void key_alloc_serial(struct key *key) · 246 unmodified lines | ||
| 247 | 247 | * instantiate the key or discard it before returning |
| 248 | 248 | */ |
| 249 | 249 | struct key *key_alloc(struct key_type *type, const char *desc, |
| 250 | − uid_t uid, gid_t gid, key_perm_t perm, | |
| 251 | − int not_in_quota) | |
| 250 | + uid_t uid, gid_t gid, struct task_struct *ctx, | |
| 251 | + key_perm_t perm, int not_in_quota) | |
| 252 | 252 | { |
| 253 | 253 | struct key_user *user = NULL; |
| 254 | 254 | struct key *key; |
| @@ -318,7 +318,7 @@ struct key *key_alloc(struct key_type *type, const char *desc, · 63 unmodified lines | ||
| 318 | 318 | #endif |
| 319 | 319 | |
| 320 | 320 | /* let the security module know about the key */ |
| 321 | − ret = security_key_alloc(key); | |
| 321 | + ret = security_key_alloc(key, ctx); | |
| 322 | 322 | if (ret < 0) |
| 323 | 323 | goto security_error; |
| 324 | 324 | |
| @@ -822,7 +822,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, · 497 unmodified lines | ||
| 822 | 822 | |
| 823 | 823 | /* allocate a new key */ |
| 824 | 824 | key = key_alloc(ktype, description, current->fsuid, current->fsgid, |
| 825 | − perm, not_in_quota); | |
| 825 | + current, perm, not_in_quota); | |
| 826 | 826 | if (IS_ERR(key)) { |
| 827 | 827 | key_ref = ERR_PTR(PTR_ERR(key)); |
| 828 | 828 | goto error_3; |
| @@ -240,13 +240,14 @@ static long keyring_read(const struct key *keyring, · 239 unmodified lines | ||
| 240 | 240 | * allocate a keyring and link into the destination keyring |
| 241 | 241 | */ |
| 242 | 242 | struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, |
| 243 | − int not_in_quota, struct key *dest) | |
| 243 | + struct task_struct *ctx, int not_in_quota, | |
| 244 | + struct key *dest) | |
| 244 | 245 | { |
| 245 | 246 | struct key *keyring; |
| 246 | 247 | int ret; |
| 247 | 248 | |
| 248 | 249 | keyring = key_alloc(&key_type_keyring, description, |
| 249 | − uid, gid, | |
| 250 | + uid, gid, ctx, | |
| 250 | 251 | (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL, |
| 251 | 252 | not_in_quota); |
| 252 | 253 | |
| @@ -67,7 +67,8 @@ struct key root_session_keyring = { · 66 unmodified lines | ||
| 67 | 67 | /* |
| 68 | 68 | * allocate the keyrings to be associated with a UID |
| 69 | 69 | */ |
| 70 | −int alloc_uid_keyring(struct user_struct *user) | |
| 70 | +int alloc_uid_keyring(struct user_struct *user, | |
| 71 | + struct task_struct *ctx) | |
| 71 | 72 | { |
| 72 | 73 | struct key *uid_keyring, *session_keyring; |
| 73 | 74 | char buf[20]; |
| @@ -76,7 +77,7 @@ int alloc_uid_keyring(struct user_struct *user) · 2 unmodified lines | ||
| 76 | 77 | /* concoct a default session keyring */ |
| 77 | 78 | sprintf(buf, "_uid_ses.%u", user->uid); |
| 78 | 79 | |
| 79 | − session_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, 0, NULL); | |
| 80 | + session_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, ctx, 0, NULL); | |
| 80 | 81 | if (IS_ERR(session_keyring)) { |
| 81 | 82 | ret = PTR_ERR(session_keyring); |
| 82 | 83 | goto error; |
| @@ -86,7 +87,7 @@ int alloc_uid_keyring(struct user_struct *user) · 3 unmodified lines | ||
| 86 | 87 | * keyring */ |
| 87 | 88 | sprintf(buf, "_uid.%u", user->uid); |
| 88 | 89 | |
| 89 | − uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, 0, | |
| 90 | + uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, ctx, 0, | |
| 90 | 91 | session_keyring); |
| 91 | 92 | if (IS_ERR(uid_keyring)) { |
| 92 | 93 | key_put(session_keyring); |
| @@ -143,7 +144,7 @@ int install_thread_keyring(struct task_struct *tsk) · 50 unmodified lines | ||
| 143 | 144 | |
| 144 | 145 | sprintf(buf, "_tid.%u", tsk->pid); |
| 145 | 146 | |
| 146 | − keyring = keyring_alloc(buf, tsk->uid, tsk->gid, 1, NULL); | |
| 147 | + keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 1, NULL); | |
| 147 | 148 | if (IS_ERR(keyring)) { |
| 148 | 149 | ret = PTR_ERR(keyring); |
| 149 | 150 | goto error; |
| @@ -177,7 +178,7 @@ int install_process_keyring(struct task_struct *tsk) · 27 unmodified lines | ||
| 177 | 178 | if (!tsk->signal->process_keyring) { |
| 178 | 179 | sprintf(buf, "_pid.%u", tsk->tgid); |
| 179 | 180 | |
| 180 | − keyring = keyring_alloc(buf, tsk->uid, tsk->gid, 1, NULL); | |
| 181 | + keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 1, NULL); | |
| 181 | 182 | if (IS_ERR(keyring)) { |
| 182 | 183 | ret = PTR_ERR(keyring); |
| 183 | 184 | goto error; |
| @@ -217,7 +218,7 @@ static int install_session_keyring(struct task_struct *tsk, · 33 unmodified lines | ||
| 217 | 218 | if (!keyring) { |
| 218 | 219 | sprintf(buf, "_ses.%u", tsk->tgid); |
| 219 | 220 | |
| 220 | − keyring = keyring_alloc(buf, tsk->uid, tsk->gid, 1, NULL); | |
| 221 | + keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 1, NULL); | |
| 221 | 222 | if (IS_ERR(keyring)) |
| 222 | 223 | return PTR_ERR(keyring); |
| 223 | 224 | } |
| @@ -717,7 +718,7 @@ long join_session_keyring(const char *name) · 493 unmodified lines | ||
| 717 | 718 | keyring = find_keyring_by_name(name, 0); |
| 718 | 719 | if (PTR_ERR(keyring) == -ENOKEY) { |
| 719 | 720 | /* not found - try and create a new one */ |
| 720 | − keyring = keyring_alloc(name, tsk->uid, tsk->gid, 0, NULL); | |
| 721 | + keyring = keyring_alloc(name, tsk->uid, tsk->gid, tsk, 0, NULL); | |
| 721 | 722 | if (IS_ERR(keyring)) { |
| 722 | 723 | ret = PTR_ERR(keyring); |
| 723 | 724 | goto error2; |
| @@ -48,7 +48,8 @@ static int call_sbin_request_key(struct key *key, · 47 unmodified lines | ||
| 48 | 48 | /* allocate a new session keyring */ |
| 49 | 49 | sprintf(desc, "_req.%u", key->serial); |
| 50 | 50 | |
| 51 | − keyring = keyring_alloc(desc, current->fsuid, current->fsgid, 1, NULL); | |
| 51 | + keyring = keyring_alloc(desc, current->fsuid, current->fsgid, | |
| 52 | + current, 1, NULL); | |
| 52 | 53 | if (IS_ERR(keyring)) { |
| 53 | 54 | ret = PTR_ERR(keyring); |
| 54 | 55 | goto error_alloc; |
| @@ -137,7 +138,8 @@ static struct key *__request_key_construction(struct key_type *type, · 82 unmodified lines | ||
| 137 | 138 | |
| 138 | 139 | /* create a key and add it to the queue */ |
| 139 | 140 | key = key_alloc(type, description, |
| 140 | − current->fsuid, current->fsgid, KEY_POS_ALL, 0); | |
| 141 | + current->fsuid, current->fsgid, | |
| 142 | + current, KEY_POS_ALL, 0); | |
| 141 | 143 | if (IS_ERR(key)) |
| 142 | 144 | goto alloc_failed; |
| 143 | 145 | |
| @@ -148,7 +148,7 @@ struct key *request_key_auth_new(struct key *target, const char *callout_info) · 147 unmodified lines | ||
| 148 | 148 | sprintf(desc, "%x", target->serial); |
| 149 | 149 | |
| 150 | 150 | authkey = key_alloc(&key_type_request_key_auth, desc, |
| 151 | − current->fsuid, current->fsgid, | |
| 151 | + current->fsuid, current->fsgid, current, | |
| 152 | 152 | KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH | |
| 153 | 153 | KEY_USR_VIEW, 1); |
| 154 | 154 | if (IS_ERR(authkey)) { |