]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/uuid.c
Merge pull request #3059 from brauner/2019-06-21/seccomp_notify
[mirror_lxc.git] / src / lxc / uuid.c
CommitLineData
20502652
CB
1/* liblxcapi
2 *
3 * Copyright © 2019 Christian Brauner <christian.brauner@ubuntu.com>.
4 * Copyright © 2019 Canonical Ltd.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this library; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 * Stolen and reworked from systemd.
21 */
22
23#define _GNU_SOURCE
24#define __STDC_FORMAT_MACROS /* Required for PRIu64 to work. */
25#include <errno.h>
26#include <fcntl.h>
27#include <inttypes.h>
28#include <limits.h>
29#include <linux/types.h>
30#include <sched.h>
31#include <signal.h>
32#include <stdio.h>
33#include <stdlib.h>
34#include <string.h>
35#include <sys/mount.h>
36#include <sys/stat.h>
37#include <sys/syscall.h>
38#include <sys/types.h>
39#include <unistd.h>
40
41#include "config.h"
42#include "file_utils.h"
43#include "memory_utils.h"
44#include "uuid.h"
45
46static lxc_id128_t make_v4_uuid(lxc_id128_t id)
47{
48 /* Stolen from generate_random_uuid() of drivers/char/random.c
49 * in the kernel sources */
50
51 /* Set UUID version to 4 --- truly random generation */
52 id.bytes[6] = (id.bytes[6] & 0x0F) | 0x40;
53
54 /* Set the UUID variant to DCE */
55 id.bytes[8] = (id.bytes[8] & 0x3F) | 0x80;
56
57 return id;
58}
59
60static int get_random_bytes(void *p, size_t n)
61{
62 __do_close_prot_errno int fd = -1;
63 ssize_t bytes = 0;
64
65 fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOCTTY);
66 if (fd < 0)
67 return -1;
68
69 bytes = read(fd, p, n);
70 if (bytes != n)
71 return -1;
72
73 return 0;
74}
75
76int lxc_id128_randomize(lxc_id128_t *ret)
77{
78 lxc_id128_t t;
79 int r;
80
81 /* We allow usage if x86-64 RDRAND here. It might not be trusted enough
82 * for keeping secrets, but it should be fine for UUIDS. */
83 r = get_random_bytes(&t, sizeof(t));
84 if (r < 0)
85 return r;
86
87 /* Turn this into a valid v4 UUID, to be nice. Note that we
88 * only guarantee this for newly generated UUIDs, not for
89 * pre-existing ones. */
90
91 *ret = make_v4_uuid(t);
92 return 0;
93}
94
95static char hexchar(int x)
96{
97 static const char table[16] = "0123456789abcdef";
98
99 return table[x & 15];
100}
101
102char *id128_to_uuid_string(lxc_id128_t id, char s[37])
103{
104 unsigned n, k = 0;
105
106 for (n = 0; n < 16; n++) {
107
108 if (n == 4 || n == 6 || n == 8 || n == 10)
109 s[k++] = '-';
110
111 s[k++] = hexchar(id.bytes[n] >> 4);
112 s[k++] = hexchar(id.bytes[n] & 0xF);
113 }
114
115 s[k] = 0;
116
117 return s;
118}
119
120int lxc_id128_write_fd(int fd, lxc_id128_t id)
121{
122 char buffer[36 + 2];
123 size_t sz;
124 int ret;
125
126 id128_to_uuid_string(id, buffer);
127 buffer[36] = '\n';
128 sz = 37;
129
130 ret = lxc_write_nointr(fd, buffer, sz);
131 if (ret < 0)
132 return -1;
133
134 return 0;
135}
136
137int lxc_id128_write(const char *p, lxc_id128_t id)
138{
139 int fd = -1;
140
141 fd = open(p, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_TRUNC, 0444);
142 if (fd < 0)
143 return -1;
144
145 return lxc_id128_write_fd(fd, id);
146}