diff options
author | alfred <alfred@FreeBSD.org> | 2001-12-29 07:13:47 +0000 |
---|---|---|
committer | alfred <alfred@FreeBSD.org> | 2001-12-29 07:13:47 +0000 |
commit | f097734c278c9d8c5412bc8bdd71ac4cf940152b (patch) | |
tree | 5fea52eb8edad79619358670508ccdce9203dfdf /sys/kern/kern_exec.c | |
parent | f96a36771992bfbe155d46db18744d7c849d2518 (diff) | |
download | FreeBSD-src-f097734c278c9d8c5412bc8bdd71ac4cf940152b.zip FreeBSD-src-f097734c278c9d8c5412bc8bdd71ac4cf940152b.tar.gz |
Make AIO a loadable module.
Remove the explicit call to aio_proc_rundown() from exit1(), instead AIO
will use at_exit(9).
Add functions at_exec(9), rm_at_exec(9) which function nearly the
same as at_exec(9) and rm_at_exec(9), these functions are called
on behalf of modules at the time of execve(2) after the image
activator has run.
Use a modified version of tegge's suggestion via at_exec(9) to close
an exploitable race in AIO.
Fix SYSCALL_MODULE_HELPER such that it's archetecuterally neutral,
the problem was that one had to pass it a paramater indicating the
number of arguments which were actually the number of "int". Fix
it by using an inline version of the AS macro against the syscall
arguments. (AS should be available globally but we'll get to that
later.)
Add a primative system for dynamically adding kqueue ops, it's really
not as sophisticated as it should be, but I'll discuss with jlemon when
he's around.
Diffstat (limited to 'sys/kern/kern_exec.c')
-rw-r--r-- | sys/kern/kern_exec.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 41ff7d8..670d5dd 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -65,6 +65,19 @@ MALLOC_DEFINE(M_PARGS, "proc-args", "Process arguments"); +static MALLOC_DEFINE(M_ATEXEC, "atexec", "atexec callback"); + +/* + * callout list for things to do at exec time + */ +struct execlist { + execlist_fn function; + TAILQ_ENTRY(execlist) next; +}; + +TAILQ_HEAD(exec_list_head, execlist); +static struct exec_list_head exec_list = TAILQ_HEAD_INITIALIZER(exec_list); + static register_t *exec_copyout_strings __P((struct image_params *)); /* XXX This should be vm_size_t. */ @@ -115,6 +128,7 @@ execve(td, uap) struct vattr attr; int (*img_first) __P((struct image_params *)); struct pargs *pa; + struct execlist *ep; imgp = &image_params; @@ -244,6 +258,9 @@ interpret: goto interpret; } + TAILQ_FOREACH(ep, &exec_list, next) + (*ep->function)(p); + /* * Copy out strings (args and env) and initialize stack base */ @@ -926,3 +943,44 @@ exec_unregister(execsw_arg) execsw = newexecsw; return 0; } + +int +at_exec(function) + execlist_fn function; +{ + struct execlist *ep; + +#ifdef INVARIANTS + /* Be noisy if the programmer has lost track of things */ + if (rm_at_exec(function)) + printf("WARNING: exec callout entry (%p) already present\n", + function); +#endif + ep = malloc(sizeof(*ep), M_ATEXEC, M_NOWAIT); + if (ep == NULL) + return (ENOMEM); + ep->function = function; + TAILQ_INSERT_TAIL(&exec_list, ep, next); + return (0); +} + +/* + * Scan the exec callout list for the given item and remove it. + * Returns the number of items removed (0 or 1) + */ +int +rm_at_exec(function) + execlist_fn function; +{ + struct execlist *ep; + + TAILQ_FOREACH(ep, &exec_list, next) { + if (ep->function == function) { + TAILQ_REMOVE(&exec_list, ep, next); + free(ep, M_ATEXEC); + return(1); + } + } + return (0); +} + |