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 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security

Pull keyring/nfs fixes from James Morris:
"From David Howells:

The first one fixes the handling of maximum buffer size for key
descriptions, fixing the size at 4095 + NUL char rather than whatever
PAGE_SIZE happens to be and permits you to read back the full
description without it getting clipped because some extra information
got prepended.

The second and third fix a bug in NFS idmapper handling whereby a key
representing a mapping between an id and a name expires and causing
EKEYEXPIRED to be seen internally in NFS (which prevents the mapping
from happening) rather than re-looking up the mapping"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security:
KEYS: request_key() should reget expired keys rather than give EKEYEXPIRED
KEYS: Simplify KEYRING_SEARCH_{NO,DO}_STATE_CHECK flags
KEYS: Fix the size of the key description passed to/from userspace

+36 -34
+1
security/keys/internal.h
··· 117 117 #define KEYRING_SEARCH_NO_UPDATE_TIME 0x0004 /* Don't update times */ 118 118 #define KEYRING_SEARCH_NO_CHECK_PERM 0x0008 /* Don't check permissions */ 119 119 #define KEYRING_SEARCH_DETECT_TOO_DEEP 0x0010 /* Give an error on excessive depth */ 120 + #define KEYRING_SEARCH_SKIP_EXPIRED 0x0020 /* Ignore expired keys (intention to replace) */ 120 121 121 122 int (*iterator)(const void *object, void *iterator_data); 122 123
+26 -30
security/keys/keyctl.c
··· 26 26 #include <asm/uaccess.h> 27 27 #include "internal.h" 28 28 29 + #define KEY_MAX_DESC_SIZE 4096 30 + 29 31 static int key_get_type_from_user(char *type, 30 32 const char __user *_type, 31 33 unsigned len) ··· 80 78 81 79 description = NULL; 82 80 if (_description) { 83 - description = strndup_user(_description, PAGE_SIZE); 81 + description = strndup_user(_description, KEY_MAX_DESC_SIZE); 84 82 if (IS_ERR(description)) { 85 83 ret = PTR_ERR(description); 86 84 goto error; ··· 179 177 goto error; 180 178 181 179 /* pull the description into kernel space */ 182 - description = strndup_user(_description, PAGE_SIZE); 180 + description = strndup_user(_description, KEY_MAX_DESC_SIZE); 183 181 if (IS_ERR(description)) { 184 182 ret = PTR_ERR(description); 185 183 goto error; ··· 289 287 /* fetch the name from userspace */ 290 288 name = NULL; 291 289 if (_name) { 292 - name = strndup_user(_name, PAGE_SIZE); 290 + name = strndup_user(_name, KEY_MAX_DESC_SIZE); 293 291 if (IS_ERR(name)) { 294 292 ret = PTR_ERR(name); 295 293 goto error; ··· 564 562 { 565 563 struct key *key, *instkey; 566 564 key_ref_t key_ref; 567 - char *tmpbuf; 565 + char *infobuf; 568 566 long ret; 567 + int desclen, infolen; 569 568 570 569 key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, KEY_NEED_VIEW); 571 570 if (IS_ERR(key_ref)) { ··· 589 586 } 590 587 591 588 okay: 592 - /* calculate how much description we're going to return */ 593 - ret = -ENOMEM; 594 - tmpbuf = kmalloc(PAGE_SIZE, GFP_KERNEL); 595 - if (!tmpbuf) 596 - goto error2; 597 - 598 589 key = key_ref_to_ptr(key_ref); 590 + desclen = strlen(key->description); 599 591 600 - ret = snprintf(tmpbuf, PAGE_SIZE - 1, 601 - "%s;%d;%d;%08x;%s", 602 - key->type->name, 603 - from_kuid_munged(current_user_ns(), key->uid), 604 - from_kgid_munged(current_user_ns(), key->gid), 605 - key->perm, 606 - key->description ?: ""); 607 - 608 - /* include a NUL char at the end of the data */ 609 - if (ret > PAGE_SIZE - 1) 610 - ret = PAGE_SIZE - 1; 611 - tmpbuf[ret] = 0; 612 - ret++; 592 + /* calculate how much information we're going to return */ 593 + ret = -ENOMEM; 594 + infobuf = kasprintf(GFP_KERNEL, 595 + "%s;%d;%d;%08x;", 596 + key->type->name, 597 + from_kuid_munged(current_user_ns(), key->uid), 598 + from_kgid_munged(current_user_ns(), key->gid), 599 + key->perm); 600 + if (!infobuf) 601 + goto error2; 602 + infolen = strlen(infobuf); 603 + ret = infolen + desclen + 1; 613 604 614 605 /* consider returning the data */ 615 - if (buffer && buflen > 0) { 616 - if (buflen > ret) 617 - buflen = ret; 618 - 619 - if (copy_to_user(buffer, tmpbuf, buflen) != 0) 606 + if (buffer && buflen >= ret) { 607 + if (copy_to_user(buffer, infobuf, infolen) != 0 || 608 + copy_to_user(buffer + infolen, key->description, 609 + desclen + 1) != 0) 620 610 ret = -EFAULT; 621 611 } 622 612 623 - kfree(tmpbuf); 613 + kfree(infobuf); 624 614 error2: 625 615 key_ref_put(key_ref); 626 616 error: ··· 645 649 if (ret < 0) 646 650 goto error; 647 651 648 - description = strndup_user(_description, PAGE_SIZE); 652 + description = strndup_user(_description, KEY_MAX_DESC_SIZE); 649 653 if (IS_ERR(description)) { 650 654 ret = PTR_ERR(description); 651 655 goto error;
+6 -4
security/keys/keyring.c
··· 546 546 } 547 547 548 548 if (key->expiry && ctx->now.tv_sec >= key->expiry) { 549 - ctx->result = ERR_PTR(-EKEYEXPIRED); 549 + if (!(ctx->flags & KEYRING_SEARCH_SKIP_EXPIRED)) 550 + ctx->result = ERR_PTR(-EKEYEXPIRED); 550 551 kleave(" = %d [expire]", ctx->skipped_ret); 551 552 goto skipped; 552 553 } ··· 629 628 ctx->index_key.type->name, 630 629 ctx->index_key.description); 631 630 631 + #define STATE_CHECKS (KEYRING_SEARCH_NO_STATE_CHECK | KEYRING_SEARCH_DO_STATE_CHECK) 632 + BUG_ON((ctx->flags & STATE_CHECKS) == 0 || 633 + (ctx->flags & STATE_CHECKS) == STATE_CHECKS); 634 + 632 635 if (ctx->index_key.description) 633 636 ctx->index_key.desc_len = strlen(ctx->index_key.description); 634 637 ··· 642 637 if (ctx->match_data.lookup_type == KEYRING_SEARCH_LOOKUP_ITERATE || 643 638 keyring_compare_object(keyring, &ctx->index_key)) { 644 639 ctx->skipped_ret = 2; 645 - ctx->flags |= KEYRING_SEARCH_DO_STATE_CHECK; 646 640 switch (ctx->iterator(keyring_key_to_ptr(keyring), ctx)) { 647 641 case 1: 648 642 goto found; ··· 653 649 } 654 650 655 651 ctx->skipped_ret = 0; 656 - if (ctx->flags & KEYRING_SEARCH_NO_STATE_CHECK) 657 - ctx->flags &= ~KEYRING_SEARCH_DO_STATE_CHECK; 658 652 659 653 /* Start processing a new keyring */ 660 654 descend_to_keyring:
+2
security/keys/request_key.c
··· 516 516 .match_data.cmp = key_default_cmp, 517 517 .match_data.raw_data = description, 518 518 .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, 519 + .flags = (KEYRING_SEARCH_DO_STATE_CHECK | 520 + KEYRING_SEARCH_SKIP_EXPIRED), 519 521 }; 520 522 struct key *key; 521 523 key_ref_t key_ref;
+1
security/keys/request_key_auth.c
··· 249 249 .match_data.cmp = key_default_cmp, 250 250 .match_data.raw_data = description, 251 251 .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, 252 + .flags = KEYRING_SEARCH_DO_STATE_CHECK, 252 253 }; 253 254 struct key *authkey; 254 255 key_ref_t authkey_ref;