diff options
-rw-r--r-- | ChangeLog.txt | 3 | ||||
-rw-r--r-- | doc/program_flow | 16 | ||||
-rw-r--r-- | guts/clone.c | 20 | ||||
-rw-r--r-- | guts/fork.c | 27 | ||||
-rw-r--r-- | pseudo_wrappers.c | 322 | ||||
-rw-r--r-- | templates/wrapfuncs.c | 60 |
6 files changed, 214 insertions, 234 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt index 9832e4a..0c942e7 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,3 +1,6 @@ +2010-12-14: + * (mhatle) restructure wrapfuncs.c + 2010-12-09: * (mhatle) Add doc/program_flow to attempt to explain startup/running * (mhatle) guts/* minor cleanup diff --git a/doc/program_flow b/doc/program_flow index b0680a0..8991681 100644 --- a/doc/program_flow +++ b/doc/program_flow @@ -37,7 +37,7 @@ libpseudo execution flow: fork() clone() - pseudo_populate_wrappers(): + pseudo_check_wrappers(): pseudo_reinit_libpseudo if necessary call wrap_exec*() if !PSEUDO_RELOADED @@ -49,7 +49,19 @@ libpseudo execution flow: pseudo_dropenv() real_*() - ... normal function wrappers ... + ... normal function wrappers ... (templates/wrapfuncs.c): + pseudo_check_wrappers() || !real_* + return enosys + variadic setup (if necessary) + if pseudo_disabled return real_*() + pseudo_sigblock + pseudo_getlock + if antimagic rc = real_*() + else rc = wrap_*() + variadic end (if necessary) + pseudo_droplock + unmask signals + return rc pseudo execution flow: pseudo.c: main() diff --git a/guts/clone.c b/guts/clone.c index 8299c54..b3400c7 100644 --- a/guts/clone.c +++ b/guts/clone.c @@ -12,21 +12,15 @@ * undo it later. UGH! */ pseudo_debug(1, "client resetting for clone(2) call\n"); - if (real_clone) { - if (!pseudo_get_value("PSEUDO_RELOADED")) { - pseudo_setupenv(); - pseudo_reinit_libpseudo(); - } else { - pseudo_setupenv(); - pseudo_dropenv(); - } - /* call the real syscall */ - rc = (*real_clone)(fn, child_stack, flags, arg, pid, tls, ctid); + if (!pseudo_get_value("PSEUDO_RELOADED")) { + pseudo_setupenv(); + pseudo_reinit_libpseudo(); } else { - /* rc was initialized to the "failure" value */ - pseudo_enosys("clone"); + pseudo_setupenv(); + pseudo_dropenv(); } - + /* call the real syscall */ + rc = (*real_clone)(fn, child_stack, flags, arg, pid, tls, ctid); /* ... * return rc; * } diff --git a/guts/fork.c b/guts/fork.c index b7fd239..76cac6f 100644 --- a/guts/fork.c +++ b/guts/fork.c @@ -6,23 +6,18 @@ * wrap_fork(void) { * int rc = -1; */ - if (real_fork) { - rc = real_fork(); - /* special case: we may want to enable or disable - * pseudo in the child process - */ - if (rc == 0) { - if (!pseudo_get_value("PSEUDO_RELOADED")) { - pseudo_setupenv(); - pseudo_reinit_libpseudo(); - } else { - pseudo_setupenv(); - pseudo_dropenv(); - } + rc = real_fork(); + /* special case: we may want to enable or disable + * pseudo in the child process + */ + if (rc == 0) { + if (!pseudo_get_value("PSEUDO_RELOADED")) { + pseudo_setupenv(); + pseudo_reinit_libpseudo(); + } else { + pseudo_setupenv(); + pseudo_dropenv(); } - } else { - /* rc was initialized to the "failure" value */ - pseudo_enosys("fork"); } /* return rc; * } diff --git a/pseudo_wrappers.c b/pseudo_wrappers.c index 414cc05..470206a 100644 --- a/pseudo_wrappers.c +++ b/pseudo_wrappers.c @@ -252,6 +252,12 @@ execl(const char *file, const char *arg, ...) { int rc = -1; + if (!pseudo_check_wrappers()) { + /* rc was initialized to the "failure" value */ + pseudo_enosys("execl"); + return rc; + } + va_start(ap, arg); argv = execl_to_v(ap, arg, 0); va_end(ap); @@ -267,29 +273,20 @@ execl(const char *file, const char *arg, ...) { sigprocmask(SIG_SETMASK, &saved, NULL); return -1; } - if (pseudo_check_wrappers()) { - int save_errno; - /* exec*() use this to restore the sig mask */ - pseudo_saved_sigmask = saved; - rc = wrap_execv(file, argv); + int save_errno; - save_errno = errno; - pseudo_droplock(); - sigprocmask(SIG_SETMASK, &saved, NULL); - pseudo_debug(4, "completed: execl\n"); - errno = save_errno; - free(argv); - return rc; - } else { - pseudo_droplock(); - sigprocmask(SIG_SETMASK, &saved, NULL); - pseudo_debug(4, "completed: execl\n"); - /* rc was initialized to the "failure" value */ - pseudo_enosys("execl"); - free(argv); - return rc; - } + /* exec*() use this to restore the sig mask */ + pseudo_saved_sigmask = saved; + rc = wrap_execv(file, argv); + + save_errno = errno; + pseudo_droplock(); + sigprocmask(SIG_SETMASK, &saved, NULL); + pseudo_debug(4, "completed: execl\n"); + errno = save_errno; + free(argv); + return rc; } int @@ -300,6 +297,12 @@ execlp(const char *file, const char *arg, ...) { int rc = -1; + if (!pseudo_check_wrappers()) { + /* rc was initialized to the "failure" value */ + pseudo_enosys("execlp"); + return rc; + } + va_start(ap, arg); argv = execl_to_v(ap, arg, 0); va_end(ap); @@ -315,29 +318,20 @@ execlp(const char *file, const char *arg, ...) { sigprocmask(SIG_SETMASK, &saved, NULL); return -1; } - if (pseudo_check_wrappers()) { - int save_errno; - /* exec*() use this to restore the sig mask */ - pseudo_saved_sigmask = saved; - rc = wrap_execvp(file, argv); + int save_errno; - save_errno = errno; - pseudo_droplock(); - sigprocmask(SIG_SETMASK, &saved, NULL); - pseudo_debug(4, "completed: execlp\n"); - errno = save_errno; - free(argv); - return rc; - } else { - pseudo_droplock(); - sigprocmask(SIG_SETMASK, &saved, NULL); - pseudo_debug(4, "completed: execlp\n"); - /* rc was initialized to the "failure" value */ - pseudo_enosys("execlp"); - free(argv); - return rc; - } + /* exec*() use this to restore the sig mask */ + pseudo_saved_sigmask = saved; + rc = wrap_execvp(file, argv); + + save_errno = errno; + pseudo_droplock(); + sigprocmask(SIG_SETMASK, &saved, NULL); + pseudo_debug(4, "completed: execlp\n"); + errno = save_errno; + free(argv); + return rc; } int @@ -349,6 +343,12 @@ execle(const char *file, const char *arg, ...) { int rc = -1; + if (!pseudo_check_wrappers()) { + /* rc was initialized to the "failure" value */ + pseudo_enosys("execle"); + return rc; + } + va_start(ap, arg); argv = execl_to_v(ap, arg, (char *const **)&envp); va_end(ap); @@ -364,29 +364,20 @@ execle(const char *file, const char *arg, ...) { sigprocmask(SIG_SETMASK, &saved, NULL); return -1; } - if (pseudo_check_wrappers()) { - int save_errno; - /* exec*() use this to restore the sig mask */ - pseudo_saved_sigmask = saved; - rc = wrap_execve(file, argv, envp); + int save_errno; - save_errno = errno; - pseudo_droplock(); - sigprocmask(SIG_SETMASK, &saved, NULL); - pseudo_debug(4, "completed: execle\n"); - errno = save_errno; - free(argv); - return rc; - } else { - pseudo_droplock(); - sigprocmask(SIG_SETMASK, &saved, NULL); - pseudo_debug(4, "completed: execle\n"); - /* rc was initialized to the "failure" value */ - pseudo_enosys("execle"); - free(argv); - return rc; - } + /* exec*() use this to restore the sig mask */ + pseudo_saved_sigmask = saved; + rc = wrap_execve(file, argv, envp); + + save_errno = errno; + pseudo_droplock(); + sigprocmask(SIG_SETMASK, &saved, NULL); + pseudo_debug(4, "completed: execle\n"); + errno = save_errno; + free(argv); + return rc; } int @@ -395,6 +386,12 @@ execv(const char *file, char *const *argv) { int rc = -1; + if (!pseudo_check_wrappers() || !real_execv) { + /* rc was initialized to the "failure" value */ + pseudo_enosys("execv"); + return rc; + } + pseudo_debug(4, "called: execv\n"); pseudo_sigblock(&saved); if (pseudo_getlock()) { @@ -402,28 +399,19 @@ execv(const char *file, char *const *argv) { sigprocmask(SIG_SETMASK, &saved, NULL); return -1; } - if (pseudo_check_wrappers()) { - int save_errno; + + int save_errno; - /* exec*() use this to restore the sig mask */ - pseudo_saved_sigmask = saved; - rc = wrap_execv(file, argv); - - save_errno = errno; - pseudo_droplock(); - sigprocmask(SIG_SETMASK, &saved, NULL); - pseudo_debug(4, "completed: execv\n"); - errno = save_errno; - return rc; - } else { - pseudo_droplock(); - sigprocmask(SIG_SETMASK, &saved, NULL); - pseudo_debug(4, "completed: execv\n"); - /* rc was initialized to the "failure" value */ - pseudo_enosys("execv"); + /* exec*() use this to restore the sig mask */ + pseudo_saved_sigmask = saved; + rc = wrap_execv(file, argv); - return rc; - } + save_errno = errno; + pseudo_droplock(); + sigprocmask(SIG_SETMASK, &saved, NULL); + pseudo_debug(4, "completed: execv\n"); + errno = save_errno; + return rc; } int @@ -432,6 +420,12 @@ execve(const char *file, char *const *argv, char *const *envp) { int rc = -1; + if (!pseudo_check_wrappers() || !real_execve) { + /* rc was initialized to the "failure" value */ + pseudo_enosys("execve"); + return rc; + } + pseudo_debug(4, "called: execve\n"); pseudo_sigblock(&saved); if (pseudo_getlock()) { @@ -439,28 +433,19 @@ execve(const char *file, char *const *argv, char *const *envp) { sigprocmask(SIG_SETMASK, &saved, NULL); return -1; } - if (pseudo_check_wrappers()) { - int save_errno; + + int save_errno; - /* exec*() use this to restore the sig mask */ - pseudo_saved_sigmask = saved; - rc = wrap_execve(file, argv, envp); - - save_errno = errno; - pseudo_droplock(); - sigprocmask(SIG_SETMASK, &saved, NULL); - pseudo_debug(4, "completed: execve\n"); - errno = save_errno; - return rc; - } else { - pseudo_droplock(); - sigprocmask(SIG_SETMASK, &saved, NULL); - pseudo_debug(4, "completed: execve\n"); - /* rc was initialized to the "failure" value */ - pseudo_enosys("execve"); + /* exec*() use this to restore the sig mask */ + pseudo_saved_sigmask = saved; + rc = wrap_execve(file, argv, envp); - return rc; - } + save_errno = errno; + pseudo_droplock(); + sigprocmask(SIG_SETMASK, &saved, NULL); + pseudo_debug(4, "completed: execve\n"); + errno = save_errno; + return rc; } int @@ -469,6 +454,12 @@ execvp(const char *file, char *const *argv) { int rc = -1; + if (!pseudo_check_wrappers() || !real_execvp) { + /* rc was initialized to the "failure" value */ + pseudo_enosys("execvp"); + return rc; + } + pseudo_debug(4, "called: execvp\n"); pseudo_sigblock(&saved); if (pseudo_getlock()) { @@ -476,28 +467,19 @@ execvp(const char *file, char *const *argv) { sigprocmask(SIG_SETMASK, &saved, NULL); return -1; } - if (pseudo_check_wrappers()) { - int save_errno; + + int save_errno; - /* exec*() use this to restore the sig mask */ - pseudo_saved_sigmask = saved; - rc = wrap_execvp(file, argv); - - save_errno = errno; - pseudo_droplock(); - sigprocmask(SIG_SETMASK, &saved, NULL); - pseudo_debug(4, "completed: execvp\n"); - errno = save_errno; - return rc; - } else { - pseudo_droplock(); - sigprocmask(SIG_SETMASK, &saved, NULL); - pseudo_debug(4, "completed: execvp\n"); - /* rc was initialized to the "failure" value */ - pseudo_enosys("execvp"); + /* exec*() use this to restore the sig mask */ + pseudo_saved_sigmask = saved; + rc = wrap_execvp(file, argv); - return rc; - } + save_errno = errno; + pseudo_droplock(); + sigprocmask(SIG_SETMASK, &saved, NULL); + pseudo_debug(4, "completed: execvp\n"); + errno = save_errno; + return rc; } int @@ -506,6 +488,12 @@ fork(void) { int rc = -1; + if (!pseudo_check_wrappers() || !real_fork) { + /* rc was initialized to the "failure" value */ + pseudo_enosys("fork"); + return rc; + } + pseudo_debug(4, "called: fork\n"); pseudo_sigblock(&saved); if (pseudo_getlock()) { @@ -513,27 +501,18 @@ fork(void) { sigprocmask(SIG_SETMASK, &saved, NULL); return -1; } - if (pseudo_check_wrappers()) { - int save_errno; + + int save_errno; - rc = wrap_fork(); + rc = wrap_fork(); - save_errno = errno; - - pseudo_droplock(); - sigprocmask(SIG_SETMASK, &saved, NULL); - pseudo_debug(4, "completed: fork\n"); - errno = save_errno; - return rc; - } else { - pseudo_droplock(); - sigprocmask(SIG_SETMASK, &saved, NULL); - pseudo_debug(4, "completed: fork\n"); - /* rc was initialized to the "failure" value */ - pseudo_enosys("fork"); + save_errno = errno; - return rc; - } + pseudo_droplock(); + sigprocmask(SIG_SETMASK, &saved, NULL); + pseudo_debug(4, "completed: fork\n"); + errno = save_errno; + return rc; } int @@ -554,6 +533,12 @@ clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...) { int rc = -1; + if (!pseudo_check_wrappers() || !real_clone) { + /* rc was initialized to the "failure" value */ + pseudo_enosys("clone"); + return rc; + } + va_start(ap, arg); pid = va_arg(ap, pid_t *); tls = va_arg(ap, struct user_desc *); @@ -567,47 +552,40 @@ clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...) { sigprocmask(SIG_SETMASK, &saved, NULL); return -1; } - if (pseudo_check_wrappers()) { - int save_errno; - int save_disabled = pseudo_disabled; - /* because clone() doesn't actually continue in this function, we - * can't check the return and fix up environment variables in the - * child. Instead, we have to temporarily do any fixup, then possibly - * undo it later. UGH! - */ + + int save_errno; + int save_disabled = pseudo_disabled; + /* because clone() doesn't actually continue in this function, we + * can't check the return and fix up environment variables in the + * child. Instead, we have to temporarily do any fixup, then possibly + * undo it later. UGH! + */ #include "guts/clone.c" - if (save_disabled != pseudo_disabled) { - if (pseudo_disabled) { - pseudo_disabled = 0; - pseudo_magic(); - } else { - pseudo_disabled = 1; - pseudo_antimagic(); - } + if (save_disabled != pseudo_disabled) { + if (pseudo_disabled) { + pseudo_disabled = 0; + pseudo_magic(); + } else { + pseudo_disabled = 1; + pseudo_antimagic(); } - - save_errno = errno; - pseudo_droplock(); - sigprocmask(SIG_SETMASK, &saved, NULL); - pseudo_debug(4, "completed: clone\n"); - errno = save_errno; - return rc; - } else { - pseudo_droplock(); - sigprocmask(SIG_SETMASK, &saved, NULL); - pseudo_debug(4, "completed: clone\n"); - /* rc was initialized to the "failure" value */ - pseudo_enosys("clone"); - - return rc; } + + save_errno = errno; + pseudo_droplock(); + sigprocmask(SIG_SETMASK, &saved, NULL); + pseudo_debug(4, "completed: clone\n"); + errno = save_errno; + return rc; } +#if 0 static int (*real_execlp)(const char *file, const char *arg, ...) = NULL; static int (*real_execl)(const char *file, const char *arg, ...) = NULL; static int (*real_execle)(const char *file, const char *arg, ...) = NULL; +#endif static int (*real_execv)(const char *file, char *const *argv) = NULL; static int (*real_execve)(const char *file, char *const *argv, char *const *envp) = NULL; static int (*real_execvp)(const char *file, char *const *argv) = NULL; diff --git a/templates/wrapfuncs.c b/templates/wrapfuncs.c index 61065c5..0a90efd 100644 --- a/templates/wrapfuncs.c +++ b/templates/wrapfuncs.c @@ -21,8 +21,20 @@ ${name}(${decl_args}) { ${variadic_decl} ${rc_decl} + if (!pseudo_check_wrappers() || !real_$name) { + /* rc was initialized to the "failure" value */ + pseudo_enosys("${name}"); + ${rc_return} + } + ${variadic_start} + if (pseudo_disabled) { + ${rc_assign} (*real_${name})(${call_args}); + ${variadic_end} + ${rc_return} + } + pseudo_debug(4, "called: ${name}\n"); pseudo_sigblock(&saved); if (pseudo_getlock()) { @@ -30,39 +42,25 @@ ${name}(${decl_args}) { sigprocmask(SIG_SETMASK, &saved, NULL); ${def_return} } - if (pseudo_check_wrappers()) { - int save_errno; - if (antimagic > 0) { - if (real_$name) { - /* call the real syscall */ - ${rc_assign} (*real_${name})(${call_args}); - } else { - /* rc was initialized to the "failure" value */ - pseudo_enosys("${name}"); - } - } else { - ${alloc_paths} - /* exec*() use this to restore the sig mask */ - pseudo_saved_sigmask = saved; - ${rc_assign} wrap_$name(${call_args}); - ${free_paths} - } - ${variadic_end} - save_errno = errno; - pseudo_droplock(); - sigprocmask(SIG_SETMASK, &saved, NULL); - pseudo_debug(4, "completed: $name\n"); - errno = save_errno; - ${rc_return} + + int save_errno; + if (antimagic > 0) { + /* call the real syscall */ + ${rc_assign} (*real_${name})(${call_args}); } else { - pseudo_droplock(); - sigprocmask(SIG_SETMASK, &saved, NULL); - pseudo_debug(4, "completed: $name\n"); - /* rc was initialized to the "failure" value */ - pseudo_enosys("${name}"); - ${variadic_end} - ${rc_return} + ${alloc_paths} + /* exec*() use this to restore the sig mask */ + pseudo_saved_sigmask = saved; + ${rc_assign} wrap_$name(${call_args}); + ${free_paths} } + ${variadic_end} + save_errno = errno; + pseudo_droplock(); + sigprocmask(SIG_SETMASK, &saved, NULL); + pseudo_debug(4, "completed: $name\n"); + errno = save_errno; + ${rc_return} } static ${type} |