Bug #357833 Setting RLIMIT_DATA to zero breaks with linux 4.5+

We used to set the process datasize rlimit to zero to prevent
any internal use of brk() from having any effect. But later
linux kernels redefine RLIMIT_DATA as the size of any data
areas, including some dynamic mmap memory allocations.

See bug #357833 for the commit that went into linux 4.5
changing the definition of RLIMIT_DATA. So don't mess with
RLIMIT_DATA anymore. Just remember it for use in the syscall
wrappers.

This also cleans up some hacks around the execv and spawn wrappers.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15766
This commit is contained in:
Mark Wielaard 2016-01-21 11:37:43 +00:00
parent 0fe0da145d
commit 6072a5a3ac
5 changed files with 9 additions and 33 deletions

1
NEWS
View File

@ -58,6 +58,7 @@ where XXXXXX is the bug number as listed below.
355454 do not intercept malloc related symbols from the runtime linker
356044 Dwarf line info reader misinterprets is_stmt register
356817 valgrind.h triggers compiler errors on MSVC when defining NVALGRIND
357833 Setting RLIMIT_DATA to zero breaks with linux 4.5+
357871 pthread_spin_destroy not properly wrapped
357887 Fix a file handle leak. VG_(fclose) did not close the file
358030 support direct socket calls on x86 32bit (new in linux 4.3)

View File

@ -450,9 +450,6 @@ void VG_(execv) ( const HChar* filename, const HChar** argv )
HChar** envp;
SysRes res;
/* restore the DATA rlimit for the child */
VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
envp = VG_(env_clone)(VG_(client_envp));
VG_(env_remove_valgrind_env_stuff)( envp, True /*ro_strings*/, NULL );
@ -511,17 +508,9 @@ Int VG_(spawn) ( const HChar *filename, const HChar **argv )
# undef COPY_CHAR_TO_ARGENV
# undef COPY_STRING_TOARGENV
/* HACK: Temporarily restore the DATA rlimit for spawned child. */
VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
SysRes res = VG_(do_syscall5)(__NR_spawn, (UWord) filename, (UWord) NULL, 0,
(UWord) argenv, argenv_size);
/* Restore DATA rlimit back to its previous value set in m_main.c. */
struct vki_rlimit zero = { 0, 0 };
zero.rlim_max = VG_(client_rlimit_data).rlim_max;
VG_(setrlimit)(VKI_RLIMIT_DATA, &zero);
VG_(free)(argenv);
for (HChar **p = envp; *p != NULL; p++) {
VG_(free)(*p);

View File

@ -1627,7 +1627,6 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp )
Bool logging_to_fd = False;
const HChar* xml_fname_unexpanded = NULL;
Int loglevel, i;
struct vki_rlimit zero = { 0, 0 };
XArray* addr2dihandle = NULL;
//============================================================
@ -1800,13 +1799,15 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp )
VG_(debugLog)(1, "main", "... %s\n", VG_(name_of_launcher));
//--------------------------------------------------------------
// Get the current process datasize rlimit, and set it to zero.
// This prevents any internal uses of brk() from having any effect.
// We remember the old value so we can restore it on exec, so that
// child processes will have a reasonable brk value.
// We used to set the process datasize rlimit to zero to prevent
// any internal use of brk() from having any effect. But later
// linux kernels redefine RLIMIT_DATA as the size of any data
// areas, including some dynamic mmap memory allocations.
// See bug #357833 for the commit that went into linux 4.5
// changing the definition of RLIMIT_DATA. So don't mess with
// RLIMIT_DATA here now anymore. Just remember it for use in
// the syscall wrappers.
VG_(getrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
zero.rlim_max = VG_(client_rlimit_data).rlim_max;
VG_(setrlimit)(VKI_RLIMIT_DATA, &zero);
// Get the current process stack rlimit.
VG_(getrlimit)(VKI_RLIMIT_STACK, &VG_(client_rlimit_stack));

View File

@ -3014,9 +3014,6 @@ PRE(sys_execve)
vg_assert(j == tot_args+1);
}
/* restore the DATA rlimit for the child */
VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
/*
Set the signal state up for exec.

View File

@ -1589,21 +1589,12 @@ PRE(sys_spawn)
#undef COPY_CHAR_TO_ARGENV
#undef COPY_STRING_TOARGENV
/* HACK: Temporarily restore the DATA rlimit for spawned child.
This is a terrible hack to provide sensible brk limit for child. */
VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
/* Actual spawn() syscall. */
SysRes res = VG_(do_syscall5)(__NR_spawn, (UWord) path, (UWord) attrs,
attrs_size, (UWord) argenv, argenv_size);
SET_STATUS_from_SysRes(res);
VG_(free)(argenv);
/* Restore DATA rlimit back to its previous value set in m_main.c. */
struct vki_rlimit zero = { 0, 0 };
zero.rlim_max = VG_(client_rlimit_data).rlim_max;
VG_(setrlimit)(VKI_RLIMIT_DATA, &zero);
if (SUCCESS) {
PRINT(" spawn: process %d spawned child %ld\n", VG_(getpid)(), RES);
}
@ -3794,9 +3785,6 @@ PRE(sys_execve)
VG_(sigprocmask)(VKI_SIG_SETMASK, &tst->sig_mask, NULL);
}
/* Restore the DATA rlimit for the child. */
VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
/* Debug-only printing. */
if (0) {
HChar **cpp;