1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include "keyring-util.h"
4 #include "memory-util.h"
5 #include "missing_syscall.h"
6
keyring_read(key_serial_t serial,void ** ret,size_t * ret_size)7 int keyring_read(key_serial_t serial, void **ret, size_t *ret_size) {
8 size_t m = 100;
9
10 for (;;) {
11 _cleanup_(erase_and_freep) uint8_t *p = NULL;
12 long n;
13
14 p = new(uint8_t, m+1);
15 if (!p)
16 return -ENOMEM;
17
18 n = keyctl(KEYCTL_READ, (unsigned long) serial, (unsigned long) p, (unsigned long) m, 0);
19 if (n < 0)
20 return -errno;
21
22 if ((size_t) n <= m) {
23 p[n] = 0; /* NUL terminate, just in case */
24
25 if (ret)
26 *ret = TAKE_PTR(p);
27 if (ret_size)
28 *ret_size = n;
29
30 return 0;
31 }
32
33 if (m > (SIZE_MAX-1) / 2) /* overflow check */
34 return -ENOMEM;
35
36 m *= 2;
37 }
38 }
39