diff options
-rw-r--r-- | TODO | 4 | ||||
-rw-r--r-- | config.make.in | 5 | ||||
-rw-r--r-- | configure.ac | 6 | ||||
-rw-r--r-- | console-client/Makefile | 4 | ||||
-rw-r--r-- | console-client/console.c | 115 | ||||
-rw-r--r-- | daemons/console-run.c | 5 | ||||
-rw-r--r-- | exec/Makefile | 10 | ||||
-rw-r--r-- | exec/exec.c | 648 | ||||
-rw-r--r-- | exec/main.c | 3 | ||||
-rw-r--r-- | exec/priv.h | 41 | ||||
-rw-r--r-- | hurd/process_reply.defs | 114 | ||||
-rw-r--r-- | include/pids.h | 29 | ||||
-rw-r--r-- | init/init.c | 3 | ||||
-rw-r--r-- | libdiskfs/boot-start.c | 3 | ||||
-rw-r--r-- | libdiskfs/init-startup.c | 3 | ||||
-rw-r--r-- | libnetfs/Makefile | 4 | ||||
-rw-r--r-- | libnetfs/dead-name.c | 45 | ||||
-rw-r--r-- | libnetfs/file-get-transcntl.c | 52 | ||||
-rw-r--r-- | libnetfs/file-get-translator.c | 14 | ||||
-rw-r--r-- | libnetfs/fsstubs.c | 8 | ||||
-rw-r--r-- | libshouldbeinlibc/Makefile | 4 | ||||
-rw-r--r-- | libshouldbeinlibc/nullauth.c | 47 | ||||
-rw-r--r-- | libshouldbeinlibc/nullauth.h | 31 | ||||
-rw-r--r-- | pfinet/main.c | 3 | ||||
-rw-r--r-- | proc/main.c | 3 | ||||
-rw-r--r-- | proc/mgt.c | 3 | ||||
-rw-r--r-- | tmpfs/tmpfs.c | 6 | ||||
-rw-r--r-- | trans/null.c | 5 | ||||
-rw-r--r-- | utils/Makefile | 6 | ||||
-rw-r--r-- | utils/nullauth.c | 90 |
30 files changed, 640 insertions, 674 deletions
@@ -173,10 +173,6 @@ See `tasks', the exported task list. 3: when a session leader exits, the association has to be torn down; bsd does SIGHUP + drain + revoke.) -** exec: -*** either resurrect or excise BFD exec server - (needs stdio magic converted to use libio when libc converts) - ** proc: *** Add a version of proc_wait usable by non-parent processes, and use it in gdb; maybe just a flag WNOREAP to proc_wait that doesn't reap and allows diff --git a/config.make.in b/config.make.in index dbcf8a38..edb74c07 100644 --- a/config.make.in +++ b/config.make.in @@ -80,6 +80,11 @@ X11_LIBS = @X11_LIBS@ XKB_BASE = @XKB_BASE@ X11_KEYSYMDEF_H = @X11_KEYSYMDEF_H@ +# How to compile and link against libdaemon. +HAVE_DAEMON = @HAVE_DAEMON@ +libdaemon_CFLAGS = @libdaemon_CFLAGS@ +libdaemon_LIBS = @libdaemon_LIBS@ + # Whether Sun RPC support is available. HAVE_SUN_RPC = @HAVE_SUN_RPC@ diff --git a/configure.ac b/configure.ac index b8275360..d40c01fb 100644 --- a/configure.ac +++ b/configure.ac @@ -297,6 +297,12 @@ else echo ${file}:build.mk.in; done`" fi +PKG_CHECK_MODULES([libdaemon], [libdaemon], + [AC_DEFINE([HAVE_DAEMON], [1], [Use libdaemon])], + [true]) +AC_SUBST([libdaemon_LIBS]) +AC_SUBST([libdaemon_CFLAGS]) + AC_CONFIG_FILES([config.make ${makefiles}]) AC_OUTPUT diff --git a/console-client/Makefile b/console-client/Makefile index 69a7e371..65a04e0d 100644 --- a/console-client/Makefile +++ b/console-client/Makefile @@ -37,11 +37,11 @@ SRCS = $(CONSOLE_SRCS) \ VPATH += $(srcdir)/xkb OBJS = $(addsuffix .o,$(basename $(notdir $(SRCS)))) kdioctlServer.o HURDLIBS = cons ports netfs fshelp iohelp ihash shouldbeinlibc -LDLIBS = -ldl -lpthread +LDLIBS = -ldl -lpthread $(libdaemon_LIBS) module-dir = $(libdir)/hurd/console console-LDFLAGS = -Wl,-E -CPPFLAGS += -I$(CURDIR)/xkb -I$(srcdir)/xkb +CPPFLAGS += -I$(CURDIR)/xkb -I$(srcdir)/xkb $(libdaemon_CFLAGS) LFLAGS = -i YFLAGS = -by XKB_DATA_FILES = keymap/hurd types/hurd symbols/hurd diff --git a/console-client/console.c b/console-client/console.c index 7c9a8801..f995ca2e 100644 --- a/console-client/console.c +++ b/console-client/console.c @@ -26,6 +26,9 @@ #include <assert.h> #include <pthread.h> +#if HAVE_DAEMON +#include <libdaemon/daemon.h> +#endif #include <hurd/console.h> #include <hurd/cons.h> @@ -61,6 +64,8 @@ static cons_t saved_cons; set. */ static char *console_node; +/* If set, the client will daemonize. */ +static int daemonize; /* Callbacks for input source drivers. */ @@ -516,6 +521,8 @@ cons_vcons_set_mousecursor_status (vcons_t vcons, int status) } +#define DAEMONIZE_KEY 0x80 /* !isascii (DAEMONIZE_KEY), so no short option. */ + /* Console-specific options. */ static const struct argp_option options[] = @@ -524,6 +531,9 @@ options[] = {"driver", 'd', "NAME", 0, "Add driver NAME to the console" }, {"console-node", 'c', "FILE", OPTION_ARG_OPTIONAL, "Set a translator on the node FILE (default: " DEFAULT_CONSOLE_NODE ")" }, +#if HAVE_DAEMON + {"daemonize", DAEMONIZE_KEY, NULL, 0, "daemonize the console client"}, +#endif {0} }; @@ -577,7 +587,11 @@ parse_opt (int key, char *arg, struct argp_state *state) if (!console_node) return ENOMEM; break; - + + case DAEMONIZE_KEY: + daemonize = 1; + break; + case ARGP_KEY_SUCCESS: if (!devcount) { @@ -597,6 +611,31 @@ static const struct argp_child startup_children[] = { { &cons_startup_argp }, { 0 } }; static struct argp startup_argp = {options, parse_opt, 0, 0, startup_children}; +#if HAVE_DAEMON +#define daemon_error(status, errnum, format, args...) \ + do \ + { \ + if (daemonize) \ + { \ + if (errnum) \ + daemon_log (LOG_ERR, format ": %s", ##args, \ + strerror(errnum)); \ + else \ + daemon_log (LOG_ERR, format, ##args); \ + if (status) \ + { \ + /* Signal parent. */ \ + daemon_retval_send (status); \ + return 0; \ + } \ + } \ + else \ + error (status, errnum, format, ##args); \ + } \ + while (0); +#else +#define daemon_error error +#endif int main (int argc, char *argv[]) @@ -609,9 +648,69 @@ main (int argc, char *argv[]) /* Parse our command line. This shouldn't ever return an error. */ argp_parse (&startup_argp, argc, argv, ARGP_IN_ORDER, 0, 0); +#if HAVE_DAEMON + if (daemonize) + { + /* Reset signal handlers. */ + if (daemon_reset_sigs (-1) < 0) + error (1, errno, "Failed to reset all signal handlers"); + + /* Unblock signals. */ + if (daemon_unblock_sigs (-1) < 0) + error (1, errno, "Failed to unblock all signals"); + + /* Set indetification string for the daemon for both syslog and + PID file. */ + daemon_pid_file_ident = daemon_log_ident = \ + daemon_ident_from_argv0 (argv[0]); + + /* Check that the daemon is not run twice at the same time. */ + pid_t pid; + if ((pid = daemon_pid_file_is_running ()) >= 0) + error (1, errno, "Daemon already running on PID file %u", pid); + + /* Prepare for return value passing from the initialization + procedure of the daemon process. */ + if (daemon_retval_init () < 0) + error (1, errno, "Failed to create pipe."); + + /* Do the fork. */ + if ((pid = daemon_fork ()) < 0) + { + /* Exit on error. */ + daemon_retval_done (); + error (1, errno, "Failed to fork"); + } + else if (pid) + { + /* The parent. */ + int ret; + + /* Wait for 20 seconds for the return value passed from the + daemon process. . */ + if ((ret = daemon_retval_wait (20)) < 0) + error (1, errno, + "Could not receive return value from daemon process"); + + return ret; + } + else + { + /* The daemon. */ + /* Close FDs. */ + if (daemon_close_all (-1) < 0) + daemon_error (1, errno, "Failed to close all file descriptors"); + + /* Create the PID file. */ + if (daemon_pid_file_create () < 0) + daemon_error (2, errno, "Could not create PID file"); + } + } +#endif /* HAVE_DAEMON */ + err = driver_start (&errname); if (err) - error (1, err, "Starting driver %s failed", errname); + daemon_error (1, err, "Starting driver %s failed", errname); pthread_mutex_init (&global_lock, NULL); @@ -619,19 +718,25 @@ main (int argc, char *argv[]) if (err) { driver_fini (); - error (1, err, "Console library initialization failed"); + daemon_error (1, err, "Console library initialization failed"); } err = timer_init (); if (err) { driver_fini (); - error (1, err, "Timer thread initialization failed"); + daemon_error (1, err, "Timer thread initialization failed"); } if (console_node) console_setup_node (console_node); - + +#if HAVE_DAEMON + if (daemonize) + /* Signal parent that all went well. */ + daemon_retval_send(0); +#endif + cons_server_loop (); /* Never reached. */ diff --git a/daemons/console-run.c b/daemons/console-run.c index fb879e53..e1bfe642 100644 --- a/daemons/console-run.c +++ b/daemons/console-run.c @@ -217,8 +217,9 @@ open_console (char **namep) dup2 (0, 1); dup2 (0, 2); - if (setsid () == -1) - error (0, errno, "setsid"); + if (getsid (0) != getpid ()) + if (setsid () == -1) + error (0, errno, "setsid"); /* Set the console to our pgrp. */ tcsetpgrp (0, getpid ()); diff --git a/exec/Makefile b/exec/Makefile index 3fc82739..eb883612 100644 --- a/exec/Makefile +++ b/exec/Makefile @@ -20,11 +20,11 @@ dir := exec makemode := server -SRCS = exec.c main.c hashexec.c hostarch.c \ - $(gzip-sources) $(bzip2-sources) +SRCS = exec.c main.c hashexec.c hostarch.c +# $(gzip-sources) $(bzip2-sources) OBJS = main.o hostarch.o exec.o hashexec.o \ - execServer.o exec_startupServer.o \ - $(gzip-objects) $(bzip2-objects) + execServer.o exec_startupServer.o +# $(gzip-objects) $(bzip2-objects) gzip-sources = unzip.c util.c inflate.c gzip-objects = $(gzip-sources:%.c=%.o) bzip2-sources = do-bunzip2.c @@ -40,6 +40,6 @@ exec-MIGSFLAGS = -imacros $(srcdir)/execmutations.h include ../Makeconf -CPPFLAGS += -DGZIP -DBZIP2 # -DBFD +CPPFLAGS += # -DGZIP -DBZIP2 -DBFD exec.static exec: $(OBJS) $(library_deps) diff --git a/exec/exec.c b/exec/exec.c index 30a5e000..f139792b 100644 --- a/exec/exec.c +++ b/exec/exec.c @@ -7,10 +7,6 @@ #ifdef GZIP Can gunzip executables into core on the fly. #endif - #ifdef BFD - Can exec any executable format the BFD library understands - to be for this flavor of machine. - #endif #ifdef BZIP2 Can bunzip2 executables into core on the fly. #endif @@ -50,26 +46,7 @@ size_t std_nports, std_nints; pthread_rwlock_t std_lock = PTHREAD_RWLOCK_INITIALIZER; -#ifdef BFD -/* Return a Hurd error code corresponding to the most recent BFD error. */ -static error_t -b2he (error_t deflt) -{ - switch (bfd_get_error ()) - { - case bfd_error_system_call: - return errno; - - case bfd_error_no_memory: - return ENOMEM; - - default: - return deflt; - } -} -#else #define b2he() a2he (errno) -#endif #ifdef GZIP static void check_gzip (struct execdata *); @@ -79,41 +56,6 @@ static void check_gzip (struct execdata *); static void check_bzip2 (struct execdata *); #endif -#ifdef BFD - -/* Check a section, updating the `locations' vector [BFD]. */ -static void -check_section (bfd *bfd, asection *sec, void *userdata) -{ - struct execdata *u = userdata; - static const union - { - char string[8]; - unsigned int quadword __attribute__ ((mode (DI))); - } interp = { string: ".interp" }; - - if (u->error) - return; - - /* Fast strcmp for this 8-byte constant string. */ - if (*(const __typeof (interp.quadword) *) sec->name == interp.quadword) - u->interp.section = sec; - - if (!(sec->flags & (SEC_ALLOC|SEC_LOAD)) || - (sec->flags & SEC_NEVER_LOAD)) - /* Nothing to do for this section. */ - return; - - if (sec->flags & SEC_LOAD) - { - u->info.bfd_locations[sec->index] = sec->filepos; - if ((off_t) sec->filepos < 0 || (off_t) sec->filepos > u->file_size) - u->error = ENOEXEC; - } -} -#endif - - /* Zero the specified region but don't crash the server if it faults. */ #include <hurd/sigpreempt.h> @@ -135,69 +77,45 @@ load_section (void *section, struct execdata *u) vm_prot_t vm_prot; int anywhere; vm_address_t mask = 0; -#ifdef BFD - asection *const sec = section; -#endif const ElfW(Phdr) *const ph = section; if (u->error) return; -#ifdef BFD - if (u->bfd && sec->flags & SEC_NEVER_LOAD) - /* Nothing to do for this section. */ - return; -#endif - vm_prot = VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE; -#ifdef BFD - if (u->bfd) - { - addr = (vm_address_t) sec->vma; - filepos = u->info.bfd_locations[sec->index]; - memsz = sec->_raw_size; - filesz = (sec->flags & SEC_LOAD) ? memsz : 0; - if (sec->flags & (SEC_READONLY|SEC_ROM)) - vm_prot &= ~VM_PROT_WRITE; - anywhere = 0; - } + addr = ph->p_vaddr & ~(ph->p_align - 1); + memsz = ph->p_vaddr + ph->p_memsz - addr; + filepos = ph->p_offset & ~(ph->p_align - 1); + filesz = ph->p_offset + ph->p_filesz - filepos; + if ((ph->p_flags & PF_R) == 0) + vm_prot &= ~VM_PROT_READ; + if ((ph->p_flags & PF_W) == 0) + vm_prot &= ~VM_PROT_WRITE; + if ((ph->p_flags & PF_X) == 0) + vm_prot &= ~VM_PROT_EXECUTE; + anywhere = u->info.elf.anywhere; + if (! anywhere) + addr += u->info.elf.loadbase; else -#endif - { - addr = ph->p_vaddr & ~(ph->p_align - 1); - memsz = ph->p_vaddr + ph->p_memsz - addr; - filepos = ph->p_offset & ~(ph->p_align - 1); - filesz = ph->p_offset + ph->p_filesz - filepos; - if ((ph->p_flags & PF_R) == 0) - vm_prot &= ~VM_PROT_READ; - if ((ph->p_flags & PF_W) == 0) - vm_prot &= ~VM_PROT_WRITE; - if ((ph->p_flags & PF_X) == 0) - vm_prot &= ~VM_PROT_EXECUTE; - anywhere = u->info.elf.anywhere; - if (! anywhere) - addr += u->info.elf.loadbase; - else #if 0 - switch (elf_machine) - { - case EM_386: - case EM_486: - /* On the i386, programs normally load at 0x08000000, and - expect their data segment to be able to grow dynamically - upward from its start near that address. We need to make - sure that the dynamic linker is not mapped in a conflicting - address. */ - /* mask = 0xf8000000UL; */ /* XXX */ - break; - default: - break; - } + switch (elf_machine) + { + case EM_386: + case EM_486: + /* On the i386, programs normally load at 0x08000000, and + expect their data segment to be able to grow dynamically + upward from its start near that address. We need to make + sure that the dynamic linker is not mapped in a conflicting + address. */ + /* mask = 0xf8000000UL; */ /* XXX */ + break; + default: + break; + } #endif - if (anywhere && addr < vm_page_size) - addr = vm_page_size; - } + if (anywhere && addr < vm_page_size) + addr = vm_page_size; if (memsz == 0) /* This section is empty; ignore it. */ @@ -502,16 +420,6 @@ map (struct execdata *e, off_t posn, size_t len) return map_buffer (e) + offset; } - -/* Initialize E's stdio stream. */ -static void prepare_stream (struct execdata *e); - -/* Point the stream at the buffer of file data in E->file_data. */ -static void prepare_in_memory (struct execdata *e); - - -#ifndef EXECDATA_STREAM - /* We don't have a stdio stream, but we have a mapping window we need to initialize. */ static void @@ -521,199 +429,7 @@ prepare_stream (struct execdata *e) e->map_vsize = e->map_fsize = 0; e->map_filepos = 0; } - -static void prepare_in_memory (struct execdata *e) -{ - prepare_stream(e); -} - -#else - -#ifdef _STDIO_USES_IOSTREAM - -# error implement me for libio! - -#else /* old GNU stdio */ - -#if 0 -void * -map (struct execdata *e, off_t posn, size_t len) -{ - FILE *f = &e->stream; - const size_t size = e->file_size; - size_t offset; - - if ((f->__offset & ~(f->__bufsize - 1)) == (posn & ~(f->__bufsize - 1)) && - f->__buffer + (posn + len - f->__offset) < f->__get_limit) - /* The current mapping window covers it. */ - offset = posn & (f->__bufsize - 1); - else if (e->file_data != NULL) - { - /* The current "mapping window" is in fact the whole file contents. - So if it's not in there, it's not in there. */ - f->__eof = 1; - return NULL; - } - else if (e->filemap == MACH_PORT_NULL) - { - /* No mapping for the file. Read the data by RPC. */ - char *buffer = f->__buffer; - mach_msg_type_number_t nread = f->__bufsize; - /* Read as much as we can get into the buffer right now. */ - e->error = io_read (e->file, &buffer, &nread, posn, round_page (len)); - if (e->error) - { - errno = e->error; - f->__error = 1; - return NULL; - } - if (buffer != f->__buffer) - { - /* The data was returned out of line. Discard the old buffer. */ - if (f->__bufsize != 0) - munmap (f->__buffer, f->__bufsize); - f->__buffer = buffer; - f->__bufsize = round_page (nread); - } - - f->__offset = posn; - f->__get_limit = f->__buffer + nread; - offset = 0; - } - else - { - /* Deallocate the old mapping area. */ - if (f->__buffer != NULL) - munmap (f->__buffer, f->__bufsize); - f->__buffer = NULL; - - /* Make sure our mapping is page-aligned in the file. */ - offset = posn & (vm_page_size - 1); - f->__offset = trunc_page (posn); - f->__bufsize = round_page (posn + len) - f->__offset; - - /* Map the data from the file. */ - if (vm_map (mach_task_self (), - (vm_address_t *) &f->__buffer, f->__bufsize, 0, 1, - e->filemap, f->__offset, 1, VM_PROT_READ, VM_PROT_READ, - VM_INHERIT_NONE)) - { - errno = e->error = EIO; - f->__error = 1; - return NULL; - } - - if (e->cntl) - e->cntl->accessed = 1; - - if (f->__offset + f->__bufsize > size) - f->__get_limit = f->__buffer + (size - f->__offset); - else - f->__get_limit = f->__buffer + f->__bufsize; - } - - f->__target = f->__offset; - f->__bufp = f->__buffer + offset; - - if (f->__bufp + len > f->__get_limit) - { - f->__eof = 1; - return NULL; - } - - return f->__bufp; -} -#endif - -/* stdio input-room function. - XXX/fault in the stdio case (or libio replacement), i.e. for bfd - (if ever revived), need to check all the mapping fault issues */ -static int -input_room (FILE *f) -{ - struct execdata *e = f->__cookie; - char *p = map (e, f->__target, 1); - if (p == NULL) - { - (e->error ? f->__error : f->__eof) = 1; - return EOF; - } - - f->__target = f->__offset; - f->__bufp = p; - - return (unsigned char) *f->__bufp++; -} - -static int -close_exec_stream (void *cookie) -{ - struct execdata *e = cookie; - - if (e->stream.__buffer != NULL) - munmap (e->stream.__buffer, e->stream.__bufsize); - - return 0; -} - -/* stdio seek function. */ -static int -fake_seek (void *cookie, fpos_t *pos, int whence) -{ - struct execdata *e = cookie; - - /* Set __target to match the specifed seek location */ - switch (whence) - { - case SEEK_END: - e->stream.__target = e->file_size + *pos; - break; - - case SEEK_CUR: - e->stream.__target += *pos; - break; - - case SEEK_SET: - e->stream.__target = *pos; - break; - } - *pos = e->stream.__target; - return 0; -} - -/* Initialize E's stdio stream. */ -static void -prepare_stream (struct execdata *e) -{ - memset (&e->stream, 0, sizeof (e->stream)); - e->stream.__magic = _IOMAGIC; - e->stream.__mode.__read = 1; - e->stream.__userbuf = 1; - e->stream.__room_funcs.__input = input_room; - e->stream.__io_funcs.seek = fake_seek; - e->stream.__io_funcs.close = close_exec_stream; - e->stream.__cookie = e; - e->stream.__seen = 1; -} - -/* Point the stream at the buffer of file data. */ -static void -prepare_in_memory (struct execdata *e) -{ - memset (&e->stream, 0, sizeof (e->stream)); - e->stream.__magic = _IOMAGIC; - e->stream.__mode.__read = 1; - e->stream.__buffer = e->file_data; - e->stream.__bufsize = e->file_size; - e->stream.__get_limit = e->stream.__buffer + e->stream.__bufsize; - e->stream.__bufp = e->stream.__buffer; - e->stream.__seen = 1; -} -#endif - -#endif - /* Prepare to check and load FILE. */ static void prepare (file_t file, struct execdata *e) @@ -722,9 +438,6 @@ prepare (file_t file, struct execdata *e) e->file = file; -#ifdef BFD - e->bfd = NULL; -#endif e->file_data = NULL; e->cntl = NULL; e->filemap = MACH_PORT_NULL; @@ -801,42 +514,6 @@ prepare (file_t file, struct execdata *e) } } -/* Check the magic number, etc. of the file. - On successful return, the caller must allocate the - E->locations vector, and map check_section over the BFD. */ - -#ifdef BFD -static void -check_bfd (struct execdata *e) -{ - bfd_set_error (bfd_error_no_error); - - e->bfd = bfd_openstreamr (NULL, NULL, &e->stream); - if (e->bfd == NULL) - { - e->error = b2he (ENOEXEC); - return; - } - - if (!bfd_check_format (e->bfd, bfd_object)) - { - e->error = b2he (ENOEXEC); - return; - } - else if (/* !(e->bfd->flags & EXEC_P) || XXX */ - (host_bfd.arch_info->compatible = e->bfd->arch_info->compatible, - bfd_arch_get_compatible (&host_bfd, e->bfd)) != host_bfd.arch_info) - { - /* This file is of a recognized binary file format, but it is not - executable on this machine. */ - e->error = b2he (ENOEXEC); - return; - } - - e->entry = e->bfd->start_address; -} -#endif - #include <endian.h> #if BYTE_ORDER == BIG_ENDIAN #define host_ELFDATA ELFDATA2MSB @@ -955,13 +632,6 @@ static void check (struct execdata *e) { check_elf (e); /* XXX/fault */ -#ifdef BFD - if (e->error == ENOEXEC) - { - e->error = 0; - check_bfd (e); - } -#endif } @@ -1004,18 +674,7 @@ void finish (struct execdata *e, int dealloc_file) { finish_mapping (e); -#ifdef BFD - if (e->bfd != NULL) { - bfd_close (e->bfd); - e->bfd = NULL; - } - else -#endif - { -#ifdef EXECDATA_STREAM - fclose (&e->stream); -#else if (e->file_data != NULL) { free (e->file_data); e->file_data = NULL; @@ -1023,7 +682,6 @@ finish (struct execdata *e, int dealloc_file) munmap (map_buffer (e), map_vsize (e)); map_buffer (e) = NULL; } -#endif } if (dealloc_file && e->file != MACH_PORT_NULL) { @@ -1041,81 +699,18 @@ load (task_t usertask, struct execdata *e) if (! e->error) { -#ifdef BFD - if (e->bfd) - { - void load_bfd_section (bfd *bfd, asection *sec, void *userdata) - { - load_section (sec, userdata); - } - bfd_map_over_sections (e->bfd, &load_bfd_section, e); - } - else -#endif - { - ElfW(Word) i; - for (i = 0; i < e->info.elf.phnum; ++i) - if (e->info.elf.phdr[i].p_type == PT_LOAD) - load_section (&e->info.elf.phdr[i], e); - - /* The entry point address is relative to wherever we loaded the - program text. */ - e->entry += e->info.elf.loadbase; - } + ElfW(Word) i; + for (i = 0; i < e->info.elf.phnum; ++i) + if (e->info.elf.phdr[i].p_type == PT_LOAD) + load_section (&e->info.elf.phdr[i], e); + + /* The entry point address is relative to wherever we loaded the + program text. */ + e->entry += e->info.elf.loadbase; } /* Release the conch for the file. */ finish_mapping (e); - - if (! e->error) - { - /* Do post-loading processing on the task. */ - -#ifdef BFD - if (e->bfd) - { - /* Do post-loading processing for a section. This consists of - peeking the pages of non-demand-paged executables. */ - - void postload_section (bfd *bfd, asection *sec, void *userdata) - { - struct execdata *u = userdata; - vm_address_t addr = 0; - vm_size_t secsize = 0; - - addr = (vm_address_t) sec->vma; - secsize = sec->_raw_size; - - if ((sec->flags & SEC_LOAD) && !(bfd->flags & D_PAGED)) - { - /* Pre-load the section by peeking every mapped page. */ - vm_address_t myaddr, a; - vm_size_t mysize; - myaddr = 0; - - /* We have already mapped the file into the task in - load_section. Now read from the task's memory into our - own address space so we can peek each page and cause it to - be paged in. */ - u->error = vm_read (u->task, trunc_page (addr), - round_page (secsize), &myaddr, &mysize); - if (u->error) - return; - - /* Peek at the first word of each page. */ - for (a = ((myaddr + mysize) & ~(vm_page_size - 1)); - a >= myaddr; a -= vm_page_size) - /* Force it to be paged in. */ - (void) *(volatile int *) a; - - munmap ((caddr_t) myaddr, mysize); - } - } - - bfd_map_over_sections (e->bfd, postload_section, e); - } -#endif - } } #ifdef GZIP @@ -1466,20 +1061,9 @@ do_exec (file_t file, /* The file is not a valid executable. */ goto out; -#ifdef BFD - if (e.bfd) - { - e.info.bfd_locations = alloca (e.bfd->section_count * - sizeof (vm_offset_t)); - bfd_map_over_sections (e.bfd, check_section, &e); - } - else -#endif - { - const ElfW(Phdr) *phdr = e.info.elf.phdr; - e.info.elf.phdr = alloca (e.info.elf.phnum * sizeof (ElfW(Phdr))); - check_elf_phdr (&e, phdr); - } + const ElfW(Phdr) *phdr = e.info.elf.phdr; + e.info.elf.phdr = alloca (e.info.elf.phnum * sizeof (ElfW(Phdr))); + check_elf_phdr (&e, phdr); if (oldtask == MACH_PORT_NULL) flags |= EXEC_NEWTASK; @@ -1685,33 +1269,11 @@ do_exec (file_t file, along with this executable. Find the name of the file and open it. */ -#ifdef BFD - char namebuf[e.bfd ? e.interp.section->_raw_size : 0]; -#endif - char *name; - -#ifdef BFD - if (e.bfd) - { - if (! bfd_get_section_contents (e.bfd, e.interp.section, - namebuf, 0, - e.interp.section->_raw_size)) - { - e.error = b2he (errno); - name = NULL; - } - else - name = namebuf; - } - else -#endif - { - name = map (&e, (e.interp.phdr->p_offset - & ~(e.interp.phdr->p_align - 1)), - e.interp.phdr->p_filesz); - if (! name && ! e.error) - e.error = ENOEXEC; - } + char *name = map (&e, (e.interp.phdr->p_offset + & ~(e.interp.phdr->p_align - 1)), + e.interp.phdr->p_filesz); + if (! name && ! e.error) + e.error = ENOEXEC; if (! name) e.interp.section = NULL; @@ -1749,21 +1311,10 @@ do_exec (file_t file, prepare_and_check (interp.file, &interp); if (! interp.error) { -#ifdef BFD - if (interp.bfd) - { - interp.info.bfd_locations = alloca (interp.bfd->section_count * - sizeof (vm_offset_t)); - bfd_map_over_sections (interp.bfd, check_section, &e); - } - else -#endif - { - const ElfW(Phdr) *phdr = interp.info.elf.phdr; - interp.info.elf.phdr = alloca (interp.info.elf.phnum * - sizeof (ElfW(Phdr))); - check_elf_phdr (&interp, phdr); - } + const ElfW(Phdr) *phdr = interp.info.elf.phdr; + interp.info.elf.phdr = alloca (interp.info.elf.phnum * + sizeof (ElfW(Phdr))); + check_elf_phdr (&interp, phdr); } e.error = interp.error; } @@ -1842,10 +1393,7 @@ do_exec (file_t file, the image so that a load-anywhere image gets the adjusted addresses. */ if (e.info.elf.phdr_addr != 0) { -#ifdef BFD - if (!e.bfd) -#endif - e.info.elf.phdr_addr += e.info.elf.loadbase; + e.info.elf.phdr_addr += e.info.elf.loadbase; boot->phdr_addr = e.info.elf.phdr_addr; boot->phdr_size = e.info.elf.phnum * sizeof (ElfW(Phdr)); } @@ -1864,17 +1412,12 @@ do_exec (file_t file, &boot->stack_base, &boot->stack_size); if (e.error) goto out; -#ifdef BFD - if (!e.bfd) -#endif - { - /* It would probably be better to change mach_setup_thread so - it does a vm_map with the right permissions to start with. */ - if (!e.info.elf.execstack) - e.error = vm_protect (newtask, boot->stack_base, boot->stack_size, - 0, VM_PROT_READ | VM_PROT_WRITE); - } + /* It would probably be better to change mach_setup_thread so + it does a vm_map with the right permissions to start with. */ + if (!e.info.elf.execstack) + e.error = vm_protect (newtask, boot->stack_base, boot->stack_size, + 0, VM_PROT_READ | VM_PROT_WRITE); if (oldtask != newtask && oldtask != MACH_PORT_NULL) { @@ -2071,87 +1614,6 @@ S_exec_exec (struct trivfs_protid *protid, if (! protid) return EOPNOTSUPP; -#if 0 - if (!(flags & EXEC_SECURE)) - { - char *list = envz_get (envp, envplen, "EXECSERVERS"); - - if (list) - { - int tried = 0; - list = strdupa (list); - while ((p = strsep (&list, ":"))) - { - /* Open the named file using the appropriate directory ports for - the user. */ - error_t user_port (int which, error_t (*operate) (mach_port_t)) - { - return (*operate) (nports > which - ? portarray[which] : MACH_PORT_NULL); - } - file_t user_fd (int fd) - { - if (fd < 0 || fd >= dtablesize || - dtable[fd] == MACH_PORT_NULL) - { - errno = EBADF; - return MACH_PORT_NULL; - } - return dtable[fd]; - } - file_t server; - if (!hurd_file_name_lookup (user_port, user_fd, 0, p, 0,0, &server)) - { - error_t err; - struct trivfs_protid *protid - = ports_lookup_port (port_bucket, server, - trivfs_protid_portclasses[0]); - if (protid) - { - err = do_exec (file, oldtask, 0, - argv, argvlen, argv_copy, - envp, envplen, envp_copy, - dtable, dtablesize, dtable_copy, - portarray, nports, portarray_copy, - intarray, nints, intarray_copy, - deallocnames, ndeallocnames, - destroynames, ndestroynames); - ports_port_deref (protid); - } - else - { - int n; - err = exec_exec (server, - file, MACH_MSG_TYPE_COPY_SEND, - oldtask, 0, - argv, argvlen, - envp, envplen, - dtable, MACH_MSG_TYPE_COPY_SEND, - dtablesize, - portarray, MACH_MSG_TYPE_COPY_SEND, - nports, - intarray, nints, - deallocnames, ndeallocnames, - destroynames, ndestroynames); - mach_port_deallocate (mach_task_self (), file); - for (n = 0; n < dtablesize; n++) - mach_port_deallocate (mach_task_self (), dtable[n]); - for (n = 0; n < nports; n++) - mach_port_deallocate (mach_task_self (), portarray[n]); - } - mach_port_deallocate (mach_task_self (), server); - if (err != ENOEXEC) - return err; - tried = 1; - } - } - if (tried) - /* At least one exec server got a crack at it and gave up. */ - return ENOEXEC; - } - } -#endif - /* There were no user-specified exec servers, or none of them could be found. */ diff --git a/exec/main.c b/exec/main.c index efad85aa..d5d6882a 100644 --- a/exec/main.c +++ b/exec/main.c @@ -25,6 +25,7 @@ #include <hurd/startup.h> #include <argp.h> #include <version.h> +#include <pids.h> const char *argp_program_version = STANDARD_HURD_VERSION (exec); @@ -246,7 +247,7 @@ S_exec_init (struct trivfs_protid *protid, proc_register_version (procserver, host_priv, "exec", "", HURD_VERSION); - err = proc_getmsgport (procserver, 1, &startup); + err = proc_getmsgport (procserver, HURD_PID_STARTUP, &startup); assert_perror (err); mach_port_deallocate (mach_task_self (), procserver); diff --git a/exec/priv.h b/exec/priv.h index dbecb7a9..b9c6e990 100644 --- a/exec/priv.h +++ b/exec/priv.h @@ -28,10 +28,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <hurd/lookup.h> #include <pthread.h> -#ifdef BFD -#include <bfd.h> -#endif - #include <elf.h> #include <link.h> /* This gives us the ElfW macro. */ #include <fcntl.h> @@ -41,12 +37,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef exec_priv_h #define exec_priv_h -#ifdef BFD -/* A BFD whose architecture and machine type are those of the host system. */ -extern bfd_arch_info_type host_bfd_arch_info; -extern bfd host_bfd; -#endif - /* Information kept around to be given to a new task in response to a message on the task's bootstrap port. */ struct bootinfo @@ -70,12 +60,7 @@ struct port_class *execboot_portclass; extern mach_port_t procserver; /* Our proc port. */ -#ifdef BFD -#define EXECDATA_STREAM /* BFD uses stdio to access the executable. */ -#else typedef void asection; -#endif - /* Data shared between check, check_section, load, load_section, and finish. */ @@ -88,8 +73,6 @@ struct execdata vm_address_t entry; file_t file; -#ifndef EXECDATA_STREAM - /* Note that if `file_data' (below) is set, then these just point into that and should not be deallocated (file_data is malloc'd). */ char *map_buffer; /* Our mapping window or read buffer. */ @@ -102,26 +85,6 @@ struct execdata #define map_filepos(e) ((e)->map_filepos) #define map_set_fsize(e, fsize) ((e)->map_fsize = (fsize)) -#else - -#ifdef _STDIO_USES_IOSTREAM -# error implement me for libio! -#else - FILE stream; -#define map_buffer(e) ((e)->stream.__buffer) -#define map_fsize(e) ((e)->stream.__get_limit - (e)->stream.__buffer) -#define map_vsize(e) ((e)->stream.__bufsize) -#define map_filepos(e) ((e)->stream.__offset) -#define map_set_fsize(e, fsize) \ - ((e)->stream.__get_limit = (e)->stream.__buffer + (fsize)) -#endif - -#endif - -#ifdef BFD - bfd *bfd; -#endif - union /* Interpreter section giving name of file. */ { asection *section; @@ -138,10 +101,6 @@ struct execdata union { - /* Vector indexed by section index, - information passed from check_section to load_section. - Set by caller of check_section and load. */ - vm_offset_t *bfd_locations; struct { /* Program header table read from the executable. diff --git a/hurd/process_reply.defs b/hurd/process_reply.defs index 80d39293..bb663999 100644 --- a/hurd/process_reply.defs +++ b/hurd/process_reply.defs @@ -60,3 +60,117 @@ simpleroutine proc_wait_reply ( in sigcode: int; in rusage: rusage_t; in pid_status: pid_t); + +skip; /* proc_dostop */ +skip; /* proc_handle_exceptions */ +skip; /* proc_mark_stop */ +skip; /* proc_mark_cont */ +skip; /* proc_mark_exit */ +skip; /* proc_mark_exec */ +skip; /* proc_mark_traced */ +skip; /* proc_mod_stopchild */ + +simpleroutine proc_pid2task ( + reply_port: reply_port_t; + RETURN_CODE_ARG; + task: task_t); + +simpleroutine proc_task2pid ( + reply_port: reply_port_t; + RETURN_CODE_ARG; + pid: pid_t); + +simpleroutine proc_task2proc ( + reply_port: reply_port_t; + RETURN_CODE_ARG; + proc: mach_port_make_send_t); + +simpleroutine proc_proc2task ( + reply_port: reply_port_t; + RETURN_CODE_ARG; + task: task_t); + +simpleroutine proc_pid2proc ( + reply_port: reply_port_t; + RETURN_CODE_ARG; + proc: mach_port_make_send_t); + +simpleroutine proc_getprocinfo ( + reply_port: reply_port_t; + RETURN_CODE_ARG; + flags: int; + procinfo: procinfo_t, dealloc; + threadwaits: data_t, dealloc); + +simpleroutine proc_getprocargs ( + reply_port: reply_port_t; + RETURN_CODE_ARG; + procargs: data_t, dealloc); + +simpleroutine proc_getprocenv ( + reply_port: reply_port_t; + RETURN_CODE_ARG; + procenv: data_t, dealloc); + +skip; /* proc_make_login_coll */ + +simpleroutine proc_getloginid ( + reply_port: reply_port_t; + RETURN_CODE_ARG; + login_id: pid_t); + +simpleroutine proc_getloginpids ( + reply_port: reply_port_t; + RETURN_CODE_ARG; + pids: pidarray_t, dealloc); + +skip; /* proc_setlogin */ + +simpleroutine proc_getlogin ( + reply_port: reply_port_t; + RETURN_CODE_ARG; + logname: string_t); + +skip; /* proc_setsid */ + +simpleroutine proc_getsid ( + reply_port: reply_port_t; + RETURN_CODE_ARG; + sid: pid_t); + +simpleroutine proc_getsessionpgids ( + reply_port: reply_port_t; + RETURN_CODE_ARG; + pgidset: pidarray_t, dealloc); + +simpleroutine proc_getsessionpids ( + reply_port: reply_port_t; + RETURN_CODE_ARG; + pidset: pidarray_t, dealloc); + +simpleroutine proc_getsidport ( + reply_port: reply_port_t; + RETURN_CODE_ARG; + sessport: mach_port_send_t); + +skip; /* proc_setpgrp */ + +simpleroutine proc_getpgrp ( + reply_port: reply_port_t; + RETURN_CODE_ARG; + pgrp: pid_t); + +simpleroutine proc_getpgrppids ( + reply_port: reply_port_t; + RETURN_CODE_ARG; + pidset: pidarray_t, dealloc); + +simpleroutine proc_get_tty ( + reply_port: reply_port_t; + RETURN_CODE_ARG; + tty: mach_port_send_t); + +simpleroutine proc_getnports ( + reply_port: reply_port_t; + RETURN_CODE_ARG; + nports: mach_msg_type_number_t); diff --git a/include/pids.h b/include/pids.h new file mode 100644 index 00000000..485916b5 --- /dev/null +++ b/include/pids.h @@ -0,0 +1,29 @@ +/* List of special processes. + + Copyright (C) 2013 Free Software Foundation + Written by Justus Winter <4winter@informatik.uni-hamburg.de> + + This file is part of the GNU Hurd. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef _HURD_PROCESSES_H +#define _HURD_PROCESSES_H + +#define HURD_PID_PROC 0 +#define HURD_PID_STARTUP 1 +#define HURD_PID_KERNEL 2 + +#endif /* _HURD_PROCESSES_H */ diff --git a/init/init.c b/init/init.c index 930408e8..05fce78f 100644 --- a/init/init.c +++ b/init/init.c @@ -49,6 +49,7 @@ #include <maptime.h> #include <version.h> #include <argp.h> +#include <pids.h> #include "startup_notify_U.h" #include "startup_reply_U.h" @@ -770,7 +771,7 @@ frob_kernel_process (void) task_t task; process_t proc, kbs; - err = proc_pid2task (procserver, 2, &task); + err = proc_pid2task (procserver, HURD_PID_KERNEL, &task); if (err) { error (0, err, "cannot get kernel task port"); diff --git a/libdiskfs/boot-start.c b/libdiskfs/boot-start.c index b62d5f30..6d9a7734 100644 --- a/libdiskfs/boot-start.c +++ b/libdiskfs/boot-start.c @@ -33,6 +33,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <string.h> #include <argz.h> #include <error.h> +#include <pids.h> #include "fsys_S.h" #include "fsys_reply_U.h" @@ -606,7 +607,7 @@ diskfs_S_fsys_init (mach_port_t port, proc_register_version (procserver, host, diskfs_server_name, "", diskfs_server_version); - err = proc_getmsgport (procserver, 1, &startup); + err = proc_getmsgport (procserver, HURD_PID_STARTUP, &startup); if (!err) { startup_essential_task (startup, mach_task_self (), MACH_PORT_NULL, diff --git a/libdiskfs/init-startup.c b/libdiskfs/init-startup.c index 2c0814fd..ff1622f0 100644 --- a/libdiskfs/init-startup.c +++ b/libdiskfs/init-startup.c @@ -26,6 +26,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <error.h> #include <hurd/fsys.h> #include <hurd/startup.h> +#include <pids.h> char *_diskfs_chroot_directory; @@ -190,7 +191,7 @@ _diskfs_init_completed () if (err) goto errout; - err = proc_getmsgport (proc, 1, &init); + err = proc_getmsgport (proc, HURD_PID_STARTUP, &init); mach_port_deallocate (mach_task_self (), proc); if (err) goto errout; diff --git a/libnetfs/Makefile b/libnetfs/Makefile index 24b5acae..a9810d23 100644 --- a/libnetfs/Makefile +++ b/libnetfs/Makefile @@ -34,7 +34,7 @@ FSSRCS= dir-link.c dir-lookup.c dir-mkdir.c dir-mkfile.c \ file-get-translator.c file-getcontrol.c file-getlinknode.c \ file-lock-stat.c file-lock.c file-set-size.c \ file-set-translator.c file-statfs.c file-sync.c file-syncfs.c \ - file-utimes.c file-reparent.c fsstubs.c + file-utimes.c file-reparent.c fsstubs.c file-get-transcntl.c IOSRCS= io-read.c io-readable.c io-seek.c io-write.c io-stat.c io-async.c \ io-set-all-openmodes.c io-get-openmodes.c io-set-some-openmodes.c \ @@ -52,7 +52,7 @@ OTHERSRCS= drop-node.c init-init.c make-node.c make-peropen.c make-protid.c \ init-startup.c startup-argp.c set-options.c append-args.c \ runtime-argp.c std-runtime-argp.c std-startup-argp.c \ append-std-options.c trans-callback.c set-get-trans.c \ - nref.c nrele.c nput.c file-get-storage-info-default.c + nref.c nrele.c nput.c file-get-storage-info-default.c dead-name.c SRCS= $(OTHERSRCS) $(FSSRCS) $(IOSRCS) $(FSYSSRCS) $(IFSOCKSRCS) diff --git a/libnetfs/dead-name.c b/libnetfs/dead-name.c new file mode 100644 index 00000000..ff29cfe6 --- /dev/null +++ b/libnetfs/dead-name.c @@ -0,0 +1,45 @@ +/* Handle dead name notifications on ports + Copyright (C) 1996 Free Software Foundation, Inc. + Written by Michael I. Bushnell, p/BSG. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#include "priv.h" + +void +ports_dead_name (void *notify, mach_port_t dead_name) +{ + struct protid *pi = ports_lookup_port (netfs_port_bucket, dead_name, + netfs_protid_class); + struct node *np; + + if (pi) + { + np = pi->po->np; + pthread_mutex_lock (&np->lock); + if (dead_name == np->sockaddr) + { + mach_port_deallocate (mach_task_self (), np->sockaddr); + np->sockaddr = MACH_PORT_NULL; + netfs_nput (np); + } + else + pthread_mutex_unlock (&np->lock); + } + + ports_interrupt_notified_rpcs (notify, dead_name, MACH_NOTIFY_DEAD_NAME); +} diff --git a/libnetfs/file-get-transcntl.c b/libnetfs/file-get-transcntl.c new file mode 100644 index 00000000..04596d72 --- /dev/null +++ b/libnetfs/file-get-transcntl.c @@ -0,0 +1,52 @@ +/* libnetfs implementation of fs.defs: file_get_translator_cntl + + Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation + + This is a trivially adapted version of + libdiskfs/file-get-transcntl.c. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "priv.h" +#include "fs_S.h" + +/* Implement file_get_translator_cntl as described in <hurd/fs.defs>. */ +error_t +netfs_S_file_get_translator_cntl (struct protid *cred, + mach_port_t *ctl, + mach_msg_type_name_t *ctltype) +{ + struct node *np; + error_t err; + + if (!cred) + return EOPNOTSUPP; + + np = cred->po->np; + + pthread_mutex_lock (&np->lock); + + err = fshelp_isowner (&np->nn_stat, cred->user); + if (!err) + err = fshelp_fetch_control (&np->transbox, ctl); + if (!err && *ctl == MACH_PORT_NULL) + err = ENXIO; + if (!err) + *ctltype = MACH_MSG_TYPE_MOVE_SEND; + + pthread_mutex_unlock (&np->lock); + + return err; +} diff --git a/libnetfs/file-get-translator.c b/libnetfs/file-get-translator.c index 59e61020..3a54ff10 100644 --- a/libnetfs/file-get-translator.c +++ b/libnetfs/file-get-translator.c @@ -109,6 +109,20 @@ netfs_S_file_get_translator (struct protid *user, *translen = len; err = 0; } + else if (np->nn_translated & S_IPTRANS) + { + char *string = NULL; + size_t len = 0; + err = netfs_get_translator (np, &string, &len); + if (!err) + { + if (len > *translen) + *trans = mmap (0, len, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); + memcpy (*trans, string, len); + *translen = len; + free (string); + } + } else err = EINVAL; diff --git a/libnetfs/fsstubs.c b/libnetfs/fsstubs.c index 708cbb82..f1b9bf7e 100644 --- a/libnetfs/fsstubs.c +++ b/libnetfs/fsstubs.c @@ -30,14 +30,6 @@ netfs_S_file_notice_changes (struct protid *user, } error_t -netfs_S_file_get_translator_cntl (struct protid *user, - mach_port_t *trans, - mach_msg_type_name_t *transtype) -{ - return EOPNOTSUPP; -} - -error_t netfs_S_file_getfh (struct protid *user, char **data, mach_msg_type_number_t *ndata) { diff --git a/libshouldbeinlibc/Makefile b/libshouldbeinlibc/Makefile index 31a940ff..14a7939d 100644 --- a/libshouldbeinlibc/Makefile +++ b/libshouldbeinlibc/Makefile @@ -27,9 +27,9 @@ SRCS = termsize.c timefmt.c exec-reauth.c maptime-funcs.c \ idvec-impgids.c idvec-verify.c idvec-rep.c \ ugids.c ugids-argp.c ugids-rep.c ugids-verify.c ugids-subtract.c \ ugids-auth.c ugids-xinl.c ugids-merge.c ugids-imply.c ugids-posix.c \ - ugids-verify-auth.c + ugids-verify-auth.c nullauth.c installhdrs = idvec.h timefmt.h maptime.h \ - wire.h portinfo.h portxlate.h cacheq.h ugids.h + wire.h portinfo.h portxlate.h cacheq.h ugids.h nullauth.h installhdrsubdir = . OBJS = $(SRCS:.c=.o) diff --git a/libshouldbeinlibc/nullauth.c b/libshouldbeinlibc/nullauth.c new file mode 100644 index 00000000..4ba10a76 --- /dev/null +++ b/libshouldbeinlibc/nullauth.c @@ -0,0 +1,47 @@ +/* Drop all authentication credentials. + + Copyright (C) 2013 Free Software Foundation, Inc. + + Written by Justus Winter <4winter@informatik.uni-hamburg.de> + + This file is part of the GNU Hurd. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include <error.h> +#include <errno.h> +#include <hurd.h> + +/* Obtain an empty authentication handle and use it for further + authentication purposes. This effectively drops all Unix + privileges. */ +error_t +setnullauth (void) +{ + error_t err; + + auth_t nullauth; + err = auth_makeauth (getauth (), + NULL, MACH_MSG_TYPE_COPY_SEND, 0, + NULL, 0, + NULL, 0, + NULL, 0, + NULL, 0, + &nullauth); + if (err) + return err; + + err = setauth (nullauth); + return err; +} diff --git a/libshouldbeinlibc/nullauth.h b/libshouldbeinlibc/nullauth.h new file mode 100644 index 00000000..efdb5f3a --- /dev/null +++ b/libshouldbeinlibc/nullauth.h @@ -0,0 +1,31 @@ +/* Drop all authentication credentials. + + Copyright (C) 2013 Free Software Foundation, Inc. + + Written by Justus Winter <4winter@informatik.uni-hamburg.de> + + This file is part of the GNU Hurd. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef __NULLAUTH_H__ +#define __NULLAUTH_H__ + +/* Obtain an empty authentication handle and use it for further + authentication purposes. This effectively drops all Unix + privileges. */ +error_t +setnullauth (void); + +#endif /* __NULLAUTH_H__ */ diff --git a/pfinet/main.c b/pfinet/main.c index 01b324df..c9527195 100644 --- a/pfinet/main.c +++ b/pfinet/main.c @@ -28,6 +28,7 @@ #include <string.h> #include <fcntl.h> #include <version.h> +#include <pids.h> /* Include Hurd's errno.h file, but don't include glue-include/hurd/errno.h, since it #undef's the errno macro. */ @@ -153,7 +154,7 @@ arrange_shutdown_notification () if (!procserver) return; - err = proc_getmsgport (procserver, 1, &initport); + err = proc_getmsgport (procserver, HURD_PID_STARTUP, &initport); mach_port_deallocate (mach_task_self (), procserver); if (err) return; diff --git a/proc/main.c b/proc/main.c index 494169e7..73abbc07 100644 --- a/proc/main.c +++ b/proc/main.c @@ -28,6 +28,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <argp.h> #include <error.h> #include <version.h> +#include <pids.h> #include "proc.h" @@ -87,7 +88,7 @@ main (int argc, char **argv, char **envp) self_proc = allocate_proc (mach_task_self ()); assert (self_proc); - complete_proc (self_proc, 0); + complete_proc (self_proc, HURD_PID_PROC); startup_port = ports_get_send_right (startup_proc); err = startup_procinit (boot, startup_port, &startup_proc->p_task, @@ -32,6 +32,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <sys/resource.h> #include <hurd/auth.h> #include <assert.h> +#include <pids.h> #include "proc.h" #include "process_S.h" @@ -582,7 +583,7 @@ create_startup_proc (void) p = allocate_proc (MACH_PORT_NULL); assert (p); - p->p_pid = 1; + p->p_pid = HURD_PID_STARTUP; p->p_parent = p; p->p_sib = 0; diff --git a/tmpfs/tmpfs.c b/tmpfs/tmpfs.c index 7da3dd58..1872a7df 100644 --- a/tmpfs/tmpfs.c +++ b/tmpfs/tmpfs.c @@ -29,6 +29,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <fcntl.h> #include <hurd.h> #include <hurd/paths.h> +#include <nullauth.h> char *diskfs_server_name = "tmpfs"; char *diskfs_server_version = HURD_VERSION; @@ -437,6 +438,11 @@ main (int argc, char **argv) /* We must keep the REALNODE send right to remain the active translator for the underlying node. */ + /* Drop all privileges. */ + err = setnullauth(); + if (err) + error (1, err, "Could not drop privileges"); + pthread_mutex_unlock (&diskfs_root_node->lock); /* and so we die, leaving others to do the real work. */ diff --git a/trans/null.c b/trans/null.c index 1f985b39..8b3b4e0f 100644 --- a/trans/null.c +++ b/trans/null.c @@ -31,6 +31,7 @@ #include <fcntl.h> #include <limits.h> #include <argp.h> +#include <nullauth.h> const char *argp_program_version = STANDARD_HURD_VERSION (null); @@ -78,6 +79,10 @@ main (int argc, char **argv) if (err) error(3, err, "Contacting parent"); + err = setnullauth (); + if (err) + error(4, err, "Dropping privileges"); + /* Launch. */ ports_manage_port_operations_multithread (fsys->pi.bucket, trivfs_demuxer, 2 * 60 * 1000, 0, 0); diff --git a/utils/Makefile b/utils/Makefile index de33751a..8e8591f7 100644 --- a/utils/Makefile +++ b/utils/Makefile @@ -22,7 +22,7 @@ targets = shd ps settrans showtrans syncfs fsysopts \ storeinfo login w uptime ids loginpr sush vmstat portinfo \ devprobe vminfo addauth rmauth unsu setauth ftpcp ftpdir storecat \ storeread msgport rpctrace mount gcore fakeauth fakeroot remap \ - umount + umount nullauth special-targets = loginpr sush uptime fakeroot remap SRCS = shd.c ps.c settrans.c syncfs.c showtrans.c addauth.c rmauth.c \ @@ -31,7 +31,7 @@ SRCS = shd.c ps.c settrans.c syncfs.c showtrans.c addauth.c rmauth.c \ parse.c frobauth.c frobauth-mod.c setauth.c pids.c nonsugid.c \ unsu.c ftpcp.c ftpdir.c storeread.c storecat.c msgport.c \ rpctrace.c mount.c gcore.c fakeauth.c fakeroot.sh remap.sh \ - match-options.c umount.c + nullauth.c OBJS = $(filter-out %.sh,$(SRCS:.c=.o)) HURDLIBS = ps ihash store fshelp ports ftpconn shouldbeinlibc @@ -59,7 +59,7 @@ ftpcp ftpdir: ../libftpconn/libftpconn.a settrans: ../libfshelp/libfshelp.a ../libports/libports.a ps w ids settrans syncfs showtrans fsysopts storeinfo login vmstat portinfo \ devprobe vminfo addauth rmauth setauth unsu ftpcp ftpdir storeread \ - storecat msgport mount umount: \ + storecat msgport mount umount nullauth: \ ../libshouldbeinlibc/libshouldbeinlibc.a $(filter-out $(special-targets), $(targets)): %: %.o diff --git a/utils/nullauth.c b/utils/nullauth.c new file mode 100644 index 00000000..a0d5d1b8 --- /dev/null +++ b/utils/nullauth.c @@ -0,0 +1,90 @@ +/* Utility to drop all authentication credentials. + + Copyright (C) 2013 Free Software Foundation, Inc. + + Written by Justus Winter <4winter@informatik.uni-hamburg.de> + + This file is part of the GNU Hurd. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include <argp.h> +#include <error.h> +#include <nullauth.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <version.h> + +static char **args; + +const char const *argp_program_version = STANDARD_HURD_VERSION (nullauth); + +static const struct argp_option const options[] = +{ + { 0 } +}; + +static const char const doc[] = + "Drop all authentication credentials and run the given program."; +static const char const args_doc[] = + "PROGRAM [ARGUMENTS...]\tThe program to run"; + +error_t +parse_opt (int key, char *arg, struct argp_state *state) +{ + switch (key) + { + case ARGP_KEY_ARGS: + args = state->argv + state->next; + break; + + case ARGP_KEY_NO_ARGS: + argp_error (state, "expected program to run"); + return EINVAL; + + default: + return ARGP_ERR_UNKNOWN; + } + + return 0; +} + +static struct argp argp = { + options, + parse_opt, + args_doc, + doc, + NULL, +}; + +int +main (int argc, char *argv[]) +{ + error_t err; + + /* Parse our command line. This shouldn't ever return an error. */ + argp_parse (&argp, argc, argv, 0, 0, NULL); + + /* Drop all privileges. */ + err = setnullauth(); + if (err) + error (1, err, "Could not drop privileges"); + + execv (args[0], args); + error (1, errno, "execv"); + + /* Not reached. */ + return EXIT_FAILURE; +} |