aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--security/keys/keyring.c39
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/*