--- embedaddon/sudo/src/sudo_noexec.c 2013/07/22 10:46:13 1.1.1.4 +++ embedaddon/sudo/src/sudo_noexec.c 2013/10/14 07:56:35 1.1.1.5 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2005, 2010-2012 Todd C. Miller + * Copyright (c) 2004-2005, 2010-2013 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -20,20 +20,43 @@ #include #include +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ #ifdef HAVE_SPAWN_H #include #endif #include "missing.h" +#ifdef HAVE___INTERPOSE /* - * Dummy versions of the execve() family of syscalls. We don't need - * to stub out all of them, just the ones that correspond to actual - * system calls (which varies by OS). Note that it is still possible - * to access the real syscalls via the syscall() interface but very - * few programs actually do that. + * Mac OS X 10.4 and above has support for library symbol interposition. + * There is a good explanation of this in the Mac OS X Internals book. */ +typedef struct interpose_s { + void *new_func; + void *orig_func; +} interpose_t; +# define FN_NAME(fn) dummy_ ## fn +# define INTERPOSE(fn) \ + __attribute__((__used__)) static const interpose_t interpose_ ## fn \ + __attribute__((__section__("__DATA,__interpose"))) = \ + { (void *)dummy_ ## fn, (void *)fn }; +#else +# define FN_NAME(fn) fn +# define INTERPOSE(fn) +#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. + */ + #define DUMMY_BODY \ { \ errno = EACCES; \ @@ -42,59 +65,140 @@ #define DUMMY2(fn, t1, t2) \ __dso_public int \ -fn(t1 a1, t2 a2) \ -DUMMY_BODY +FN_NAME(fn)(t1 a1, t2 a2) \ +DUMMY_BODY \ +INTERPOSE(fn) #define DUMMY3(fn, t1, t2, t3) \ __dso_public int \ -fn(t1 a1, t2 a2, t3 a3) \ -DUMMY_BODY +FN_NAME(fn)(t1 a1, t2 a2, t3 a3) \ +DUMMY_BODY \ +INTERPOSE(fn) #define DUMMY6(fn, t1, t2, t3, t4, t5, t6) \ __dso_public int \ -fn(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \ -DUMMY_BODY +FN_NAME(fn)(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \ +DUMMY_BODY \ +INTERPOSE(fn) #define DUMMY_VA(fn, t1, t2) \ __dso_public int \ -fn(t1 a1, t2 a2, ...) \ -DUMMY_BODY +FN_NAME(fn)(t1 a1, t2 a2, ...) \ +DUMMY_BODY \ +INTERPOSE(fn) +/* + * Standard exec(3) family of functions. + */ DUMMY_VA(execl, const char *, const char *) +DUMMY_VA(execle, const char *, const char *) +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 *) + +/* + * 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 *) -DUMMY_VA(execle, 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 *) -DUMMY_VA(execlp, 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 *) -DUMMY3(exect, const char *, char * const *, char * const *) -DUMMY3(_exect, const char *, char * const *, char * const *) -DUMMY3(__exect, const char *, char * const *, char * const *) -DUMMY2(execv, const char *, char * const *) +#endif +#ifdef HAVE__EXECV DUMMY2(_execv, const char *, char * const *) +#endif +#ifdef HAVE___EXECV DUMMY2(__execv, const char *, char * const *) -DUMMY2(execvp, 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. + */ +#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 *) -DUMMY3(execve, const char *, char * const *, char * const *) -DUMMY3(_execve, const char *, char * const *, char * const *) -DUMMY3(__execve, 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___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 + +#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 *) -#ifdef HAVE_SPAWN_H +#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 /* HAVE_SPAWN_H */ +#endif