diff options
-rw-r--r-- | security/keys/keyring.c | 39 |
1 files changed, 19 insertions, 20 deletions
diff --git a/security/keys/keyring.c b/security/keys/keyring.c index a7e51f793867..36f842ec87f0 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c | |||
@@ -459,34 +459,33 @@ static long keyring_read(const struct key *keyring, | |||
459 | char __user *buffer, size_t buflen) | 459 | char __user *buffer, size_t buflen) |
460 | { | 460 | { |
461 | struct keyring_read_iterator_context ctx; | 461 | struct keyring_read_iterator_context ctx; |
462 | unsigned long nr_keys; | 462 | long ret; |
463 | int ret; | ||
464 | 463 | ||
465 | kenter("{%d},,%zu", key_serial(keyring), buflen); | 464 | kenter("{%d},,%zu", key_serial(keyring), buflen); |
466 | 465 | ||
467 | if (buflen & (sizeof(key_serial_t) - 1)) | 466 | if (buflen & (sizeof(key_serial_t) - 1)) |
468 | return -EINVAL; | 467 | return -EINVAL; |
469 | 468 | ||
470 | nr_keys = keyring->keys.nr_leaves_on_tree; | 469 | /* Copy as many key IDs as fit into the buffer */ |
471 | if (nr_keys == 0) | 470 | if (buffer && buflen) { |
472 | return 0; | 471 | ctx.buffer = (key_serial_t __user *)buffer; |
473 | 472 | ctx.buflen = buflen; | |
474 | /* Calculate how much data we could return */ | 473 | ctx.count = 0; |
475 | if (!buffer || !buflen) | 474 | ret = assoc_array_iterate(&keyring->keys, |
476 | return nr_keys * sizeof(key_serial_t); | 475 | keyring_read_iterator, &ctx); |
477 | 476 | if (ret < 0) { | |
478 | /* Copy the IDs of the subscribed keys into the buffer */ | 477 | kleave(" = %ld [iterate]", ret); |
479 | ctx.buffer = (key_serial_t __user *)buffer; | 478 | return ret; |
480 | ctx.buflen = buflen; | 479 | } |
481 | ctx.count = 0; | ||
482 | ret = assoc_array_iterate(&keyring->keys, keyring_read_iterator, &ctx); | ||
483 | if (ret < 0) { | ||
484 | kleave(" = %d [iterate]", ret); | ||
485 | return ret; | ||
486 | } | 480 | } |
487 | 481 | ||
488 | kleave(" = %zu [ok]", ctx.count); | 482 | /* Return the size of the buffer needed */ |
489 | return ctx.count; | 483 | ret = keyring->keys.nr_leaves_on_tree * sizeof(key_serial_t); |
484 | if (ret <= buflen) | ||
485 | kleave("= %ld [ok]", ret); | ||
486 | else | ||
487 | kleave("= %ld [buffer too small]", ret); | ||
488 | return ret; | ||
490 | } | 489 | } |
491 | 490 | ||
492 | /* | 491 | /* |