Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'fixes-v5.1-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security

Pull keys fixes from James Morris:

- Handle quotas better, allowing full quota to be reached.

- Fix the creation of shortcuts in the assoc_array internal
representation when the index key needs to be an exact multiple of
the machine word size.

- Fix a dependency loop between the request_key contruction record and
the request_key authentication key. The construction record isn't
really necessary and can be dispensed with.

- Set the timestamp on a new key rather than leaving it as 0. This
would ordinarily be fine - provided the system clock is never set to
a time before 1970

* 'fixes-v5.1-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security:
keys: Timestamp new keys
keys: Fix dependency loop between construction record and auth key
assoc_array: Fix shortcut creation
KEYS: allow reaching the keys quotas exactly

+108 -97
+17 -14
fs/nfs/nfs4idmap.c
··· 44 44 #include <linux/keyctl.h> 45 45 #include <linux/key-type.h> 46 46 #include <keys/user-type.h> 47 + #include <keys/request_key_auth-type.h> 47 48 #include <linux/module.h> 48 49 49 50 #include "internal.h" ··· 60 59 struct idmap_legacy_upcalldata { 61 60 struct rpc_pipe_msg pipe_msg; 62 61 struct idmap_msg idmap_msg; 63 - struct key_construction *key_cons; 62 + struct key *authkey; 64 63 struct idmap *idmap; 65 64 }; 66 65 ··· 385 384 { Opt_find_err, NULL } 386 385 }; 387 386 388 - static int nfs_idmap_legacy_upcall(struct key_construction *, const char *, void *); 387 + static int nfs_idmap_legacy_upcall(struct key *, void *); 389 388 static ssize_t idmap_pipe_downcall(struct file *, const char __user *, 390 389 size_t); 391 390 static void idmap_release_pipe(struct inode *); ··· 550 549 static void 551 550 nfs_idmap_complete_pipe_upcall_locked(struct idmap *idmap, int ret) 552 551 { 553 - struct key_construction *cons = idmap->idmap_upcall_data->key_cons; 552 + struct key *authkey = idmap->idmap_upcall_data->authkey; 554 553 555 554 kfree(idmap->idmap_upcall_data); 556 555 idmap->idmap_upcall_data = NULL; 557 - complete_request_key(cons, ret); 556 + complete_request_key(authkey, ret); 557 + key_put(authkey); 558 558 } 559 559 560 560 static void ··· 565 563 nfs_idmap_complete_pipe_upcall_locked(idmap, ret); 566 564 } 567 565 568 - static int nfs_idmap_legacy_upcall(struct key_construction *cons, 569 - const char *op, 570 - void *aux) 566 + static int nfs_idmap_legacy_upcall(struct key *authkey, void *aux) 571 567 { 572 568 struct idmap_legacy_upcalldata *data; 569 + struct request_key_auth *rka = get_request_key_auth(authkey); 573 570 struct rpc_pipe_msg *msg; 574 571 struct idmap_msg *im; 575 572 struct idmap *idmap = (struct idmap *)aux; 576 - struct key *key = cons->key; 573 + struct key *key = rka->target_key; 577 574 int ret = -ENOKEY; 578 575 579 576 if (!aux) ··· 587 586 msg = &data->pipe_msg; 588 587 im = &data->idmap_msg; 589 588 data->idmap = idmap; 590 - data->key_cons = cons; 589 + data->authkey = key_get(authkey); 591 590 592 591 ret = nfs_idmap_prepare_message(key->description, idmap, im, msg); 593 592 if (ret < 0) ··· 605 604 out2: 606 605 kfree(data); 607 606 out1: 608 - complete_request_key(cons, ret); 607 + complete_request_key(authkey, ret); 609 608 return ret; 610 609 } 611 610 ··· 652 651 static ssize_t 653 652 idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) 654 653 { 654 + struct request_key_auth *rka; 655 655 struct rpc_inode *rpci = RPC_I(file_inode(filp)); 656 656 struct idmap *idmap = (struct idmap *)rpci->private; 657 - struct key_construction *cons; 657 + struct key *authkey; 658 658 struct idmap_msg im; 659 659 size_t namelen_in; 660 660 int ret = -ENOKEY; ··· 667 665 if (idmap->idmap_upcall_data == NULL) 668 666 goto out_noupcall; 669 667 670 - cons = idmap->idmap_upcall_data->key_cons; 668 + authkey = idmap->idmap_upcall_data->authkey; 669 + rka = get_request_key_auth(authkey); 671 670 672 671 if (mlen != sizeof(im)) { 673 672 ret = -ENOSPC; ··· 693 690 694 691 ret = nfs_idmap_read_and_verify_message(&im, 695 692 &idmap->idmap_upcall_data->idmap_msg, 696 - cons->key, cons->authkey); 693 + rka->target_key, authkey); 697 694 if (ret >= 0) { 698 - key_set_timeout(cons->key, nfs_idmap_cache_timeout); 695 + key_set_timeout(rka->target_key, nfs_idmap_cache_timeout); 699 696 ret = mlen; 700 697 } 701 698
+36
include/keys/request_key_auth-type.h
··· 1 + /* request_key authorisation token key type 2 + * 3 + * Copyright (C) 2005 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 Licence 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the Licence, or (at your option) any later version. 10 + */ 11 + 12 + #ifndef _KEYS_REQUEST_KEY_AUTH_TYPE_H 13 + #define _KEYS_REQUEST_KEY_AUTH_TYPE_H 14 + 15 + #include <linux/key.h> 16 + 17 + /* 18 + * Authorisation record for request_key(). 19 + */ 20 + struct request_key_auth { 21 + struct key *target_key; 22 + struct key *dest_keyring; 23 + const struct cred *cred; 24 + void *callout_info; 25 + size_t callout_len; 26 + pid_t pid; 27 + char op[8]; 28 + } __randomize_layout; 29 + 30 + static inline struct request_key_auth *get_request_key_auth(const struct key *key) 31 + { 32 + return key->payload.data[0]; 33 + } 34 + 35 + 36 + #endif /* _KEYS_REQUEST_KEY_AUTH_TYPE_H */
+6 -16
include/linux/key-type.h
··· 21 21 struct kernel_pkey_params; 22 22 23 23 /* 24 - * key under-construction record 25 - * - passed to the request_key actor if supplied 26 - */ 27 - struct key_construction { 28 - struct key *key; /* key being constructed */ 29 - struct key *authkey;/* authorisation for key being constructed */ 30 - }; 31 - 32 - /* 33 24 * Pre-parsed payload, used by key add, update and instantiate. 34 25 * 35 26 * This struct will be cleared and data and datalen will be set with the data ··· 41 50 time64_t expiry; /* Expiry time of key */ 42 51 } __randomize_layout; 43 52 44 - typedef int (*request_key_actor_t)(struct key_construction *key, 45 - const char *op, void *aux); 53 + typedef int (*request_key_actor_t)(struct key *auth_key, void *aux); 46 54 47 55 /* 48 56 * Preparsed matching criterion. ··· 171 181 const void *data, 172 182 size_t datalen, 173 183 struct key *keyring, 174 - struct key *instkey); 184 + struct key *authkey); 175 185 extern int key_reject_and_link(struct key *key, 176 186 unsigned timeout, 177 187 unsigned error, 178 188 struct key *keyring, 179 - struct key *instkey); 180 - extern void complete_request_key(struct key_construction *cons, int error); 189 + struct key *authkey); 190 + extern void complete_request_key(struct key *authkey, int error); 181 191 182 192 static inline int key_negate_and_link(struct key *key, 183 193 unsigned timeout, 184 194 struct key *keyring, 185 - struct key *instkey) 195 + struct key *authkey) 186 196 { 187 - return key_reject_and_link(key, timeout, ENOKEY, keyring, instkey); 197 + return key_reject_and_link(key, timeout, ENOKEY, keyring, authkey); 188 198 } 189 199 190 200 extern int generic_key_instantiate(struct key *key, struct key_preparsed_payload *prep);
+5 -3
lib/assoc_array.c
··· 768 768 new_s0->index_key[i] = 769 769 ops->get_key_chunk(index_key, i * ASSOC_ARRAY_KEY_CHUNK_SIZE); 770 770 771 - blank = ULONG_MAX << (level & ASSOC_ARRAY_KEY_CHUNK_MASK); 772 - pr_devel("blank off [%zu] %d: %lx\n", keylen - 1, level, blank); 773 - new_s0->index_key[keylen - 1] &= ~blank; 771 + if (level & ASSOC_ARRAY_KEY_CHUNK_MASK) { 772 + blank = ULONG_MAX << (level & ASSOC_ARRAY_KEY_CHUNK_MASK); 773 + pr_devel("blank off [%zu] %d: %lx\n", keylen - 1, level, blank); 774 + new_s0->index_key[keylen - 1] &= ~blank; 775 + } 774 776 775 777 /* This now reduces to a node splitting exercise for which we'll need 776 778 * to regenerate the disparity table.
+1 -12
security/keys/internal.h
··· 186 186 return key_task_permission(key_ref, current_cred(), perm); 187 187 } 188 188 189 - /* 190 - * Authorisation record for request_key(). 191 - */ 192 - struct request_key_auth { 193 - struct key *target_key; 194 - struct key *dest_keyring; 195 - const struct cred *cred; 196 - void *callout_info; 197 - size_t callout_len; 198 - pid_t pid; 199 - } __randomize_layout; 200 - 201 189 extern struct key_type key_type_request_key_auth; 202 190 extern struct key *request_key_auth_new(struct key *target, 191 + const char *op, 203 192 const void *callout_info, 204 193 size_t callout_len, 205 194 struct key *dest_keyring);
+3 -2
security/keys/key.c
··· 265 265 266 266 spin_lock(&user->lock); 267 267 if (!(flags & KEY_ALLOC_QUOTA_OVERRUN)) { 268 - if (user->qnkeys + 1 >= maxkeys || 269 - user->qnbytes + quotalen >= maxbytes || 268 + if (user->qnkeys + 1 > maxkeys || 269 + user->qnbytes + quotalen > maxbytes || 270 270 user->qnbytes + quotalen < user->qnbytes) 271 271 goto no_quota; 272 272 } ··· 297 297 key->gid = gid; 298 298 key->perm = perm; 299 299 key->restrict_link = restrict_link; 300 + key->last_used_at = ktime_get_real_seconds(); 300 301 301 302 if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) 302 303 key->flags |= 1 << KEY_FLAG_IN_QUOTA;
+1
security/keys/keyctl.c
··· 25 25 #include <linux/security.h> 26 26 #include <linux/uio.h> 27 27 #include <linux/uaccess.h> 28 + #include <keys/request_key_auth-type.h> 28 29 #include "internal.h" 29 30 30 31 #define KEY_MAX_DESC_SIZE 4096
+1
security/keys/process_keys.c
··· 19 19 #include <linux/security.h> 20 20 #include <linux/user_namespace.h> 21 21 #include <linux/uaccess.h> 22 + #include <keys/request_key_auth-type.h> 22 23 #include "internal.h" 23 24 24 25 /* Session keyring create vs join semaphore */
+29 -43
security/keys/request_key.c
··· 18 18 #include <linux/keyctl.h> 19 19 #include <linux/slab.h> 20 20 #include "internal.h" 21 + #include <keys/request_key_auth-type.h> 21 22 22 23 #define key_negative_timeout 60 /* default timeout on a negative key's existence */ 23 24 24 25 /** 25 26 * complete_request_key - Complete the construction of a key. 26 - * @cons: The key construction record. 27 + * @auth_key: The authorisation key. 27 28 * @error: The success or failute of the construction. 28 29 * 29 30 * Complete the attempt to construct a key. The key will be negated 30 31 * if an error is indicated. The authorisation key will be revoked 31 32 * unconditionally. 32 33 */ 33 - void complete_request_key(struct key_construction *cons, int error) 34 + void complete_request_key(struct key *authkey, int error) 34 35 { 35 - kenter("{%d,%d},%d", cons->key->serial, cons->authkey->serial, error); 36 + struct request_key_auth *rka = get_request_key_auth(authkey); 37 + struct key *key = rka->target_key; 38 + 39 + kenter("%d{%d},%d", authkey->serial, key->serial, error); 36 40 37 41 if (error < 0) 38 - key_negate_and_link(cons->key, key_negative_timeout, NULL, 39 - cons->authkey); 42 + key_negate_and_link(key, key_negative_timeout, NULL, authkey); 40 43 else 41 - key_revoke(cons->authkey); 42 - 43 - key_put(cons->key); 44 - key_put(cons->authkey); 45 - kfree(cons); 44 + key_revoke(authkey); 46 45 } 47 46 EXPORT_SYMBOL(complete_request_key); 48 47 ··· 90 91 * Request userspace finish the construction of a key 91 92 * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring>" 92 93 */ 93 - static int call_sbin_request_key(struct key_construction *cons, 94 - const char *op, 95 - void *aux) 94 + static int call_sbin_request_key(struct key *authkey, void *aux) 96 95 { 97 96 static char const request_key[] = "/sbin/request-key"; 97 + struct request_key_auth *rka = get_request_key_auth(authkey); 98 98 const struct cred *cred = current_cred(); 99 99 key_serial_t prkey, sskey; 100 - struct key *key = cons->key, *authkey = cons->authkey, *keyring, 101 - *session; 100 + struct key *key = rka->target_key, *keyring, *session; 102 101 char *argv[9], *envp[3], uid_str[12], gid_str[12]; 103 102 char key_str[12], keyring_str[3][12]; 104 103 char desc[20]; 105 104 int ret, i; 106 105 107 - kenter("{%d},{%d},%s", key->serial, authkey->serial, op); 106 + kenter("{%d},{%d},%s", key->serial, authkey->serial, rka->op); 108 107 109 108 ret = install_user_keyrings(); 110 109 if (ret < 0) ··· 160 163 /* set up the argument list */ 161 164 i = 0; 162 165 argv[i++] = (char *)request_key; 163 - argv[i++] = (char *) op; 166 + argv[i++] = (char *)rka->op; 164 167 argv[i++] = key_str; 165 168 argv[i++] = uid_str; 166 169 argv[i++] = gid_str; ··· 188 191 key_put(keyring); 189 192 190 193 error_alloc: 191 - complete_request_key(cons, ret); 194 + complete_request_key(authkey, ret); 192 195 kleave(" = %d", ret); 193 196 return ret; 194 197 } ··· 202 205 size_t callout_len, void *aux, 203 206 struct key *dest_keyring) 204 207 { 205 - struct key_construction *cons; 206 208 request_key_actor_t actor; 207 209 struct key *authkey; 208 210 int ret; 209 211 210 212 kenter("%d,%p,%zu,%p", key->serial, callout_info, callout_len, aux); 211 213 212 - cons = kmalloc(sizeof(*cons), GFP_KERNEL); 213 - if (!cons) 214 - return -ENOMEM; 215 - 216 214 /* allocate an authorisation key */ 217 - authkey = request_key_auth_new(key, callout_info, callout_len, 215 + authkey = request_key_auth_new(key, "create", callout_info, callout_len, 218 216 dest_keyring); 219 - if (IS_ERR(authkey)) { 220 - kfree(cons); 221 - ret = PTR_ERR(authkey); 222 - authkey = NULL; 223 - } else { 224 - cons->authkey = key_get(authkey); 225 - cons->key = key_get(key); 217 + if (IS_ERR(authkey)) 218 + return PTR_ERR(authkey); 226 219 227 - /* make the call */ 228 - actor = call_sbin_request_key; 229 - if (key->type->request_key) 230 - actor = key->type->request_key; 220 + /* Make the call */ 221 + actor = call_sbin_request_key; 222 + if (key->type->request_key) 223 + actor = key->type->request_key; 231 224 232 - ret = actor(cons, "create", aux); 225 + ret = actor(authkey, aux); 233 226 234 - /* check that the actor called complete_request_key() prior to 235 - * returning an error */ 236 - WARN_ON(ret < 0 && 237 - !test_bit(KEY_FLAG_REVOKED, &authkey->flags)); 238 - key_put(authkey); 239 - } 227 + /* check that the actor called complete_request_key() prior to 228 + * returning an error */ 229 + WARN_ON(ret < 0 && 230 + !test_bit(KEY_FLAG_REVOKED, &authkey->flags)); 240 231 232 + key_put(authkey); 241 233 kleave(" = %d", ret); 242 234 return ret; 243 235 } ··· 261 275 if (cred->request_key_auth) { 262 276 authkey = cred->request_key_auth; 263 277 down_read(&authkey->sem); 264 - rka = authkey->payload.data[0]; 278 + rka = get_request_key_auth(authkey); 265 279 if (!test_bit(KEY_FLAG_REVOKED, 266 280 &authkey->flags)) 267 281 dest_keyring =
+9 -7
security/keys/request_key_auth.c
··· 17 17 #include <linux/slab.h> 18 18 #include <linux/uaccess.h> 19 19 #include "internal.h" 20 - #include <keys/user-type.h> 20 + #include <keys/request_key_auth-type.h> 21 21 22 22 static int request_key_auth_preparse(struct key_preparsed_payload *); 23 23 static void request_key_auth_free_preparse(struct key_preparsed_payload *); ··· 68 68 static void request_key_auth_describe(const struct key *key, 69 69 struct seq_file *m) 70 70 { 71 - struct request_key_auth *rka = key->payload.data[0]; 71 + struct request_key_auth *rka = get_request_key_auth(key); 72 72 73 73 seq_puts(m, "key:"); 74 74 seq_puts(m, key->description); ··· 83 83 static long request_key_auth_read(const struct key *key, 84 84 char __user *buffer, size_t buflen) 85 85 { 86 - struct request_key_auth *rka = key->payload.data[0]; 86 + struct request_key_auth *rka = get_request_key_auth(key); 87 87 size_t datalen; 88 88 long ret; 89 89 ··· 109 109 */ 110 110 static void request_key_auth_revoke(struct key *key) 111 111 { 112 - struct request_key_auth *rka = key->payload.data[0]; 112 + struct request_key_auth *rka = get_request_key_auth(key); 113 113 114 114 kenter("{%d}", key->serial); 115 115 ··· 136 136 */ 137 137 static void request_key_auth_destroy(struct key *key) 138 138 { 139 - struct request_key_auth *rka = key->payload.data[0]; 139 + struct request_key_auth *rka = get_request_key_auth(key); 140 140 141 141 kenter("{%d}", key->serial); 142 142 ··· 147 147 * Create an authorisation token for /sbin/request-key or whoever to gain 148 148 * access to the caller's security data. 149 149 */ 150 - struct key *request_key_auth_new(struct key *target, const void *callout_info, 151 - size_t callout_len, struct key *dest_keyring) 150 + struct key *request_key_auth_new(struct key *target, const char *op, 151 + const void *callout_info, size_t callout_len, 152 + struct key *dest_keyring) 152 153 { 153 154 struct request_key_auth *rka, *irka; 154 155 const struct cred *cred = current->cred; ··· 167 166 if (!rka->callout_info) 168 167 goto error_free_rka; 169 168 rka->callout_len = callout_len; 169 + strlcpy(rka->op, op, sizeof(rka->op)); 170 170 171 171 /* see if the calling process is already servicing the key request of 172 172 * another process */