summaryrefslogtreecommitdiffstats
path: root/src/shared/keyring-util.c
blob: 655cf5241d2937d6db9bba37d9dbe9e357051a86 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include "keyring-util.h"
#include "memory-util.h"
#include "missing_syscall.h"

int keyring_read(key_serial_t serial, void **ret, size_t *ret_size) {
        size_t m = 100;

        for (;;) {
                _cleanup_(erase_and_freep) uint8_t *p = NULL;
                long n;

                p = new(uint8_t, m+1);
                if (!p)
                        return -ENOMEM;

                n = keyctl(KEYCTL_READ, (unsigned long) serial, (unsigned long) p, (unsigned long) m, 0);
                if (n < 0)
                        return -errno;

                if ((size_t) n <= m) {
                        p[n] = 0; /* NUL terminate, just in case */

                        if (ret)
                                *ret = TAKE_PTR(p);
                        if (ret_size)
                                *ret_size = n;

                        return 0;
                }

                if (m > (SIZE_MAX-1) / 2) /* overflow check */
                        return -ENOMEM;

                m *= 2;
        }
}