mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-07-27 14:30:32 +00:00
rexec: make rexecution opt-in for library callers
We cannot rexecute the liblxc shared library unconditionally as this would break most of our downstreams. Here are some scenarios: - anyone performing a dlopen() on the shared library (e.g. users of the LXC Python bindings) - LXD as it needs to know the absolute path to its own executable based on /proc/self/exe etc. This commit makes the rexecution of liblxc conditional on whether the LXC_MEMFD_REXEC environment variable is set or not. If it is then liblxc is unconditionally rexecuted. The only relevant attack vector exists for lxc-attach which we simply reexecute unconditionally. Reported-by: Stéphane Graber <stgraber@ubuntu.com> Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
This commit is contained in:
parent
b88ccedc1e
commit
d3a9befc86
@ -25,6 +25,7 @@ noinst_HEADERS = api_extensions.h \
|
|||||||
monitor.h \
|
monitor.h \
|
||||||
namespace.h \
|
namespace.h \
|
||||||
raw_syscalls.h \
|
raw_syscalls.h \
|
||||||
|
rexec.h \
|
||||||
start.h \
|
start.h \
|
||||||
state.h \
|
state.h \
|
||||||
storage/btrfs.h \
|
storage/btrfs.h \
|
||||||
@ -180,7 +181,7 @@ liblxc_la_SOURCES += ../include/strlcat.c ../include/strlcat.h
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
if ENFORCE_MEMFD_REXEC
|
if ENFORCE_MEMFD_REXEC
|
||||||
liblxc_la_SOURCES += rexec.c
|
liblxc_la_SOURCES += rexec.c rexec.h
|
||||||
endif
|
endif
|
||||||
|
|
||||||
AM_CFLAGS = -DLXCROOTFSMOUNT=\"$(LXCROOTFSMOUNT)\" \
|
AM_CFLAGS = -DLXCROOTFSMOUNT=\"$(LXCROOTFSMOUNT)\" \
|
||||||
@ -307,6 +308,7 @@ LDADD = liblxc.la \
|
|||||||
|
|
||||||
if ENABLE_TOOLS
|
if ENABLE_TOOLS
|
||||||
lxc_attach_SOURCES = tools/lxc_attach.c \
|
lxc_attach_SOURCES = tools/lxc_attach.c \
|
||||||
|
rexec.c rexec.h \
|
||||||
tools/arguments.c tools/arguments.h
|
tools/arguments.c tools/arguments.h
|
||||||
lxc_autostart_SOURCES = tools/lxc_autostart.c \
|
lxc_autostart_SOURCES = tools/lxc_autostart.c \
|
||||||
tools/arguments.c tools/arguments.h
|
tools/arguments.c tools/arguments.h
|
||||||
|
@ -142,7 +142,7 @@ on_error:
|
|||||||
errno = saved_errno;
|
errno = saved_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lxc_rexec(const char *memfd_name)
|
int lxc_rexec(const char *memfd_name)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
char **argv = NULL, **envp = NULL;
|
char **argv = NULL, **envp = NULL;
|
||||||
@ -179,7 +179,7 @@ static int lxc_rexec(const char *memfd_name)
|
|||||||
*/
|
*/
|
||||||
__attribute__((constructor)) static void liblxc_rexec(void)
|
__attribute__((constructor)) static void liblxc_rexec(void)
|
||||||
{
|
{
|
||||||
if (lxc_rexec("liblxc")) {
|
if (getenv("LXC_MEMFD_REXEC") && lxc_rexec("liblxc")) {
|
||||||
fprintf(stderr, "Failed to re-execute liblxc via memory file descriptor\n");
|
fprintf(stderr, "Failed to re-execute liblxc via memory file descriptor\n");
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
26
src/lxc/rexec.h
Normal file
26
src/lxc/rexec.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __LXC_REXEC_H
|
||||||
|
#define __LXC_REXEC_H
|
||||||
|
|
||||||
|
extern int lxc_rexec(const char *memfd_name);
|
||||||
|
|
||||||
|
#endif /* __LXC_REXEC_H */
|
@ -44,10 +44,28 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "confile.h"
|
#include "confile.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "rexec.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
lxc_log_define(lxc_attach, lxc);
|
lxc_log_define(lxc_attach, lxc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will copy any binary that calls liblxc into a memory file and
|
||||||
|
* will use the memfd to rexecute the binary. This is done to prevent attacks
|
||||||
|
* through the /proc/self/exe symlink to corrupt the host binary when host and
|
||||||
|
* container are in the same user namespace or have set up an identity id
|
||||||
|
* mapping: CVE-2019-5736.
|
||||||
|
*/
|
||||||
|
#ifdef ENFORCE_MEMFD_REXEC
|
||||||
|
__attribute__((constructor)) static void lxc_attach_rexec(void)
|
||||||
|
{
|
||||||
|
if (!getenv("LXC_MEMFD_REXEC") && lxc_rexec("lxc-attach")) {
|
||||||
|
fprintf(stderr, "Failed to re-execute lxc-attach via memory file descriptor\n");
|
||||||
|
_exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int my_parser(struct lxc_arguments *args, int c, char *arg);
|
static int my_parser(struct lxc_arguments *args, int c, char *arg);
|
||||||
static int add_to_simple_array(char ***array, ssize_t *capacity, char *value);
|
static int add_to_simple_array(char ***array, ssize_t *capacity, char *value);
|
||||||
static bool stdfd_is_pty(void);
|
static bool stdfd_is_pty(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user