handle execveat systemcall on McKernel

Refs: #1366
Change-Id: I921e04a0df8d0d798fc94f675e5112dd2fec190a
This commit is contained in:
Ken Sato
2019-11-14 10:56:28 +09:00
parent d052acab1d
commit 7fc4272b89
10 changed files with 356 additions and 10 deletions

View File

@@ -122,6 +122,11 @@
# define CLONE_NEWNET 0x40000000 /* New network namespace. */
# define CLONE_IO 0x80000000 /* Clone I/O context. */
/* for execveat() */
#define AT_FDCWD -100
#define AT_SYMLINK_NOFOLLOW 0x100
#define AT_EMPTY_PATH 0x1000
struct user_desc {
unsigned int entry_number;
unsigned int base_addr;

View File

@@ -2493,13 +2493,11 @@ static void munmap_all(void)
return;
} /* munmap_all() */
SYSCALL_DECLARE(execve)
static int do_execveat(ihk_mc_user_context_t *ctx, int dirfd,
const char *filename, char **argv, char **envp, int flags)
{
int error;
long ret;
const char *filename = (const char *)ihk_mc_syscall_arg0(ctx);
char **argv = (char **)ihk_mc_syscall_arg1(ctx);
char **envp = (char **)ihk_mc_syscall_arg2(ctx);
char *argv_flat = NULL;
int argv_flat_len = 0;
@@ -2538,8 +2536,10 @@ SYSCALL_DECLARE(execve)
/* Request host to open executable and load ELF section descriptions */
request.number = __NR_execve;
request.args[0] = 1; /* 1st phase - get ELF desc */
request.args[1] = (unsigned long)filename;
request.args[2] = virt_to_phys(desc);
request.args[1] = dirfd;
request.args[2] = (unsigned long)filename;
request.args[3] = virt_to_phys(desc);
request.args[4] = flags;
ret = do_syscall(&request, ihk_mc_get_processor_id());
if (ret != 0) {
@@ -2626,7 +2626,7 @@ SYSCALL_DECLARE(execve)
}
/* Request host to transfer ELF image */
request.number = __NR_execve;
request.number = __NR_execve;
request.args[0] = 2; /* 2nd phase - transfer ELF image */
request.args[1] = virt_to_phys(desc);
request.args[2] = sizeof(struct program_load_desc) +
@@ -2687,6 +2687,14 @@ end:
return ret;
}
SYSCALL_DECLARE(execve)
{
return do_execveat(ctx, AT_FDCWD,
(const char *)ihk_mc_syscall_arg0(ctx),
(char **)ihk_mc_syscall_arg1(ctx),
(char **)ihk_mc_syscall_arg2(ctx), 0);
}
unsigned long do_fork(int clone_flags, unsigned long newsp,
unsigned long parent_tidptr, unsigned long child_tidptr,
unsigned long tlsblock_base, unsigned long curpc,
@@ -3569,6 +3577,39 @@ out:
return rc;
}
SYSCALL_DECLARE(execveat)
{
int dirfd = (int)ihk_mc_syscall_arg0(ctx);
const char *filename = (const char *)ihk_mc_syscall_arg1(ctx);
int flags = (int)ihk_mc_syscall_arg4(ctx);
long ret;
/* validate flags */
if ((flags & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0) {
ret = -EINVAL;
goto out;
}
if (filename[0] == '/' || dirfd == AT_FDCWD) {
/* behave same as execve */
goto exec;
}
/* validate dirfd */
if (dirfd < 0 && dirfd != AT_FDCWD) {
ret = -EBADF;
goto out;
}
exec:
ret = do_execveat(ctx, dirfd, filename,
(char **)ihk_mc_syscall_arg2(ctx),
(char **)ihk_mc_syscall_arg3(ctx), flags);
out:
return ret;
}
SYSCALL_DECLARE(close)
{
int fd = ihk_mc_syscall_arg0(ctx);