Compare commits

...

2 Commits

Author SHA1 Message Date
liang.he
86be34c387
Merge c1df02fddb into 5478d267f4 2025-06-12 10:52:13 +08:00
liang.he@intel.com
c1df02fddb Use execve() to replace system() and rename to os_execve()
- Direct Execution: execve() directly executes a program, bypassing the shell.
  This avoids vulnerabilities like shell injection, which can occur with
  system() if user input is not properly sanitized.
- Controlled Environment: With execve(), you can explicitly specify the
  environment variables for the new process, providing better control over
  the execution context.
- No Shell Overhead: execve() does not invoke a shell, reducing the risk
  of unintended behavior caused by shell features or configurations.
- Predictable Behavior: execve() only executes the specified program, whereas
  system() relies on the shell, which may interpret commands differently
  based on the shell's configuration or environment.
2025-05-09 09:33:15 +00:00
19 changed files with 239 additions and 55 deletions

View File

@ -4202,13 +4202,13 @@ aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name)
bh_print_time("Begin to emit object file"); bh_print_time("Begin to emit object file");
if (comp_ctx->external_llc_compiler || comp_ctx->external_asm_compiler) { if (comp_ctx->external_llc_compiler || comp_ctx->external_asm_compiler) {
char cmd[1024];
int ret; int ret;
if (comp_ctx->external_llc_compiler) { if (comp_ctx->external_llc_compiler) {
const char *stack_usage_flag = ""; char *stack_usage_flag = "";
char bc_file_name[64]; char bc_file_name[64] = { 0 };
char su_file_name[65]; /* See the comment below */ char su_file_name[65] = { 0 };
char *argv[10] = { 0 };
if (comp_ctx->stack_usage_file != NULL) { if (comp_ctx->stack_usage_file != NULL) {
/* /*
@ -4236,14 +4236,16 @@ aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name)
return false; return false;
} }
snprintf(cmd, sizeof(cmd), "%s%s %s -o %s %s", argv[0] = stack_usage_flag;
comp_ctx->external_llc_compiler, stack_usage_flag, argv[1] = comp_ctx->llc_compiler_flags
comp_ctx->llc_compiler_flags ? comp_ctx->llc_compiler_flags ? (char *)comp_ctx->llc_compiler_flags
: "-O3 -c", : "-O3 -c";
file_name, bc_file_name); argv[2] = "-o";
LOG_VERBOSE("invoking external LLC compiler:\n\t%s", cmd); argv[3] = file_name;
argv[4] = bc_file_name;
argv[5] = NULL;
ret = bh_system(cmd); ret = os_execve(comp_ctx->external_llc_compiler, argv, 6);
/* remove temp bitcode file */ /* remove temp bitcode file */
unlink(bc_file_name); unlink(bc_file_name);
@ -4270,7 +4272,8 @@ aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name)
} }
} }
else if (comp_ctx->external_asm_compiler) { else if (comp_ctx->external_asm_compiler) {
char asm_file_name[64]; char asm_file_name[64] = { 0 };
char *argv[10] = { 0 };
if (!aot_generate_tempfile_name("wamrc-asm", "s", asm_file_name, if (!aot_generate_tempfile_name("wamrc-asm", "s", asm_file_name,
sizeof(asm_file_name))) { sizeof(asm_file_name))) {
@ -4289,14 +4292,15 @@ aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name)
return false; return false;
} }
snprintf(cmd, sizeof(cmd), "%s %s -o %s %s", argv[0] = comp_ctx->asm_compiler_flags
comp_ctx->external_asm_compiler, ? (char *)comp_ctx->asm_compiler_flags
comp_ctx->asm_compiler_flags ? comp_ctx->asm_compiler_flags : "-O3 -c";
: "-O3 -c", argv[1] = "-o";
file_name, asm_file_name); argv[2] = file_name;
LOG_VERBOSE("invoking external ASM compiler:\n\t%s", cmd); argv[3] = asm_file_name;
argv[4] = NULL;
ret = bh_system(cmd); ret = os_execve(comp_ctx->external_asm_compiler, argv, 5);
/* remove temp assembly file */ /* remove temp assembly file */
unlink(asm_file_name); unlink(asm_file_name);

View File

@ -4361,18 +4361,23 @@ aot_obj_data_create(AOTCompContext *comp_ctx)
else if (!strncmp(LLVMGetTargetName(target), "arc", 3)) { else if (!strncmp(LLVMGetTargetName(target), "arc", 3)) {
/* Emit to assembly file instead for arc target /* Emit to assembly file instead for arc target
as it cannot emit to object file */ as it cannot emit to object file */
char file_name[] = "wasm-XXXXXX", buf[128]; char file_name[] = "wasm-XXXXXX";
char assembly_file_name[64] = { 0 };
char object_file_name[64] = { 0 };
int ret; int ret;
char *argv[] = { "-mcpu=arcem", "-o", object_file_name, "-c",
assembly_file_name, NULL };
if (!bh_mkstemp(file_name, sizeof(file_name))) { if (!bh_mkstemp(file_name, sizeof(file_name))) {
aot_set_last_error("make temp file failed."); aot_set_last_error("make temp file failed.");
goto fail; goto fail;
} }
snprintf(buf, sizeof(buf), "%s%s", file_name, ".s"); snprintf(assembly_file_name, sizeof(assembly_file_name) - 1, "%s.s",
file_name);
if (LLVMTargetMachineEmitToFile(comp_ctx->target_machine, if (LLVMTargetMachineEmitToFile(comp_ctx->target_machine,
comp_ctx->module, buf, LLVMAssemblyFile, comp_ctx->module, assembly_file_name,
&err) LLVMAssemblyFile, &err)
!= 0) { != 0) {
if (err) { if (err) {
LLVMDisposeMessage(err); LLVMDisposeMessage(err);
@ -4385,14 +4390,14 @@ aot_obj_data_create(AOTCompContext *comp_ctx)
/* call arc gcc to compile assembly file to object file */ /* call arc gcc to compile assembly file to object file */
/* TODO: get arc gcc from environment variable firstly /* TODO: get arc gcc from environment variable firstly
and check whether the toolchain exists actually */ and check whether the toolchain exists actually */
snprintf(buf, sizeof(buf), "%s%s%s%s%s%s", snprintf(object_file_name, sizeof(object_file_name) - 1, "%s.o",
"/opt/zephyr-sdk/arc-zephyr-elf/bin/arc-zephyr-elf-gcc ", file_name);
"-mcpu=arcem -o ", file_name, ".o -c ", file_name, ".s");
/* TODO: use try..catch to handle possible exceptions */ /* TODO: use try..catch to handle possible exceptions */
ret = bh_system(buf); /* TODO: use ZEPHYR_SDK_INSTALL_DIR to construct the path */
ret = os_execve("/opt/zephyr-sdk/arc-zephyr-elf/bin/arc-zephyr-elf-gcc",
argv, 6);
/* remove temp assembly file */ /* remove temp assembly file */
snprintf(buf, sizeof(buf), "%s%s", file_name, ".s"); unlink(assembly_file_name);
unlink(buf);
if (ret != 0) { if (ret != 0) {
aot_set_last_error("failed to compile asm file to obj file " aot_set_last_error("failed to compile asm file to obj file "
@ -4401,12 +4406,10 @@ aot_obj_data_create(AOTCompContext *comp_ctx)
} }
/* create memory buffer from object file */ /* create memory buffer from object file */
snprintf(buf, sizeof(buf), "%s%s", file_name, ".o"); ret = LLVMCreateMemoryBufferWithContentsOfFile(
ret = LLVMCreateMemoryBufferWithContentsOfFile(buf, &obj_data->mem_buf, object_file_name, &obj_data->mem_buf, &err);
&err);
/* remove temp object file */ /* remove temp object file */
snprintf(buf, sizeof(buf), "%s%s", file_name, ".o"); unlink(object_file_name);
unlink(buf);
if (ret != 0) { if (ret != 0) {
if (err) { if (err) {

View File

@ -85,3 +85,10 @@ os_invalid_raw_handle(void)
{ {
return -1; return -1;
} }
int
os_execve(const char *pathname, char *const argv[], int argc)
{
/* not implemented */
return -1;
}

View File

@ -36,6 +36,7 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/wait.h>
#include <android/log.h> #include <android/log.h>
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -0,0 +1,75 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "platform_api_vmcore.h"
int
os_execve(const char *pathname, char *const argv[], int argc)
{
pid_t pid;
int ret;
/* no environment variables */
char *const envp[] = { NULL };
if (pathname == NULL) {
goto fail;
}
if (argc > 0) {
if (argv == NULL) {
goto fail;
}
/* The `argv[]` must be terminated by a NULL pointer. */
if (argv[argc - 1] != NULL) {
goto fail;
}
}
pid = fork();
if (pid < 0) {
perror("fork failed: ");
goto fail;
}
if (pid == 0) {
/* child process */
ret = execve(pathname, argv, envp);
if (ret == -1) {
perror("execve failed(from child): ");
}
/* _exit() for thread safe? */
exit(ret);
}
else {
/* parent process */
int status;
ret = waitpid(pid, &status, 0);
if (ret == -1) {
perror("waitpid failed: ");
goto fail;
}
if (WIFEXITED(status)) {
/* child terminated normally with exit code */
ret = WEXITSTATUS(status);
if (ret != 0) {
printf("execute failed(from parent) with exit code: %d\n", ret);
}
}
else {
/*
* child terminated abnormally.
* include if killed or stopped by a signal
*/
goto fail;
}
}
return ret;
fail:
return -1;
}

View File

@ -36,6 +36,7 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/wait.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

View File

@ -37,6 +37,7 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/wait.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

View File

@ -36,6 +36,7 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/wait.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

View File

@ -185,6 +185,26 @@ os_dcache_flush(void);
void void
os_icache_flush(void *start, size_t len); os_icache_flush(void *start, size_t len);
/*
* Executes a program referred to by cmd in bash/cmd.exe
* Always be sure that argv[argc-1] == NULL
*
* @param pathname The program to execute. need to be absolute path.
* @param argv The command line arguments.
* @param argc The number of command line arguments.
*
* like to execute "ls -l /tmp":
* os_execve("/bin/ls", (char *const []){ "-l", "/tmp", NULL }, 3);
*
* @return 0 if success
* -1 if can't execute the program or can't get exit code.
* like fork() failed, execve() failed, waitpid() failed
* or the program is not terminated normally(via exit() or main())
* other values indicate exit code.
*/
int
os_execve(const char *pathname, char *const argv[], int argc);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -221,3 +221,10 @@ os_dcache_flush(void)
void void
os_icache_flush(void *start, size_t len) os_icache_flush(void *start, size_t len)
{} {}
int
os_execve(const char *pathname, char *const argv[], int argc)
{
/* not implemented */
return -1;
}

View File

@ -22,10 +22,10 @@
#include <limits.h> #include <limits.h>
#include <dirent.h> #include <dirent.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h>
#include <poll.h> #include <poll.h>
#include <sched.h> #include <sched.h>
#include <errno.h> #include <errno.h>
#include <unistd.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -36,6 +36,7 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/wait.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

View File

@ -27,6 +27,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/wait.h>
#include <semaphore.h> #include <semaphore.h>
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -101,3 +101,10 @@ os_invalid_raw_handle(void)
{ {
return -1; return -1;
} }
int
os_execve(const char *pathname, char *const argv[], int argc)
{
/* not implemented */
return -1;
}

View File

@ -210,3 +210,10 @@ os_clock_res_get(__wasi_clockid_t clock_id, __wasi_timestamp_t *resolution)
{ {
return 0; return 0;
} }
int
os_execve(const char *pathname, char *const argv[], int argc)
{
/* not implemented */
return -1;
}

View File

@ -35,6 +35,7 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/wait.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

View File

@ -72,8 +72,66 @@ os_getpagesize()
void void
os_dcache_flush(void) os_dcache_flush(void)
{} {
}
void void
os_icache_flush(void *start, size_t len) os_icache_flush(void *start, size_t len)
{} {
}
int
os_execve(const char *pathname, char *const argv[], int argc)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
DWORD exit_code;
int ret;
if (pathname == NULL) {
goto fail;
}
if (argc > 0) {
if (argv == NULL) {
goto fail;
}
/* The `argv[]` must be terminated by a NULL pointer. */
if (argv[argc - 1] != NULL) {
goto fail;
}
}
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
if (!CreateProcess(pathname, (LPSTR)argv[0],
/* security attributes */
NULL, NULL,
/* not inherited handlers */
FALSE,
/* creation flags */
0,
/* not use parent's environment */
NULL,
/* not use parent's directory */
NULL, &si, &pi)) {
printf("CreateProcess failed: %d\n", GetLastError());
goto fail;
}
WaitForSingleObject(pi.hProcess, INFINITE);
if (!GetExitCodeProcess(pi.hProcess, &exit_code)) {
printf("GetExitCodeProcess failed: %d\n", GetLastError());
goto fail;
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return exit_code;
fail:
return -1;
}

View File

@ -261,3 +261,10 @@ os_invalid_raw_handle(void)
{ {
return -1; return -1;
} }
int
os_execve(const char *pathname, char *const argv[], int argc)
{
/* not implemented */
return -1;
}

View File

@ -167,20 +167,6 @@ wa_strdup(const char *s)
} }
#if WASM_ENABLE_WAMR_COMPILER != 0 || WASM_ENABLE_JIT != 0 #if WASM_ENABLE_WAMR_COMPILER != 0 || WASM_ENABLE_JIT != 0
int
bh_system(const char *cmd)
{
int ret;
#if !(defined(_WIN32) || defined(_WIN32_))
ret = system(cmd);
#else
ret = _spawnlp(_P_WAIT, "cmd.exe", "/c", cmd, NULL);
#endif
return ret;
}
#if defined(_WIN32) || defined(_WIN32_) #if defined(_WIN32) || defined(_WIN32_)
errno_t errno_t
_mktemp_s(char *nameTemplate, size_t sizeInChars); _mktemp_s(char *nameTemplate, size_t sizeInChars);

View File

@ -67,10 +67,6 @@ char *
wa_strdup(const char *s); wa_strdup(const char *s);
#if WASM_ENABLE_WAMR_COMPILER != 0 || WASM_ENABLE_JIT != 0 #if WASM_ENABLE_WAMR_COMPILER != 0 || WASM_ENABLE_JIT != 0
/* Executes a system command in bash/cmd.exe */
int
bh_system(const char *cmd);
/* Tests whether can create a temporary file with the given name */ /* Tests whether can create a temporary file with the given name */
bool bool
bh_mkstemp(char *filename, size_t name_len); bh_mkstemp(char *filename, size_t name_len);