utils: add lxc_setup_keyring()

Allocate a new keyring if we can to prevent information leak.

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
This commit is contained in:
Christian Brauner 2018-09-28 13:14:25 +02:00
parent c73fbad129
commit b25291da14
No known key found for this signature in database
GPG Key ID: 8EB056D53EECB12D
6 changed files with 93 additions and 0 deletions

View File

@ -651,6 +651,10 @@ AC_CHECK_FUNCS([fgetln],
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]),

View File

@ -37,6 +37,7 @@ noinst_HEADERS = api_extensions.h \
storage/storage_utils.h \
storage/zfs.h \
string_utils.h \
syscall_wrappers.h \
terminal.h \
../tests/lxctest.h \
tools/arguments.h \
@ -132,6 +133,7 @@ liblxc_la_SOURCES = af_unix.c af_unix.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 \

View File

@ -3586,6 +3586,10 @@ int lxc_setup(struct lxc_handler *handler)
}
}
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");

View File

@ -0,0 +1,51 @@
/* 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 */

View File

@ -51,6 +51,7 @@
#include "lxclock.h"
#include "namespace.h"
#include "parse.h"
#include "syscall_wrappers.h"
#include "utils.h"
#ifndef HAVE_STRLCPY
@ -1753,3 +1754,33 @@ int recursive_destroy(char *dirname)
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;
}

View File

@ -436,5 +436,6 @@ static inline pid_t lxc_raw_gettid(void)
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 */