There's no point in trying to interpose protected versions of the

exec family of functions.  Many modern C libraries use hidden symbols
for the functions and syscalls defined in libc such that they cannot
be overridden inside libc itself.  We have to just wrap all the exec
variants plus system and popen.
This commit is contained in:
Todd C. Miller
2015-09-28 21:20:37 -06:00
parent d5086dfde4
commit 37abc1b7e4
4 changed files with 23 additions and 412 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2004-2005, 2010-2013 Todd C. Miller <Todd.Miller@courtesan.com>
* Copyright (c) 2004-2005, 2010-2015 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -50,11 +50,10 @@ typedef struct interpose_s {
#endif
/*
* Dummy versions of the exec(3) family of syscalls. It is not enough
* to just dummy out execve(2) since some C libraries use direct syscalls
* for the other functions instead of calling execve(2). Note that it is
* still possible to access the real syscalls via the syscall(2) interface
* but very few programs actually do that.
* Dummy versions of the exec(3) family of syscalls. It is not enough to
* just dummy out execve(2) since many C libraries do not call the public
* execve(2) interface. Note that it is still possible to access the real
* syscalls via the syscall(2) interface, but that is rarely done.
*/
#define DUMMY_BODY \
@@ -102,115 +101,39 @@ DUMMY_VA(execlp, const char *, const char *)
DUMMY2(execv, const char *, char * const *)
DUMMY2(execvp, const char *, char * const *)
DUMMY3(execve, const char *, char * const *, char * const *)
DUMMY1(system, const char *)
/*
* Private versions of the above.
*/
#ifdef HAVE__EXECL
DUMMY_VA(_execl, const char *, const char *)
#endif
#ifdef HAVE___EXECL
DUMMY_VA(__execl, const char *, const char *)
#endif
#ifdef HAVE__EXECLE
DUMMY_VA(_execle, const char *, const char *)
#endif
#ifdef HAVE___EXECLE
DUMMY_VA(__execle, const char *, const char *)
#endif
#ifdef HAVE__EXECLP
DUMMY_VA(_execlp, const char *, const char *)
#endif
#ifdef HAVE___EXECLP
DUMMY_VA(__execlp, const char *, const char *)
#endif
#ifdef HAVE__EXECV
DUMMY2(_execv, const char *, char * const *)
#endif
#ifdef HAVE___EXECV
DUMMY2(__execv, const char *, char * const *)
#endif
#ifdef HAVE__EXECVP
DUMMY2(_execvp, const char *, char * const *)
#endif
#ifdef HAVE___EXECVP
DUMMY2(__execvp, const char *, char * const *)
#endif
#ifdef HAVE__EXECVE
DUMMY3(_execve, const char *, char * const *, char * const *)
#endif
#ifdef HAVE___EXECVE
DUMMY3(__execve, const char *, char * const *, char * const *)
#endif
/*
* Non-standard exec functions and corresponding private versions.
* Non-standard exec(3) functions and corresponding private versions.
*/
#ifdef HAVE_EXECVP
DUMMY3(execvP, const char *, const char *, char * const *)
#endif
#ifdef HAVE__EXECVP
DUMMY3(_execvP, const char *, const char *, char * const *)
#endif
#ifdef HAVE___EXECVP
DUMMY3(__execvP, const char *, const char *, char * const *)
#endif
#ifdef HAVE_EXECVPE
DUMMY3(execvpe, const char *, char * const *, char * const *)
#endif
#ifdef HAVE__EXECVPE
DUMMY3(_execvpe, const char *, char * const *, char * const *)
#endif
#ifdef HAVE___EXECVPE
DUMMY3(__execvpe, const char *, char * const *, char * const *)
#endif
#ifdef HAVE_EXECT
DUMMY3(exect, const char *, char * const *, char * const *)
#endif
#ifdef HAVE__EXECT
DUMMY3(_exect, const char *, char * const *, char * const *)
#endif
#ifdef HAVE___EXECT
DUMMY3(__exect, const char *, char * const *, char * const *)
#endif
/*
* Not all systems support fexecve(2), posix_spawn(2) and posix_spawnp(2).
*/
#ifdef HAVE_FEXECVE
DUMMY3(fexecve, int , char * const *, char * const *)
#endif
#ifdef HAVE__FEXECVE
DUMMY3(_fexecve, int , char * const *, char * const *)
#endif
#ifdef HAVE___FEXECVE
DUMMY3(__fexecve, int , char * const *, char * const *)
#endif
/*
* posix_spawn, posix_spawnp and any private versions.
*/
#ifdef HAVE_POSIX_SPAWN
DUMMY6(posix_spawn, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *)
#endif
#ifdef HAVE__POSIX_SPAWN
DUMMY6(_posix_spawn, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *)
#endif
#ifdef HAVE___POSIX_SPAWN
DUMMY6(__posix_spawn, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *)
#endif
#ifdef HAVE_POSIX_SPAWNP
DUMMY6(posix_spawnp, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *)
#endif
#ifdef HAVE_POSIX__SPAWNP
DUMMY6(_posix_spawnp, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *)
#endif
#ifdef HAVE_POSIX___SPAWNP
DUMMY6(__posix_spawnp, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *)
#endif
/* popen(3) returns FILE *, not int so we can't use a wrapper. */
/*
* system(3) and popen(3).
* We can't use a wrapper for popen since it returns FILE *, not int.
*/
DUMMY1(system, const char *)
__dso_public FILE *
FN_NAME(popen)(const char *c, const char *t)
{