Skip to content

Commit c1df02f

Browse files
committed
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.
1 parent 6aa223d commit c1df02f

File tree

19 files changed

+239
-55
lines changed

19 files changed

+239
-55
lines changed

core/iwasm/compilation/aot_compiler.c

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4195,13 +4195,13 @@ aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name)
41954195
bh_print_time("Begin to emit object file");
41964196

41974197
if (comp_ctx->external_llc_compiler || comp_ctx->external_asm_compiler) {
4198-
char cmd[1024];
41994198
int ret;
42004199

42014200
if (comp_ctx->external_llc_compiler) {
4202-
const char *stack_usage_flag = "";
4203-
char bc_file_name[64];
4204-
char su_file_name[65]; /* See the comment below */
4201+
char *stack_usage_flag = "";
4202+
char bc_file_name[64] = { 0 };
4203+
char su_file_name[65] = { 0 };
4204+
char *argv[10] = { 0 };
42054205

42064206
if (comp_ctx->stack_usage_file != NULL) {
42074207
/*
@@ -4229,14 +4229,16 @@ aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name)
42294229
return false;
42304230
}
42314231

4232-
snprintf(cmd, sizeof(cmd), "%s%s %s -o %s %s",
4233-
comp_ctx->external_llc_compiler, stack_usage_flag,
4234-
comp_ctx->llc_compiler_flags ? comp_ctx->llc_compiler_flags
4235-
: "-O3 -c",
4236-
file_name, bc_file_name);
4237-
LOG_VERBOSE("invoking external LLC compiler:\n\t%s", cmd);
4232+
argv[0] = stack_usage_flag;
4233+
argv[1] = comp_ctx->llc_compiler_flags
4234+
? (char *)comp_ctx->llc_compiler_flags
4235+
: "-O3 -c";
4236+
argv[2] = "-o";
4237+
argv[3] = file_name;
4238+
argv[4] = bc_file_name;
4239+
argv[5] = NULL;
42384240

4239-
ret = bh_system(cmd);
4241+
ret = os_execve(comp_ctx->external_llc_compiler, argv, 6);
42404242
/* remove temp bitcode file */
42414243
unlink(bc_file_name);
42424244

@@ -4263,7 +4265,8 @@ aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name)
42634265
}
42644266
}
42654267
else if (comp_ctx->external_asm_compiler) {
4266-
char asm_file_name[64];
4268+
char asm_file_name[64] = { 0 };
4269+
char *argv[10] = { 0 };
42674270

42684271
if (!aot_generate_tempfile_name("wamrc-asm", "s", asm_file_name,
42694272
sizeof(asm_file_name))) {
@@ -4282,14 +4285,15 @@ aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name)
42824285
return false;
42834286
}
42844287

4285-
snprintf(cmd, sizeof(cmd), "%s %s -o %s %s",
4286-
comp_ctx->external_asm_compiler,
4287-
comp_ctx->asm_compiler_flags ? comp_ctx->asm_compiler_flags
4288-
: "-O3 -c",
4289-
file_name, asm_file_name);
4290-
LOG_VERBOSE("invoking external ASM compiler:\n\t%s", cmd);
4288+
argv[0] = comp_ctx->asm_compiler_flags
4289+
? (char *)comp_ctx->asm_compiler_flags
4290+
: "-O3 -c";
4291+
argv[1] = "-o";
4292+
argv[2] = file_name;
4293+
argv[3] = asm_file_name;
4294+
argv[4] = NULL;
42914295

4292-
ret = bh_system(cmd);
4296+
ret = os_execve(comp_ctx->external_asm_compiler, argv, 5);
42934297
/* remove temp assembly file */
42944298
unlink(asm_file_name);
42954299

core/iwasm/compilation/aot_emit_aot_file.c

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4361,18 +4361,23 @@ aot_obj_data_create(AOTCompContext *comp_ctx)
43614361
else if (!strncmp(LLVMGetTargetName(target), "arc", 3)) {
43624362
/* Emit to assembly file instead for arc target
43634363
as it cannot emit to object file */
4364-
char file_name[] = "wasm-XXXXXX", buf[128];
4364+
char file_name[] = "wasm-XXXXXX";
4365+
char assembly_file_name[64] = { 0 };
4366+
char object_file_name[64] = { 0 };
43654367
int ret;
4368+
char *argv[] = { "-mcpu=arcem", "-o", object_file_name, "-c",
4369+
assembly_file_name, NULL };
43664370

43674371
if (!bh_mkstemp(file_name, sizeof(file_name))) {
43684372
aot_set_last_error("make temp file failed.");
43694373
goto fail;
43704374
}
43714375

4372-
snprintf(buf, sizeof(buf), "%s%s", file_name, ".s");
4376+
snprintf(assembly_file_name, sizeof(assembly_file_name) - 1, "%s.s",
4377+
file_name);
43734378
if (LLVMTargetMachineEmitToFile(comp_ctx->target_machine,
4374-
comp_ctx->module, buf, LLVMAssemblyFile,
4375-
&err)
4379+
comp_ctx->module, assembly_file_name,
4380+
LLVMAssemblyFile, &err)
43764381
!= 0) {
43774382
if (err) {
43784383
LLVMDisposeMessage(err);
@@ -4385,14 +4390,14 @@ aot_obj_data_create(AOTCompContext *comp_ctx)
43854390
/* call arc gcc to compile assembly file to object file */
43864391
/* TODO: get arc gcc from environment variable firstly
43874392
and check whether the toolchain exists actually */
4388-
snprintf(buf, sizeof(buf), "%s%s%s%s%s%s",
4389-
"/opt/zephyr-sdk/arc-zephyr-elf/bin/arc-zephyr-elf-gcc ",
4390-
"-mcpu=arcem -o ", file_name, ".o -c ", file_name, ".s");
4393+
snprintf(object_file_name, sizeof(object_file_name) - 1, "%s.o",
4394+
file_name);
43914395
/* TODO: use try..catch to handle possible exceptions */
4392-
ret = bh_system(buf);
4396+
/* TODO: use ZEPHYR_SDK_INSTALL_DIR to construct the path */
4397+
ret = os_execve("/opt/zephyr-sdk/arc-zephyr-elf/bin/arc-zephyr-elf-gcc",
4398+
argv, 6);
43934399
/* remove temp assembly file */
4394-
snprintf(buf, sizeof(buf), "%s%s", file_name, ".s");
4395-
unlink(buf);
4400+
unlink(assembly_file_name);
43964401

43974402
if (ret != 0) {
43984403
aot_set_last_error("failed to compile asm file to obj file "
@@ -4401,12 +4406,10 @@ aot_obj_data_create(AOTCompContext *comp_ctx)
44014406
}
44024407

44034408
/* create memory buffer from object file */
4404-
snprintf(buf, sizeof(buf), "%s%s", file_name, ".o");
4405-
ret = LLVMCreateMemoryBufferWithContentsOfFile(buf, &obj_data->mem_buf,
4406-
&err);
4409+
ret = LLVMCreateMemoryBufferWithContentsOfFile(
4410+
object_file_name, &obj_data->mem_buf, &err);
44074411
/* remove temp object file */
4408-
snprintf(buf, sizeof(buf), "%s%s", file_name, ".o");
4409-
unlink(buf);
4412+
unlink(object_file_name);
44104413

44114414
if (ret != 0) {
44124415
if (err) {

core/shared/platform/alios/alios_platform.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,10 @@ os_invalid_raw_handle(void)
8585
{
8686
return -1;
8787
}
88+
89+
int
90+
os_execve(const char *pathname, char *const argv[], int argc)
91+
{
92+
/* not implemented */
93+
return -1;
94+
}

core/shared/platform/android/platform_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include <sys/ioctl.h>
3737
#include <sys/socket.h>
3838
#include <sys/resource.h>
39+
#include <sys/wait.h>
3940
#include <android/log.h>
4041

4142
#ifdef __cplusplus
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright (C) 2019 Intel Corporation. All rights reserved.
3+
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4+
*/
5+
6+
#include "platform_api_vmcore.h"
7+
8+
int
9+
os_execve(const char *pathname, char *const argv[], int argc)
10+
{
11+
pid_t pid;
12+
int ret;
13+
/* no environment variables */
14+
char *const envp[] = { NULL };
15+
16+
if (pathname == NULL) {
17+
goto fail;
18+
}
19+
20+
if (argc > 0) {
21+
if (argv == NULL) {
22+
goto fail;
23+
}
24+
25+
/* The `argv[]` must be terminated by a NULL pointer. */
26+
if (argv[argc - 1] != NULL) {
27+
goto fail;
28+
}
29+
}
30+
31+
pid = fork();
32+
if (pid < 0) {
33+
perror("fork failed: ");
34+
goto fail;
35+
}
36+
37+
if (pid == 0) {
38+
/* child process */
39+
ret = execve(pathname, argv, envp);
40+
if (ret == -1) {
41+
perror("execve failed(from child): ");
42+
}
43+
/* _exit() for thread safe? */
44+
exit(ret);
45+
}
46+
else {
47+
/* parent process */
48+
int status;
49+
50+
ret = waitpid(pid, &status, 0);
51+
if (ret == -1) {
52+
perror("waitpid failed: ");
53+
goto fail;
54+
}
55+
56+
if (WIFEXITED(status)) {
57+
/* child terminated normally with exit code */
58+
ret = WEXITSTATUS(status);
59+
if (ret != 0) {
60+
printf("execute failed(from parent) with exit code: %d\n", ret);
61+
}
62+
}
63+
else {
64+
/*
65+
* child terminated abnormally.
66+
* include if killed or stopped by a signal
67+
*/
68+
goto fail;
69+
}
70+
}
71+
72+
return ret;
73+
fail:
74+
return -1;
75+
}

core/shared/platform/cosmopolitan/platform_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include <sys/ioctl.h>
3737
#include <sys/socket.h>
3838
#include <sys/resource.h>
39+
#include <sys/wait.h>
3940

4041
#ifdef __cplusplus
4142
extern "C" {

core/shared/platform/darwin/platform_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include <sys/ioctl.h>
3838
#include <sys/socket.h>
3939
#include <sys/resource.h>
40+
#include <sys/wait.h>
4041

4142
#ifdef __cplusplus
4243
extern "C" {

core/shared/platform/freebsd/platform_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include <sys/ioctl.h>
3737
#include <sys/socket.h>
3838
#include <sys/resource.h>
39+
#include <sys/wait.h>
3940

4041
#ifdef __cplusplus
4142
extern "C" {

core/shared/platform/include/platform_api_vmcore.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,26 @@ os_dcache_flush(void);
185185
void
186186
os_icache_flush(void *start, size_t len);
187187

188+
/*
189+
* Executes a program referred to by cmd in bash/cmd.exe
190+
* Always be sure that argv[argc-1] == NULL
191+
*
192+
* @param pathname The program to execute. need to be absolute path.
193+
* @param argv The command line arguments.
194+
* @param argc The number of command line arguments.
195+
*
196+
* like to execute "ls -l /tmp":
197+
* os_execve("/bin/ls", (char *const []){ "-l", "/tmp", NULL }, 3);
198+
*
199+
* @return 0 if success
200+
* -1 if can't execute the program or can't get exit code.
201+
* like fork() failed, execve() failed, waitpid() failed
202+
* or the program is not terminated normally(via exit() or main())
203+
* other values indicate exit code.
204+
*/
205+
int
206+
os_execve(const char *pathname, char *const argv[], int argc);
207+
188208
#ifdef __cplusplus
189209
}
190210
#endif

core/shared/platform/linux-sgx/sgx_platform.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,3 +221,10 @@ os_dcache_flush(void)
221221
void
222222
os_icache_flush(void *start, size_t len)
223223
{}
224+
225+
int
226+
os_execve(const char *pathname, char *const argv[], int argc)
227+
{
228+
/* not implemented */
229+
return -1;
230+
}

core/shared/platform/linux/platform_internal.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@
2222
#include <limits.h>
2323
#include <dirent.h>
2424
#include <fcntl.h>
25-
#include <unistd.h>
2625
#include <poll.h>
2726
#include <sched.h>
2827
#include <errno.h>
28+
#include <unistd.h>
2929
#include <netinet/in.h>
3030
#include <sys/types.h>
3131
#include <sys/stat.h>
@@ -36,6 +36,7 @@
3636
#include <sys/ioctl.h>
3737
#include <sys/socket.h>
3838
#include <sys/resource.h>
39+
#include <sys/wait.h>
3940

4041
#ifdef __cplusplus
4142
extern "C" {

core/shared/platform/nuttx/platform_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <sys/stat.h>
2828
#include <sys/time.h>
2929
#include <sys/mman.h>
30+
#include <sys/wait.h>
3031
#include <semaphore.h>
3132

3233
#ifdef __cplusplus

core/shared/platform/riot/riot_platform.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,10 @@ os_invalid_raw_handle(void)
101101
{
102102
return -1;
103103
}
104+
105+
int
106+
os_execve(const char *pathname, char *const argv[], int argc)
107+
{
108+
/* not implemented */
109+
return -1;
110+
}

core/shared/platform/rt-thread/rtt_platform.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,3 +210,10 @@ os_clock_res_get(__wasi_clockid_t clock_id, __wasi_timestamp_t *resolution)
210210
{
211211
return 0;
212212
}
213+
214+
int
215+
os_execve(const char *pathname, char *const argv[], int argc)
216+
{
217+
/* not implemented */
218+
return -1;
219+
}

core/shared/platform/vxworks/platform_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include <sys/ioctl.h>
3636
#include <sys/socket.h>
3737
#include <sys/resource.h>
38+
#include <sys/wait.h>
3839

3940
#ifdef __cplusplus
4041
extern "C" {

0 commit comments

Comments
 (0)