Now doing pre_mem_read()s on the args to execve(), so eg. Memcheck can check
them. Added a regtest for this.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2244 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/vg_syscalls.c b/coregrind/vg_syscalls.c
index 5ae3cfe..f1509ad 100644
--- a/coregrind/vg_syscalls.c
+++ b/coregrind/vg_syscalls.c
@@ -1810,13 +1810,28 @@
arg2, sizeof( vki_cap_user_data_t) );
}
+// Pre_read a char** argument.
+void pre_argv_envp(Addr a, ThreadId tid, Char* s1, Char* s2)
+{
+ while (True) {
+ Addr a_deref = deref_Addr( tid, a, s1 );
+ if (0 == a_deref)
+ break;
+ SYSCALL_TRACK( pre_mem_read_asciiz, tid, s2, a_deref );
+ a += sizeof(char*);
+ }
+}
+
PRE(execve)
{
/* int execve (const char *filename,
char *const argv [],
char *const envp[]); */
- MAYBE_PRINTF("execve ( %p(%s), %p, %p ) --- NOT CHECKED\n",
- arg1, arg1, arg2, arg3);
+ MAYBE_PRINTF("execve ( %p(%s), %p, %p )\n", arg1, arg1, arg2, arg3);
+
+ SYSCALL_TRACK( pre_mem_read_asciiz, tid, "execve(filename)", arg1 );
+ pre_argv_envp( arg2, tid, "execve(argv)", "execve(argv[i])" );
+ pre_argv_envp( arg3, tid, "execve(envp)", "execve(envp[i])" );
/* Erk. If the exec fails, then the following will have made a
mess of things which makes it hard for us to continue. The
diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am
index b94f2c1..2a2c7e5 100644
--- a/memcheck/tests/Makefile.am
+++ b/memcheck/tests/Makefile.am
@@ -24,6 +24,7 @@
error_counts.stderr.exp error_counts.stdout.exp error_counts.vgtest \
errs1.stderr.exp errs1.vgtest \
exitprog.stderr.exp exitprog.vgtest \
+ execve.stderr.exp execve.vgtest \
fprw.stderr.exp fprw.vgtest \
fwrite.stderr.exp fwrite.stdout.exp fwrite.vgtest \
inits.stderr.exp inits.vgtest \
@@ -68,7 +69,8 @@
check_PROGRAMS = \
badaddrvalue badfree badjump badloop badrw brk buflen_check \
clientperm custom_alloc \
- doublefree error_counts errs1 exitprog fprw fwrite inits inline \
+ doublefree error_counts errs1 exitprog execve \
+ fprw fwrite inits inline \
malloc1 malloc2 malloc3 manuel1 manuel2 manuel3 \
memalign_test memcmptest mmaptest nanoleak new_nothrow null_socket \
overlap pushfpopf \
@@ -93,6 +95,7 @@
doublefree_SOURCES = doublefree.c
error_counts_SOURCES = error_counts.c
errs1_SOURCES = errs1.c
+execve_SOURCES = execve.c
exitprog_SOURCES = exitprog.c
fprw_SOURCES = fprw.c
fwrite_SOURCES = fwrite.c
diff --git a/memcheck/tests/execve.c b/memcheck/tests/execve.c
new file mode 100644
index 0000000..0e8222d
--- /dev/null
+++ b/memcheck/tests/execve.c
@@ -0,0 +1,12 @@
+#include <unistd.h>
+
+int main(void)
+{
+ char* bad[2] = { (char*)1, NULL };
+ char* good[1] = { NULL };
+
+ execve(NULL, bad, bad);
+ execve("/bin/true", good, good);
+
+ return 0;
+}
diff --git a/memcheck/tests/execve.stderr.exp b/memcheck/tests/execve.stderr.exp
new file mode 100644
index 0000000..aee2580
--- /dev/null
+++ b/memcheck/tests/execve.stderr.exp
@@ -0,0 +1,14 @@
+Syscall param execve(filename) contains uninitialised or unaddressable byte(s)
+ at 0x........: execve (in /...libc...)
+ by 0x........: main (execve.c:8)
+ Address 0x........ is not stack'd, malloc'd or free'd
+
+Syscall param execve(argv[i]) contains uninitialised or unaddressable byte(s)
+ at 0x........: execve (in /...libc...)
+ by 0x........: main (execve.c:8)
+ Address 0x........ is not stack'd, malloc'd or free'd
+
+Syscall param execve(envp[i]) contains uninitialised or unaddressable byte(s)
+ at 0x........: execve (in /...libc...)
+ by 0x........: main (execve.c:8)
+ Address 0x........ is not stack'd, malloc'd or free'd
diff --git a/memcheck/tests/execve.vgtest b/memcheck/tests/execve.vgtest
new file mode 100644
index 0000000..51a8d51
--- /dev/null
+++ b/memcheck/tests/execve.vgtest
@@ -0,0 +1,2 @@
+prog: execve
+vgopts: -q