Allocate a new keyring if we can to prevent information leak.
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
AM_CONDITIONAL(HAVE_FGETLN, true)
AC_DEFINE(HAVE_FGETLN,1,[Have fgetln]),
AM_CONDITIONAL(HAVE_FGETLN, false))
+AC_CHECK_FUNCS([keyctl],
+ AM_CONDITIONAL(HAVE_KEYCTL, true)
+ AC_DEFINE(HAVE_KEYCTL,1,[Have keyctl]),
+ AM_CONDITIONAL(HAVE_KEYCTL, false))
AC_CHECK_FUNCS([prlimit],
AM_CONDITIONAL(HAVE_PRLIMIT, true)
AC_DEFINE(HAVE_PRLIMIT,1,[Have prlimit]),
storage/storage_utils.h \
storage/zfs.h \
string_utils.h \
+ syscall_wrappers.h \
terminal.h \
../tests/lxctest.h \
tools/arguments.h \
storage/zfs.c storage/zfs.h \
string_utils.c string_utils.h \
sync.c sync.h \
+ syscall_wrappers.h \
terminal.c \
utils.c utils.h \
version.h \
}
}
+ ret = lxc_setup_keyring();
+ if (ret < 0)
+ return -1;
+
ret = lxc_setup_network_in_child_namespaces(lxc_conf, &lxc_conf->network);
if (ret < 0) {
ERROR("Failed to setup network");
--- /dev/null
+/* liblxcapi
+ *
+ * Copyright © 2018 Christian Brauner <christian.brauner@ubuntu.com>.
+ * Copyright © 2018 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __LXC_SYSCALL_WRAPPER_H
+#define __LXC_SYSCALL_WRAPPER_H
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE 1
+#endif
+#include <asm/unistd.h>
+#include <linux/keyctl.h>
+#include <stdint.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "config.h"
+
+typedef int32_t key_serial_t;
+
+#if !HAVE_KEYCTL
+static inline long __keyctl(int cmd, unsigned long arg2, unsigned long arg3,
+ unsigned long arg4, unsigned long arg5)
+{
+#ifdef __NR_keyctl
+ return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+#define keyctl __keyctl
+#endif
+
+#endif /* __LXC_SYSCALL_WRAPPER_H */
#include "lxclock.h"
#include "namespace.h"
#include "parse.h"
+#include "syscall_wrappers.h"
#include "utils.h"
#ifndef HAVE_STRLCPY
return r;
}
+
+int lxc_setup_keyring(void)
+{
+ key_serial_t keyring;
+ int ret = 0;
+
+ /* Try to allocate a new session keyring for the container to prevent
+ * information leaks.
+ */
+ keyring = keyctl(KEYCTL_JOIN_SESSION_KEYRING, prctl_arg(0),
+ prctl_arg(0), prctl_arg(0), prctl_arg(0));
+ if (keyring < 0) {
+ switch (errno) {
+ case ENOSYS:
+ DEBUG("The keyctl() syscall is not supported or blocked");
+ break;
+ case EACCES:
+ __fallthrough;
+ case EPERM:
+ DEBUG("Failed to access kernel keyring. Continuing...");
+ break;
+ default:
+ SYSERROR("Failed to create kernel keyring");
+ ret = -1;
+ break;
+ }
+ }
+
+ return ret;
+}
extern int lxc_set_death_signal(int signal);
extern int fd_cloexec(int fd, bool cloexec);
extern int recursive_destroy(char *dirname);
+extern int lxc_setup_keyring(void);
#endif /* __LXC_UTILS_H */