[lxc-devel] [lxc/master] start: generate new boot id on container start

brauner on Github lxc-bot at linuxcontainers.org
Wed Jun 5 22:08:44 UTC 2019


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 511 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190605/b9154994/attachment-0001.bin>
-------------- next part --------------
From 45df601362e601e0f74b87dec8d64acd2ddf0544 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 5 Jun 2019 23:43:53 +0200
Subject: [PATCH] start: generate new boot id on container start

Closes #3027.

BugLink: https://bugs.launchpad.net/bugs/1831258
Cc: Dimitri John Ledkov <xnox at ubuntu.com>
Cc: Scott Moser <smoser at ubuntu.com>
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/Makefile.am |   4 +-
 src/lxc/conf.c      |  37 +++++++++++
 src/lxc/uuid.c      | 145 ++++++++++++++++++++++++++++++++++++++++++++
 src/lxc/uuid.h      |  44 ++++++++++++++
 4 files changed, 229 insertions(+), 1 deletion(-)
 create mode 100644 src/lxc/uuid.c
 create mode 100644 src/lxc/uuid.h

diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am
index b868d530eb..49b3b014d1 100644
--- a/src/lxc/Makefile.am
+++ b/src/lxc/Makefile.am
@@ -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)
 
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 0fbbbfa797..450d8aa09f 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -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,34 @@ 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))
+		return -1;
+
+	ret = lxc_id128_write(mock_boot_id_path, n);
+	if (ret < 0)
+		return -1;
+
+	ret = mount(mock_boot_id_path, boot_id_path, NULL, MS_BIND, NULL);
+	if (ret < 0)
+		return -1;
+
+	return mount(NULL, boot_id_path, NULL,
+		     (MS_BIND | MS_REMOUNT | MS_RDONLY | MS_NOSUID | MS_NOEXEC |
+		      MS_NODEV),
+		     NULL);
+}
+
 int lxc_setup(struct lxc_handler *handler)
 {
 	int ret;
@@ -3645,6 +3674,14 @@ int lxc_setup(struct lxc_handler *handler)
 		return -1;
 	}
 
+	if (lxc_conf->autodev > 0) {
+		ret = lxc_setup_boot_id();
+		if (ret < 0) {
+			ERROR("Failed to create new boot id");
+			return -1;
+		}
+	}
+
 	ret = lxc_setup_devpts(lxc_conf);
 	if (ret < 0) {
 		ERROR("Failed to setup new devpts instance");
diff --git a/src/lxc/uuid.c b/src/lxc/uuid.c
new file mode 100644
index 0000000000..5f94c37abe
--- /dev/null
+++ b/src/lxc/uuid.c
@@ -0,0 +1,145 @@
+/* liblxcapi
+ *
+ * Copyright © 2019 Christian Brauner <christian.brauner at 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 "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 = write(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);
+}
diff --git a/src/lxc/uuid.h b/src/lxc/uuid.h
new file mode 100644
index 0000000000..c9b04a3bf8
--- /dev/null
+++ b/src/lxc/uuid.h
@@ -0,0 +1,44 @@
+/* liblxcapi
+ *
+ * Copyright © 2019 Christian Brauner <christian.brauner at 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 */


More information about the lxc-devel mailing list