raw_syscalls: add lxc_raw_execveat()

parent 5497a52d
......@@ -22,6 +22,7 @@ noinst_HEADERS = attach.h \
macro.h \
monitor.h \
namespace.h \
raw_syscalls.h \
start.h \
state.h \
storage/btrfs.h \
......@@ -114,6 +115,7 @@ liblxc_la_SOURCES = af_unix.c af_unix.h \
network.c network.h \
monitor.c monitor.h \
parse.c parse.h \
raw_syscalls.c raw_syscalls.h \
ringbuf.c ringbuf.h \
rtnl.c rtnl.h \
state.c state.h \
......
......@@ -70,6 +70,7 @@
#include "namespace.h"
#include "network.h"
#include "parse.h"
#include "raw_syscalls.h"
#include "ringbuf.h"
#include "start.h"
#include "storage.h"
......@@ -3482,21 +3483,11 @@ static bool verify_start_hooks(struct lxc_conf *conf)
static bool execveat_supported(void)
{
#ifdef __NR_execveat
/*
* We use the syscall here, because it was introduced in kernel 3.19,
* while glibc got support for using the syscall much later, in 2.27.
* We don't want to use glibc because it falls back to /proc, and the
* container may not have /proc mounted depending on its configuration.
*/
syscall(__NR_execveat, -1, "", NULL, NULL, AT_EMPTY_PATH);
lxc_raw_execveat(-1, "", NULL, NULL, AT_EMPTY_PATH);
if (errno == ENOSYS)
return false;
return true;
#else
return false;
#endif
}
int lxc_setup(struct lxc_handler *handler)
......
......@@ -35,6 +35,7 @@
#include "config.h"
#include "log.h"
#include "start.h"
#include "raw_syscalls.h"
#include "utils.h"
lxc_log_define(execute, start);
......@@ -122,11 +123,7 @@ static int execute_start(struct lxc_handler *handler, void* data)
NOTICE("Exec'ing \"%s\"", my_args->argv[0]);
if (my_args->init_fd >= 0)
#ifdef __NR_execveat
syscall(__NR_execveat, my_args->init_fd, "", argv, environ, AT_EMPTY_PATH);
#else
ERROR("System seems to be missing execveat syscall number");
#endif
lxc_raw_execveat(my_args->init_fd, "", argv, environ, AT_EMPTY_PATH);
else
execvp(argv[0], argv);
SYSERROR("Failed to exec %s", argv[0]);
......
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/syscall.h>
#include <unistd.h>
#include "config.h"
int lxc_raw_execveat(int dirfd, const char *pathname, char *const argv[],
char *const envp[], int flags)
{
#ifdef __NR_execveat
syscall(__NR_execveat, dirfd, pathname, argv, envp, flags);
#else
errno = ENOSYS;
return -1;
#endif
}
/* 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_RAW_SYSCALL_H
#define __LXC_RAW_SYSCALL_H
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
extern int lxc_raw_execveat(int dirfd, const char *pathname, char *const argv[],
char *const envp[], int flags);
#endif /* __LXC_RAW_SYSCALL_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment