mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-07-27 11:13:50 +00:00
Merge pull request #3034 from brauner/2019-06-05/boot_id
start: generate new boot id on container start
This commit is contained in:
commit
20a64b0b0d
@ -45,7 +45,8 @@ noinst_HEADERS = api_extensions.h \
|
||||
../tests/lxctest.h \
|
||||
tools/arguments.h \
|
||||
storage/storage_utils.h \
|
||||
utils.h
|
||||
utils.h \
|
||||
uuid.h
|
||||
|
||||
if IS_BIONIC
|
||||
noinst_HEADERS += ../include/fexecve.h \
|
||||
@ -143,6 +144,7 @@ liblxc_la_SOURCES = af_unix.c af_unix.h \
|
||||
syscall_wrappers.h \
|
||||
terminal.c \
|
||||
utils.c utils.h \
|
||||
uuid.c uuid.h \
|
||||
version.h \
|
||||
$(LSM_SOURCES)
|
||||
|
||||
|
@ -79,6 +79,7 @@
|
||||
#include "syscall_wrappers.h"
|
||||
#include "terminal.h"
|
||||
#include "utils.h"
|
||||
#include "uuid.h"
|
||||
|
||||
#ifdef MAJOR_IN_MKDEV
|
||||
#include <sys/mkdev.h>
|
||||
@ -3488,6 +3489,56 @@ static bool execveat_supported(void)
|
||||
return true;
|
||||
}
|
||||
|
||||
static int lxc_setup_boot_id(void)
|
||||
{
|
||||
int ret;
|
||||
const char *boot_id_path = "/proc/sys/kernel/random/boot_id";
|
||||
const char *mock_boot_id_path = "/dev/.lxc-boot-id";
|
||||
lxc_id128_t n;
|
||||
|
||||
if (access(boot_id_path, F_OK))
|
||||
return 0;
|
||||
|
||||
memset(&n, 0, sizeof(n));
|
||||
if (lxc_id128_randomize(&n)) {
|
||||
SYSERROR("Failed to generate random data for uuid");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = lxc_id128_write(mock_boot_id_path, n);
|
||||
if (ret < 0) {
|
||||
SYSERROR("Failed to write uuid to %s", mock_boot_id_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = chmod(mock_boot_id_path, 0444);
|
||||
if (ret < 0) {
|
||||
SYSERROR("Failed to chown %s", mock_boot_id_path);
|
||||
(void)unlink(mock_boot_id_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = mount(mock_boot_id_path, boot_id_path, NULL, MS_BIND, NULL);
|
||||
if (ret < 0) {
|
||||
SYSERROR("Failed to mount %s to %s", mock_boot_id_path,
|
||||
boot_id_path);
|
||||
(void)unlink(mock_boot_id_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = mount(NULL, boot_id_path, NULL,
|
||||
(MS_BIND | MS_REMOUNT | MS_RDONLY | MS_NOSUID | MS_NOEXEC |
|
||||
MS_NODEV),
|
||||
NULL);
|
||||
if (ret < 0) {
|
||||
SYSERROR("Failed to remount %s read-only", boot_id_path);
|
||||
(void)unlink(mock_boot_id_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lxc_setup(struct lxc_handler *handler)
|
||||
{
|
||||
int ret;
|
||||
@ -3645,6 +3696,10 @@ int lxc_setup(struct lxc_handler *handler)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Setting the boot-id is best-effort for now. */
|
||||
if (lxc_conf->autodev > 0)
|
||||
(void)lxc_setup_boot_id();
|
||||
|
||||
ret = lxc_setup_devpts(lxc_conf);
|
||||
if (ret < 0) {
|
||||
ERROR("Failed to setup new devpts instance");
|
||||
|
146
src/lxc/uuid.c
Normal file
146
src/lxc/uuid.c
Normal file
@ -0,0 +1,146 @@
|
||||
/* liblxcapi
|
||||
*
|
||||
* Copyright © 2019 Christian Brauner <christian.brauner@ubuntu.com>.
|
||||
* Copyright © 2019 Canonical Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Stolen and reworked from systemd.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#define __STDC_FORMAT_MACROS /* Required for PRIu64 to work. */
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
#include <linux/types.h>
|
||||
#include <sched.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "file_utils.h"
|
||||
#include "memory_utils.h"
|
||||
#include "uuid.h"
|
||||
|
||||
static lxc_id128_t make_v4_uuid(lxc_id128_t id)
|
||||
{
|
||||
/* Stolen from generate_random_uuid() of drivers/char/random.c
|
||||
* in the kernel sources */
|
||||
|
||||
/* Set UUID version to 4 --- truly random generation */
|
||||
id.bytes[6] = (id.bytes[6] & 0x0F) | 0x40;
|
||||
|
||||
/* Set the UUID variant to DCE */
|
||||
id.bytes[8] = (id.bytes[8] & 0x3F) | 0x80;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
static int get_random_bytes(void *p, size_t n)
|
||||
{
|
||||
__do_close_prot_errno int fd = -1;
|
||||
ssize_t bytes = 0;
|
||||
|
||||
fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOCTTY);
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
|
||||
bytes = read(fd, p, n);
|
||||
if (bytes != n)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lxc_id128_randomize(lxc_id128_t *ret)
|
||||
{
|
||||
lxc_id128_t t;
|
||||
int r;
|
||||
|
||||
/* We allow usage if x86-64 RDRAND here. It might not be trusted enough
|
||||
* for keeping secrets, but it should be fine for UUIDS. */
|
||||
r = get_random_bytes(&t, sizeof(t));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Turn this into a valid v4 UUID, to be nice. Note that we
|
||||
* only guarantee this for newly generated UUIDs, not for
|
||||
* pre-existing ones. */
|
||||
|
||||
*ret = make_v4_uuid(t);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char hexchar(int x)
|
||||
{
|
||||
static const char table[16] = "0123456789abcdef";
|
||||
|
||||
return table[x & 15];
|
||||
}
|
||||
|
||||
char *id128_to_uuid_string(lxc_id128_t id, char s[37])
|
||||
{
|
||||
unsigned n, k = 0;
|
||||
|
||||
for (n = 0; n < 16; n++) {
|
||||
|
||||
if (n == 4 || n == 6 || n == 8 || n == 10)
|
||||
s[k++] = '-';
|
||||
|
||||
s[k++] = hexchar(id.bytes[n] >> 4);
|
||||
s[k++] = hexchar(id.bytes[n] & 0xF);
|
||||
}
|
||||
|
||||
s[k] = 0;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int lxc_id128_write_fd(int fd, lxc_id128_t id)
|
||||
{
|
||||
char buffer[36 + 2];
|
||||
size_t sz;
|
||||
int ret;
|
||||
|
||||
id128_to_uuid_string(id, buffer);
|
||||
buffer[36] = '\n';
|
||||
sz = 37;
|
||||
|
||||
ret = lxc_write_nointr(fd, buffer, sz);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lxc_id128_write(const char *p, lxc_id128_t id)
|
||||
{
|
||||
int fd = -1;
|
||||
|
||||
fd = open(p, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_TRUNC, 0444);
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
|
||||
return lxc_id128_write_fd(fd, id);
|
||||
}
|
44
src/lxc/uuid.h
Normal file
44
src/lxc/uuid.h
Normal file
@ -0,0 +1,44 @@
|
||||
/* liblxcapi
|
||||
*
|
||||
* Copyright © 2019 Christian Brauner <christian.brauner@ubuntu.com>.
|
||||
* Copyright © 2019 Canonical Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Stolen and reworked from systemd.
|
||||
*/
|
||||
|
||||
#ifndef __LXC_UUID_H
|
||||
#define __LXC_UUID_H
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#include <inttypes.h>
|
||||
|
||||
typedef union lxc_id128 lxc_id128_t;
|
||||
|
||||
union lxc_id128 {
|
||||
uint8_t bytes[16];
|
||||
uint64_t qwords[2];
|
||||
}
|
||||
;
|
||||
extern int lxc_id128_randomize(lxc_id128_t *ret);
|
||||
extern int lxc_id128_write(const char *p, lxc_id128_t id);
|
||||
extern int lxc_id128_write_fd(int fd, lxc_id128_t id);
|
||||
extern char *id128_to_uuid_string(lxc_id128_t id, char s[37]);
|
||||
|
||||
#endif /* __LXC_UUID_H */
|
Loading…
Reference in New Issue
Block a user