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