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 | /* |
