From: Paul Floyd Date: Sun, 14 Nov 2021 21:06:14 +0000 (+0100) Subject: Bug 444925 fexecve syscall wrapper not properly implemented X-Git-Tag: VALGRIND_3_19_0~80 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=83dda2b71a75bd0058ed50a32ec871b083a96f91;p=thirdparty%2Fvalgrind.git Bug 444925 fexecve syscall wrapper not properly implemented Implement fexecve and a few testcases on FreeBSD. --- diff --git a/.gitignore b/.gitignore index 770d08c278..5ab4d74ebe 100644 --- a/.gitignore +++ b/.gitignore @@ -1330,6 +1330,7 @@ /memcheck/tests/freebsd/get_set_context /memcheck/tests/freebsd/utimes /memcheck/tests/freebsd/static_allocs +/memcheck/tests/freebsd/fexecve # /memcheck/tests/amd64-freebsd /memcheck/tests/amd64-freebsd/*.stderr.diff @@ -2051,6 +2052,8 @@ /none/tests/freebsd/auxv /none/tests/freebsd/osrel /none/tests/freebsd/swapcontext +/none/tests/freebsd/fexecve +/none/tests/freebsd/hello_world # /none/tests/x86/ /none/tests/x86/*.dSYM diff --git a/coregrind/m_libcfile.c b/coregrind/m_libcfile.c index 598027c6d9..5f9c76efe5 100644 --- a/coregrind/m_libcfile.c +++ b/coregrind/m_libcfile.c @@ -179,6 +179,34 @@ Bool VG_(resolve_filename) ( Int fd, const HChar** result ) # endif } +#if defined(VGO_freebsd) + +/* This should only be called after a successful call to + * Bool VG_(resolve_filename) ( Int fd, const HChar** result ) + * so that filedesc_buf is still valid for fd */ +Bool VG_(resolve_filemode) ( Int fd, Int * result ) +{ + Char *bp, *eb; + struct vki_kinfo_file *kf; + + /* Walk though the list. */ + bp = filedesc_buf; + eb = filedesc_buf + sizeof(filedesc_buf); + while (bp < eb) { + kf = (struct vki_kinfo_file *)bp; + if (kf->kf_fd == fd) + break; + bp += kf->kf_structsize; + } + if (bp >= eb) + *result = -1; + else + *result = kf->kf_flags; + return True; +} +#endif + + SysRes VG_(mknod) ( const HChar* pathname, Int mode, UWord dev ) { # if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) diff --git a/coregrind/m_syswrap/priv_syswrap-generic.h b/coregrind/m_syswrap/priv_syswrap-generic.h index c50b313999..5d2709adb7 100644 --- a/coregrind/m_syswrap/priv_syswrap-generic.h +++ b/coregrind/m_syswrap/priv_syswrap-generic.h @@ -127,9 +127,15 @@ void handle_sys_pwritev(ThreadId tid, SyscallStatus* status, Int fd, Addr vector, Int count, const char *str); +typedef enum { + EXECVE, + EXECVEAT, + FEXECVE +} ExecveType; + extern void handle_pre_sys_execve(ThreadId tid, SyscallStatus *status, Addr pathname, - Addr arg_2, Addr arg_3, Bool is_execveat, + Addr arg_2, Addr arg_3, ExecveType execveType, Bool check_pathptr); DECL_TEMPLATE(generic, sys_ni_syscall); // * P -- unimplemented diff --git a/coregrind/m_syswrap/syswrap-freebsd.c b/coregrind/m_syswrap/syswrap-freebsd.c index 77f5b30dd6..6dbf48d557 100644 --- a/coregrind/m_syswrap/syswrap-freebsd.c +++ b/coregrind/m_syswrap/syswrap-freebsd.c @@ -4898,11 +4898,77 @@ PRE(sys_fexecve) { PRINT("sys_fexecve ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", SARG1,ARG2,ARG3); - PRE_REG_READ3(long, "fexecve", + PRE_REG_READ3(int, "fexecve", int, fd, char * const *, argv, char * const *, envp); - PRE_MEM_RASCIIZ( "fexecve(argv)", ARG2 ); - PRE_MEM_RASCIIZ( "fexecve(envp)", ARG3 ); + + if (!ML_(fd_allowed)(ARG1, "fexecve", tid, False)) { + SET_STATUS_Failure(VKI_EBADF); + return; + } + + const HChar *fname; + + if (VG_(resolve_filename)(ARG1, &fname) == False) { + SET_STATUS_Failure(VKI_ENOENT); + return; + } + + struct vg_stat stats; + if (VG_(fstat)(ARG1, &stats) != 0) { + SET_STATUS_Failure(VKI_EACCES); + return; + } + + Int openFlags; + + if (VG_(resolve_filemode)(ARG1, &openFlags) == False) { + SET_STATUS_Failure(VKI_ENOENT); + return; + } + + /* + * openFlags is in kernel FFLAGS format + * (see /usr/include/sys/fcntl.h) + * which alllows us to tell if RDONLY is set + * + */ + + Bool isScript = False; + + SysRes res; + res = VG_(open)(fname, VKI_O_RDONLY, + VKI_S_IRUSR|VKI_S_IRGRP|VKI_S_IROTH); + if (sr_isError(res)) { + SET_STATUS_Failure(VKI_ENOENT); + return; + } else { + char buf[2]; + VG_(read)((Int)sr_Res(res), buf, 2); + VG_(close)((Int)sr_Res(res)); + if (buf[0] == '#' && buf[1] == '!') + { + isScript = True; + } + } + + if (isScript) { + if (!(openFlags & VKI_FREAD)) { + SET_STATUS_Failure(VKI_EACCES); + return; + } + } else { + if (!((openFlags & VKI_O_EXEC) || + (stats.mode & (VKI_S_IXUSR|VKI_S_IXGRP|VKI_S_IXOTH)))) { + SET_STATUS_Failure(VKI_EACCES); + return; + } + } + + Addr arg_2 = (Addr)ARG2; + Addr arg_3 = (Addr)ARG3; + + handle_pre_sys_execve(tid, status, (Addr)fname, arg_2, arg_3, FEXECVE, False); } // SYS_freebsd11_fstatat 493 diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c index b1b982cc4a..bc3fa6fe9f 100644 --- a/coregrind/m_syswrap/syswrap-generic.c +++ b/coregrind/m_syswrap/syswrap-generic.c @@ -2919,7 +2919,7 @@ void VG_(reap_threads)(ThreadId self) /* This handles the common part of the PRE macro for execve and execveat. */ void handle_pre_sys_execve(ThreadId tid, SyscallStatus *status, Addr pathname, - Addr arg_2, Addr arg_3, Bool is_execveat, + Addr arg_2, Addr arg_3, ExecveType execveType, Bool check_pathptr) { HChar* path = NULL; /* path to executable */ @@ -2934,10 +2934,19 @@ void handle_pre_sys_execve(ThreadId tid, SyscallStatus *status, Addr pathname, const char *str; char str2[30], str3[30]; - if (is_execveat) - str = "execveat"; - else - str = "execve"; + switch (execveType) { + case EXECVE: + str = "execve"; + break; + case EXECVEAT: + str = "execveat"; + break; + case FEXECVE: + str = "fexecve"; + break; + default: + vg_assert(False); + } VG_(strcpy)(str2, str); VG_(strcpy)(str3, str); @@ -3230,7 +3239,7 @@ PRE(sys_execve) Addr arg_2 = (Addr)ARG2; Addr arg_3 = (Addr)ARG3; - handle_pre_sys_execve(tid, status, (Addr)pathname, arg_2, arg_3, 0, True); + handle_pre_sys_execve(tid, status, (Addr)pathname, arg_2, arg_3, EXECVE, True); } PRE(sys_access) diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index 50203eca09..ac2a9f0c36 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -13332,7 +13332,7 @@ PRE(sys_execveat) return; } - handle_pre_sys_execve(tid, status, (Addr) path, arg_2, arg_3, 1, + handle_pre_sys_execve(tid, status, (Addr) path, arg_2, arg_3, EXECVEAT, check_pathptr); /* The exec failed, we keep running... cleanup. */ diff --git a/coregrind/pub_core_libcfile.h b/coregrind/pub_core_libcfile.h index 28f3e8c960..56289a494c 100644 --- a/coregrind/pub_core_libcfile.h +++ b/coregrind/pub_core_libcfile.h @@ -44,6 +44,11 @@ extern Int VG_(fcntl) ( Int fd, Int cmd, Addr arg ); /* Convert an fd into a filename */ extern Bool VG_(resolve_filename) ( Int fd, const HChar** buf ); +#if defined(VGO_freebsd) +/* get the flags used to obtain an fd */ +extern Bool VG_(resolve_filemode) ( Int fd, Int * result ); +#endif + /* Return the size of a file, or -1 in case of error */ extern Long VG_(fsize) ( Int fd ); diff --git a/include/vki/vki-freebsd.h b/include/vki/vki-freebsd.h index 4cf7b5aebb..b0036679ed 100644 --- a/include/vki/vki-freebsd.h +++ b/include/vki/vki-freebsd.h @@ -1536,11 +1536,17 @@ struct vki_dirent { #define VKI_O_WRONLY O_WRONLY #define VKI_O_RDWR O_RDWR +#define VKI_FREAD FREAD +#define VKI_WRITE WRITE + #define VKI_O_NONBLOCK O_NONBLOCK #define VKI_O_APPEND O_APPEND #define VKI_O_CREAT O_CREAT #define VKI_O_TRUNC O_TRUNC #define VKI_O_EXCL O_EXCL +#define VKI_O_DIRECTORY O_DIRECTORY +#define VKI_O_EXEC O_EXEC +#define VKI_O_SEARCH O_EXEC #define VKI_AT_FDCWD AT_FDCWD diff --git a/memcheck/tests/freebsd/Makefile.am b/memcheck/tests/freebsd/Makefile.am index d0e6c6cc25..f72cc2720e 100644 --- a/memcheck/tests/freebsd/Makefile.am +++ b/memcheck/tests/freebsd/Makefile.am @@ -71,14 +71,16 @@ EXTRA_DIST = \ utimes.stderr.exp-x86 \ utimes.stderr.exp \ static_allocs.vgtest \ - static_allocs.stderr.exp + static_allocs.stderr.exp \ + fexecve.vgtest \ + fexecve.stderr.exp check_PROGRAMS = \ statfs pdfork_pdkill getfsstat inlinfo inlinfo_nested.so extattr \ sigwait chflags get_set_login revoke scalar capsicum getfh \ linkat scalar_fork scalar_thr_exit scalar_abort2 scalar_pdfork \ scalar_vfork stat file_locking_wait6 utimens access chmod_chown \ - misc get_set_context utimes static_allocs + misc get_set_context utimes static_allocs fexecve AM_CFLAGS += $(AM_FLAG_M3264_PRI) AM_CXXFLAGS += $(AM_FLAG_M3264_PRI) diff --git a/memcheck/tests/freebsd/fexecve.c b/memcheck/tests/freebsd/fexecve.c new file mode 100644 index 0000000000..6fe62ed597 --- /dev/null +++ b/memcheck/tests/freebsd/fexecve.c @@ -0,0 +1,34 @@ +#include // open +#include // perror +#include // strdup +#include // exit +#include // fexecve + +int main(int argc, char **argv, char** envp) +{ + char *exe = "/usr/bin/true"; + + int fd = open(exe, O_RDONLY); + if (-1 == fd) + { + perror("open failed:"); + exit(-1); + } + char ** new_argv = malloc(2*sizeof(char *)); + char ** new_envp = malloc(2*sizeof(char *)); + char * arg1 = strdup("./fexecve"); + char * env1 = strdup("FOO=bar"); + int * new_fd = malloc(sizeof(int)); + *new_fd += fd; + new_argv[1] = new_envp[1] = NULL; + argv[0] = arg1; + envp[0] = env1; + + free(arg1); + free(env1); + if (-1 == fexecve(*new_fd, new_argv, new_envp)) + { + perror("fexecv failed:"); + exit(-1); + } +} diff --git a/memcheck/tests/freebsd/fexecve.stderr.exp b/memcheck/tests/freebsd/fexecve.stderr.exp new file mode 100644 index 0000000000..1b4da10d00 --- /dev/null +++ b/memcheck/tests/freebsd/fexecve.stderr.exp @@ -0,0 +1,18 @@ +Syscall param fexecve(fd) contains uninitialised byte(s) + at 0x........: fexecve (in /...libc...) + by 0x........: main (fexecve.c:29) + +Syscall param fexecve(argv) points to uninitialised byte(s) + at 0x........: fexecve (in /...libc...) + by 0x........: main (fexecve.c:29) + Address 0x........ is 0 bytes inside a block of size 16 alloc'd + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (fexecve.c:17) + +Syscall param fexecve(envp) points to uninitialised byte(s) + at 0x........: fexecve (in /...libc...) + by 0x........: main (fexecve.c:29) + Address 0x........ is 0 bytes inside a block of size 16 alloc'd + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (fexecve.c:18) + diff --git a/memcheck/tests/freebsd/fexecve.vgtest b/memcheck/tests/freebsd/fexecve.vgtest new file mode 100644 index 0000000000..2ba2b646ca --- /dev/null +++ b/memcheck/tests/freebsd/fexecve.vgtest @@ -0,0 +1,2 @@ +prog: fexecve +vgopts: -q diff --git a/memcheck/tests/freebsd/scalar.stderr.exp b/memcheck/tests/freebsd/scalar.stderr.exp index 7f0227083b..3f16d12d61 100644 --- a/memcheck/tests/freebsd/scalar.stderr.exp +++ b/memcheck/tests/freebsd/scalar.stderr.exp @@ -3941,14 +3941,6 @@ Syscall param fexecve(argv) contains uninitialised byte(s) Syscall param fexecve(envp) contains uninitialised byte(s) ... -Syscall param fexecve(argv) points to unaddressable byte(s) - ... - Address 0x........ is not stack'd, malloc'd or (recently) free'd - -Syscall param fexecve(envp) points to unaddressable byte(s) - ... - Address 0x........ is not stack'd, malloc'd or (recently) free'd - --------------------------------------------------------- 493: SYS_freebsd11_fstatat 4s 2m --------------------------------------------------------- diff --git a/memcheck/tests/freebsd/scalar.stderr.exp-freebsd130 b/memcheck/tests/freebsd/scalar.stderr.exp-freebsd130 index 3dabebaea8..3a74760bd5 100644 --- a/memcheck/tests/freebsd/scalar.stderr.exp-freebsd130 +++ b/memcheck/tests/freebsd/scalar.stderr.exp-freebsd130 @@ -3941,14 +3941,6 @@ Syscall param fexecve(argv) contains uninitialised byte(s) Syscall param fexecve(envp) contains uninitialised byte(s) ... -Syscall param fexecve(argv) points to unaddressable byte(s) - ... - Address 0x........ is not stack'd, malloc'd or (recently) free'd - -Syscall param fexecve(envp) points to unaddressable byte(s) - ... - Address 0x........ is not stack'd, malloc'd or (recently) free'd - --------------------------------------------------------- 493: SYS_freebsd11_fstatat 4s 2m --------------------------------------------------------- diff --git a/memcheck/tests/freebsd/scalar.stderr.exp-freebsd130-x86 b/memcheck/tests/freebsd/scalar.stderr.exp-freebsd130-x86 index 5770eb5f58..8d587d4537 100644 --- a/memcheck/tests/freebsd/scalar.stderr.exp-freebsd130-x86 +++ b/memcheck/tests/freebsd/scalar.stderr.exp-freebsd130-x86 @@ -3972,14 +3972,6 @@ Syscall param fexecve(argv) contains uninitialised byte(s) Syscall param fexecve(envp) contains uninitialised byte(s) ... -Syscall param fexecve(argv) points to unaddressable byte(s) - ... - Address 0x........ is not stack'd, malloc'd or (recently) free'd - -Syscall param fexecve(envp) points to unaddressable byte(s) - ... - Address 0x........ is not stack'd, malloc'd or (recently) free'd - --------------------------------------------------------- 493: SYS_freebsd11_fstatat 4s 2m --------------------------------------------------------- diff --git a/memcheck/tests/freebsd/scalar.stderr.exp-x86 b/memcheck/tests/freebsd/scalar.stderr.exp-x86 index 3679c1cae7..b949dbb7e8 100644 --- a/memcheck/tests/freebsd/scalar.stderr.exp-x86 +++ b/memcheck/tests/freebsd/scalar.stderr.exp-x86 @@ -3972,14 +3972,6 @@ Syscall param fexecve(argv) contains uninitialised byte(s) Syscall param fexecve(envp) contains uninitialised byte(s) ... -Syscall param fexecve(argv) points to unaddressable byte(s) - ... - Address 0x........ is not stack'd, malloc'd or (recently) free'd - -Syscall param fexecve(envp) points to unaddressable byte(s) - ... - Address 0x........ is not stack'd, malloc'd or (recently) free'd - --------------------------------------------------------- 493: SYS_freebsd11_fstatat 4s 2m --------------------------------------------------------- diff --git a/none/tests/freebsd/Makefile.am b/none/tests/freebsd/Makefile.am index dbcf32465e..f3dabc9a9b 100644 --- a/none/tests/freebsd/Makefile.am +++ b/none/tests/freebsd/Makefile.am @@ -1,7 +1,7 @@ include $(top_srcdir)/Makefile.tool-tests.am -dist_noinst_SCRIPTS = filter_stderr +dist_noinst_SCRIPTS = filter_stderr test.sh EXTRA_DIST = \ auxv.vgtest \ auxv.stderr.exp \ @@ -12,10 +12,23 @@ EXTRA_DIST = \ osrel.stdout.exp \ swapcontext.vgtest \ swapcontext.stderr.exp \ - swapcontext.stdout.exp + swapcontext.stdout.exp \ + fexecve_hw1.vgtest \ + fexecve_hw1.stdout.exp \ + fexecve_hw1.stderr.exp \ + fexecve_hw2.vgtest \ + fexecve_hw2.stdout.exp \ + fexecve_hw2.stderr.exp \ + fexecve_script1.vgtest \ + fexecve_script1.stderr.exp \ + fexecve_script2.vgtest \ + fexecve_script2.stdout.exp \ + fexecve_script2.stderr.exp \ + fexecve_txt.vgtest \ + fexecve_txt.stderr.exp check_PROGRAMS = \ - auxv osrel swapcontext + auxv osrel swapcontext hello_world fexecve AM_CFLAGS += $(AM_FLAG_M3264_PRI) AM_CXXFLAGS += $(AM_FLAG_M3264_PRI) @@ -24,3 +37,4 @@ auxv_CFLAGS = ${AM_CFLAGS} osrel_CFLAGS = ${AM_CFLAGS} swapcontext_CFLAGS = ${AM_CFLAGS} +hello_world_SOURCES = hello_world.cpp diff --git a/none/tests/freebsd/fexecve.c b/none/tests/freebsd/fexecve.c new file mode 100644 index 0000000000..d91f090d04 --- /dev/null +++ b/none/tests/freebsd/fexecve.c @@ -0,0 +1,53 @@ +#include // open +#include // perror +#include // getopt +#include // exit + +int main(int argc, char **argv, char** envp) +{ + char *exe = "./hello_world"; + int open_flags = 0; + int opt; + + while ((opt = getopt(argc, argv, "erst")) != -1) + { + switch (opt) + { + case 'e': + open_flags |= O_EXEC; + break; + case 'r': + open_flags |= O_RDONLY; + break; + case 's': + exe = "./test.sh"; + break; + case 't': + exe = "./fexecve.c"; + break; + default: + fprintf(stderr, "bad usage, options are\n" + "\texec flag\t-e\n" + "\trdonly flag\t-r\n" + "\texec script\t-s\n" + "\ntext file\n-t"); + exit(-1); + } + } + + int fd = open(exe, open_flags); + if (-1 == fd) + { + perror("open failed:"); + exit(-1); + } + char *new_argv[] = { + exe, + NULL + }; + if (-1 == fexecve(fd, new_argv, envp)) + { + perror("fexecv failed:"); + exit(-1); + } +} diff --git a/none/tests/freebsd/fexecve_hw1.stderr.exp b/none/tests/freebsd/fexecve_hw1.stderr.exp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/none/tests/freebsd/fexecve_hw1.stdout.exp b/none/tests/freebsd/fexecve_hw1.stdout.exp new file mode 100644 index 0000000000..428e0de9af --- /dev/null +++ b/none/tests/freebsd/fexecve_hw1.stdout.exp @@ -0,0 +1 @@ +Compiled Hello, World! diff --git a/none/tests/freebsd/fexecve_hw1.vgtest b/none/tests/freebsd/fexecve_hw1.vgtest new file mode 100644 index 0000000000..9f6bca7267 --- /dev/null +++ b/none/tests/freebsd/fexecve_hw1.vgtest @@ -0,0 +1,5 @@ +prereq: test -e hello_world +prog: fexecve +args: -r -e +vgopts: -q + diff --git a/none/tests/freebsd/fexecve_hw2.stderr.exp b/none/tests/freebsd/fexecve_hw2.stderr.exp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/none/tests/freebsd/fexecve_hw2.stdout.exp b/none/tests/freebsd/fexecve_hw2.stdout.exp new file mode 100644 index 0000000000..428e0de9af --- /dev/null +++ b/none/tests/freebsd/fexecve_hw2.stdout.exp @@ -0,0 +1 @@ +Compiled Hello, World! diff --git a/none/tests/freebsd/fexecve_hw2.vgtest b/none/tests/freebsd/fexecve_hw2.vgtest new file mode 100644 index 0000000000..386d398bf7 --- /dev/null +++ b/none/tests/freebsd/fexecve_hw2.vgtest @@ -0,0 +1,5 @@ +prereq: test -e hello_world +prog: fexecve +args: -e +vgopts: -q + diff --git a/none/tests/freebsd/fexecve_script1.stderr.exp b/none/tests/freebsd/fexecve_script1.stderr.exp new file mode 100644 index 0000000000..1de0dc20b7 --- /dev/null +++ b/none/tests/freebsd/fexecve_script1.stderr.exp @@ -0,0 +1 @@ +fexecv failed:: Permission denied diff --git a/none/tests/freebsd/fexecve_script1.vgtest b/none/tests/freebsd/fexecve_script1.vgtest new file mode 100644 index 0000000000..a6c3124a40 --- /dev/null +++ b/none/tests/freebsd/fexecve_script1.vgtest @@ -0,0 +1,4 @@ +prog: fexecve +args: -r -e -s +vgopts: -q + diff --git a/none/tests/freebsd/fexecve_script2.stderr.exp b/none/tests/freebsd/fexecve_script2.stderr.exp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/none/tests/freebsd/fexecve_script2.stdout.exp b/none/tests/freebsd/fexecve_script2.stdout.exp new file mode 100644 index 0000000000..cd79766ac0 --- /dev/null +++ b/none/tests/freebsd/fexecve_script2.stdout.exp @@ -0,0 +1 @@ +Script Hello, World! diff --git a/none/tests/freebsd/fexecve_script2.vgtest b/none/tests/freebsd/fexecve_script2.vgtest new file mode 100644 index 0000000000..fb65f76536 --- /dev/null +++ b/none/tests/freebsd/fexecve_script2.vgtest @@ -0,0 +1,4 @@ +prog: fexecve +args: -r -s +vgopts: -q + diff --git a/none/tests/freebsd/fexecve_txt.stderr.exp b/none/tests/freebsd/fexecve_txt.stderr.exp new file mode 100644 index 0000000000..1de0dc20b7 --- /dev/null +++ b/none/tests/freebsd/fexecve_txt.stderr.exp @@ -0,0 +1 @@ +fexecv failed:: Permission denied diff --git a/none/tests/freebsd/fexecve_txt.vgtest b/none/tests/freebsd/fexecve_txt.vgtest new file mode 100644 index 0000000000..0c52b7421c --- /dev/null +++ b/none/tests/freebsd/fexecve_txt.vgtest @@ -0,0 +1,4 @@ +prog: fexecve +args: -r -t +vgopts: -q + diff --git a/none/tests/freebsd/hello_world.cpp b/none/tests/freebsd/hello_world.cpp new file mode 100644 index 0000000000..f5648b97a6 --- /dev/null +++ b/none/tests/freebsd/hello_world.cpp @@ -0,0 +1,6 @@ +#include + +int main() +{ + std::cout << "Compiled Hello, World!\n"; +} diff --git a/none/tests/freebsd/test.sh b/none/tests/freebsd/test.sh new file mode 100755 index 0000000000..51b25d60ec --- /dev/null +++ b/none/tests/freebsd/test.sh @@ -0,0 +1,2 @@ +#!/bin/sh +echo Script Hello, World!