From 5fe915ee12806a1cb6a5ece20746a4f080de0a65 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sun, 17 Jun 2001 21:09:28 +0000 Subject: * hurd/Makefile (routines): Add lookup-retry. * hurd/hurdlookup.c (__hurd_file_name_lookup_retry): Broken out ... * hurd/lookup-retry.c: ... into here, new file. * sysdeps/mach/hurd/dl-sysdep.c (open_file): Call that instead using of duplicate code here. * hurd/hurdexec.c (_hurd_exec): Be robust for DTABLESIZE==0. * posix/regex.c: Avoid an access violation if malloc fails. --- hurd/hurdlookup.c | 285 ------------------------------------------------------ 1 file changed, 285 deletions(-) (limited to 'hurd/hurdlookup.c') diff --git a/hurd/hurdlookup.c b/hurd/hurdlookup.c index 5a54cfb9d8..a2db898235 100644 --- a/hurd/hurdlookup.c +++ b/hurd/hurdlookup.c @@ -19,11 +19,7 @@ #include #include #include -#include #include -#include "stdio-common/_itoa.h" -#include -#include /* Translate the error from dir_lookup into the error the user sees. */ @@ -102,287 +98,6 @@ __hurd_file_name_lookup (error_t (*use_init_port) } weak_alias (__hurd_file_name_lookup, hurd_file_name_lookup) -error_t -__hurd_file_name_lookup_retry (error_t (*use_init_port) - (int which, error_t (*operate) (file_t)), - file_t (*get_dtable_port) (int fd), - error_t (*lookup) - (file_t dir, char *name, - int flags, mode_t mode, - retry_type *do_retry, string_t retry_name, - mach_port_t *result), - enum retry_type doretry, - char retryname[1024], - int flags, mode_t mode, - file_t *result) -{ - error_t err; - char *file_name; - int nloops; - - error_t lookup_op (file_t startdir) - { - while (file_name[0] == '/') - file_name++; - - return lookup_error ((*lookup) (startdir, file_name, flags, mode, - &doretry, retryname, result)); - } - error_t reauthenticate (file_t unauth) - { - error_t err; - mach_port_t ref = __mach_reply_port (); - error_t reauth (auth_t auth) - { - return __auth_user_authenticate (auth, ref, - MACH_MSG_TYPE_MAKE_SEND, - result); - } - err = __io_reauthenticate (unauth, ref, MACH_MSG_TYPE_MAKE_SEND); - if (! err) - err = (*use_init_port) (INIT_PORT_AUTH, &reauth); - __mach_port_destroy (__mach_task_self (), ref); - __mach_port_deallocate (__mach_task_self (), unauth); - return err; - } - - if (! lookup) - lookup = __dir_lookup; - - nloops = 0; - err = 0; - do - { - file_t startdir = MACH_PORT_NULL; - int dirport = INIT_PORT_CWDIR; - - switch (doretry) - { - case FS_RETRY_REAUTH: - if (err = reauthenticate (*result)) - return err; - /* Fall through. */ - - case FS_RETRY_NORMAL: - if (nloops++ >= SYMLOOP_MAX) - { - __mach_port_deallocate (__mach_task_self (), *result); - return ELOOP; - } - - /* An empty RETRYNAME indicates we have the final port. */ - if (retryname[0] == '\0' && - /* If reauth'd, we must do one more retry on "" to give the new - translator a chance to make a new port for us. */ - doretry == FS_RETRY_NORMAL) - { - if (flags & O_NOFOLLOW) - { - /* In Linux, O_NOFOLLOW means to reject symlinks. If we - did an O_NOLINK lookup above and io_stat here to check - for S_IFLNK, a translator like firmlink could easily - spoof this check by not showing S_IFLNK, but in fact - redirecting the lookup to some other name - (i.e. opening the very same holes a symlink would). - - Instead we do an O_NOTRANS lookup above, and stat the - underlying node: if it has a translator set, and its - owner is not root (st_uid 0) then we reject it. - Since the motivation for this feature is security, and - that security presumes we trust the containing - directory, this check approximates the security of - refusing symlinks while accepting mount points. - Note that we actually permit something Linux doesn't: - we follow root-owned symlinks; if that is deemed - undesireable, we can add a final check for that - one exception to our general translator-based rule. */ - struct stat st; - err = __io_stat (*result, &st); - if (!err - && (st.st_mode & (S_IPTRANS|S_IATRANS))) - { - if (st.st_uid != 0) - err = ENOENT; - else if (st.st_mode & S_IPTRANS) - { - char buf[1024]; - char *trans = buf; - size_t translen = sizeof buf; - err = __file_get_translator (*result, - &trans, &translen); - if (!err - && translen > sizeof _HURD_SYMLINK - && !memcmp (trans, - _HURD_SYMLINK, sizeof _HURD_SYMLINK)) - err = ENOENT; - } - } - } - - /* We got a successful translation. Now apply any open-time - action flags we were passed. */ - - if (!err && (flags & O_TRUNC)) /* Asked to truncate the file. */ - err = __file_set_size (*result, 0); - - if (err) - __mach_port_deallocate (__mach_task_self (), *result); - return err; - } - - startdir = *result; - file_name = retryname; - break; - - case FS_RETRY_MAGICAL: - switch (retryname[0]) - { - case '/': - dirport = INIT_PORT_CRDIR; - if (*result != MACH_PORT_NULL) - __mach_port_deallocate (__mach_task_self (), *result); - if (nloops++ >= SYMLOOP_MAX) - return ELOOP; - file_name = &retryname[1]; - break; - - case 'f': - if (retryname[1] == 'd' && retryname[2] == '/') - { - int fd; - char *end; - int save = errno; - errno = 0; - fd = (int) strtol (&retryname[3], &end, 10); - if (end == NULL || errno || /* Malformed number. */ - /* Check for excess text after the number. A slash - is valid; it ends the component. Anything else - does not name a numeric file descriptor. */ - (*end != '/' && *end != '\0')) - { - errno = save; - return ENOENT; - } - if (! get_dtable_port) - err = EGRATUITOUS; - else - { - *result = (*get_dtable_port) (fd); - if (*result == MACH_PORT_NULL) - { - /* If the name was a proper number, but the file - descriptor does not exist, we return EBADF instead - of ENOENT. */ - err = errno; - errno = save; - } - } - errno = save; - if (err) - return err; - if (*end == '\0') - return 0; - else - { - /* Do a normal retry on the remaining components. */ - startdir = *result; - file_name = end + 1; /* Skip the slash. */ - break; - } - } - else - goto bad_magic; - break; - - case 'm': - if (retryname[1] == 'a' && retryname[2] == 'c' && - retryname[3] == 'h' && retryname[4] == 't' && - retryname[5] == 'y' && retryname[6] == 'p' && - retryname[7] == 'e') - { - error_t err; - struct host_basic_info hostinfo; - mach_msg_type_number_t hostinfocnt = HOST_BASIC_INFO_COUNT; - char *p; - /* XXX want client's host */ - if (err = __host_info (__mach_host_self (), HOST_BASIC_INFO, - (natural_t *) &hostinfo, - &hostinfocnt)) - return err; - if (hostinfocnt != HOST_BASIC_INFO_COUNT) - return EGRATUITOUS; - p = _itoa (hostinfo.cpu_subtype, &retryname[8], 10, 0); - *--p = '/'; - p = _itoa (hostinfo.cpu_type, &retryname[8], 10, 0); - if (p < retryname) - abort (); /* XXX write this right if this ever happens */ - if (p > retryname) - strcpy (retryname, p); - startdir = *result; - } - else - goto bad_magic; - break; - - case 't': - if (retryname[1] == 't' && retryname[2] == 'y') - switch (retryname[3]) - { - error_t opentty (file_t *result) - { - error_t err; - error_t ctty_open (file_t port) - { - if (port == MACH_PORT_NULL) - return ENXIO; /* No controlling terminal. */ - return __termctty_open_terminal (port, - flags, - result); - } - err = (*use_init_port) (INIT_PORT_CTTYID, &ctty_open); - if (! err) - err = reauthenticate (*result); - return err; - } - - case '\0': - return opentty (result); - case '/': - if (err = opentty (&startdir)) - return err; - strcpy (retryname, &retryname[4]); - break; - default: - goto bad_magic; - } - else - goto bad_magic; - break; - - default: - bad_magic: - return EGRATUITOUS; - } - break; - - default: - return EGRATUITOUS; - } - - if (startdir != MACH_PORT_NULL) - { - err = lookup_op (startdir); - __mach_port_deallocate (__mach_task_self (), startdir); - startdir = MACH_PORT_NULL; - } - else - err = (*use_init_port) (dirport, &lookup_op); - } while (! err); - - return err; -} -weak_alias (__hurd_file_name_lookup_retry, hurd_file_name_lookup_retry) - error_t __hurd_file_name_split (error_t (*use_init_port) (int which, error_t (*operate) (file_t)), -- cgit v1.2.1