From e40670ee488a5dcea90a57efb58ecd04ee39a302 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Sun, 16 Jun 2002 23:34:43 +0000 Subject: * cygheap.h (cygheap_user::issetuid): New method. * dtable.cc (dtable::vfork_child_dup): Use new method to determine if we are in "setuid mode." * fork.cc (fork_parent): Ditto. * spawn.cc (spawn_guts): Ditto. * syscalls.cc (seteuid32): Ditto. (setegid32): Ditto. * environ.cc (spenv::retrieve): (Suggested by Pierre Humblet) Do potential recalculation of cygheap_user stuff when in setuid mode. Return special value when environment variable exists but should not be added. (build_env): Don't add retrieved value to dstp if it is 'dont_add'. --- winsup/cygwin/ChangeLog | 15 +++++++++++++++ winsup/cygwin/cygheap.h | 4 ++++ winsup/cygwin/dtable.cc | 4 ++-- winsup/cygwin/environ.cc | 34 ++++++++++++++++++++++------------ winsup/cygwin/fork.cc | 7 +++---- winsup/cygwin/spawn.cc | 2 +- winsup/cygwin/syscalls.cc | 11 ++++------- 7 files changed, 51 insertions(+), 26 deletions(-) (limited to 'winsup') diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index cfe5ec628..85b3aae06 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,18 @@ +2002-06-16 Christopher Faylor + + * cygheap.h (cygheap_user::issetuid): New method. + * dtable.cc (dtable::vfork_child_dup): Use new method to determine if + we are in "setuid mode." + * fork.cc (fork_parent): Ditto. + * spawn.cc (spawn_guts): Ditto. + * syscalls.cc (seteuid32): Ditto. + (setegid32): Ditto. + * environ.cc (spenv::retrieve): (Suggested by Pierre Humblet) Do + potential recalculation of cygheap_user stuff when in setuid mode. + Return special value when environment variable exists but should not be + added. + (build_env): Don't add retrieved value to dstp if it is 'dont_add'. + 2002-06-16 Christopher Faylor Changes suggested by Pierre Humblet. diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h index 032f6a40a..ff598e548 100644 --- a/winsup/cygwin/cygheap.h +++ b/winsup/cygwin/cygheap.h @@ -144,6 +144,10 @@ public: PSID sid () const { return psid; } PSID orig_sid () const { return orig_psid; } const char *ontherange (homebodies what, struct passwd * = NULL); + bool issetuid () const + { + return impersonated && token != INVALID_HANDLE_VALUE; + } }; /* cwd cache stuff. */ diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc index 241528a3d..b94e9cf38 100644 --- a/winsup/cygwin/dtable.cc +++ b/winsup/cygwin/dtable.cc @@ -618,7 +618,7 @@ dtable::vfork_child_dup () int res = 1; /* Remove impersonation */ - if (cygheap->user.impersonated && cygheap->user.token != INVALID_HANDLE_VALUE) + if (cygheap->user.issetuid ()) RevertToSelf (); for (size_t i = 0; i < size; i++) @@ -638,7 +638,7 @@ dtable::vfork_child_dup () out: /* Restore impersonation */ - if (cygheap->user.impersonated && cygheap->user.token != INVALID_HANDLE_VALUE) + if (cygheap->user.issetuid ()) ImpersonateLoggedOnUser (cygheap->user.token); ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "dup"); diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc index 9fab98619..12ae6e76f 100644 --- a/winsup/cygwin/environ.cc +++ b/winsup/cygwin/environ.cc @@ -760,6 +760,8 @@ struct spenv __attribute__ ((regparm (3))); }; +char env_dontadd[] = ""; + /* Keep this list in upper case and sorted */ static NO_COPY spenv spenvs[] = { @@ -781,18 +783,21 @@ spenv::retrieve (bool no_envblock, const char *const envname) if (from_cygheap) { const char *p; - if (!envname) - return NULL; /* No need to force these into the + if (!cygheap->user.issetuid ()) + { + if (!envname) + return NULL; /* No need to force these into the environment */ - if (no_envblock) - return cstrdup1 (envname); /* Don't really care what it's set to + if (no_envblock) + return cstrdup1 (envname); /* Don't really care what it's set to if we're calling a cygwin program */ + } - /* Make a FOO=BAR entry from the value returned by the cygheap_user - method. */ - if (!(p = (cygheap->user.*from_cygheap) ())) - return NULL; + /* Calculate (potentially) value for given environment variable. */ + p = (cygheap->user.*from_cygheap) (); + if (!p || (no_envblock && !envname)) + return env_dontadd; char *s = (char *) cmalloc (HEAP_1_STR, namelen + strlen (p) + 1); strcpy (s, name); (void) strcpy (s + namelen, p); @@ -846,23 +851,28 @@ build_env (const char * const *envp, char *&envblock, int &envc, int tl = 0; /* Iterate over input list, generating a new environment list and refreshing "special" entries, if necessary. */ - for (srcp = envp, dstp = newenv; *srcp; srcp++, dstp++) + for (srcp = envp, dstp = newenv; *srcp; srcp++) { /* Look for entries that require special attention */ for (unsigned i = 0; i < SPENVS_SIZE; i++) if (!saw_spenv[i] && (*dstp = spenvs[i].retrieve (no_envblock, *srcp))) { saw_spenv[i] = 1; - goto next; + if (*dstp == env_dontadd) + goto next1; + goto next0; } /* Add entry to new environment */ *dstp = cstrdup1 (*srcp); - next: + next0: /* If necessary, calculate rough running total for envblock size */ if (!no_envblock) tl += strlen (*dstp) + 1; + dstp++; + next1: + continue; } /* Fill in any required-but-missing environment variables. */ @@ -870,7 +880,7 @@ build_env (const char * const *envp, char *&envblock, int &envc, if (!saw_spenv[i]) { *dstp = spenvs[i].retrieve (no_envblock); - if (*dstp) + if (*dstp && *dstp != env_dontadd) { if (!no_envblock) tl += strlen (*dstp) + 1; diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index 7a7cac0ba..e6fb91037 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -441,7 +441,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll, si.cbReserved2 = sizeof(ch); /* Remove impersonation */ - if (cygheap->user.impersonated && cygheap->user.token != INVALID_HANDLE_VALUE) + if (cygheap->user.issetuid ()) RevertToSelf (); ch.parent = hParent; @@ -490,8 +490,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll, ForceCloseHandle(subproc_ready); ForceCloseHandle(forker_finished); /* Restore impersonation */ - if (cygheap->user.impersonated - && cygheap->user.token != INVALID_HANDLE_VALUE) + if (cygheap->user.issetuid ()) ImpersonateLoggedOnUser (cygheap->user.token); cygheap_setup_for_child_cleanup (newheap, &ch, 0); return -1; @@ -519,7 +518,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll, strcpy(forked->progname, myself->progname); /* Restore impersonation */ - if (cygheap->user.impersonated && cygheap->user.token != INVALID_HANDLE_VALUE) + if (cygheap->user.issetuid ()) ImpersonateLoggedOnUser (cygheap->user.token); ProtectHandle (pi.hThread); diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 195bfcf4b..909cb0008 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -610,7 +610,7 @@ spawn_guts (const char * prog_arg, const char *const *argv, cygbench ("spawn-guts"); ciresrv.mount_h = cygwin_mount_h; - if (!cygheap->user.impersonated || cygheap->user.token == INVALID_HANDLE_VALUE) + if (!cygheap->user.issetuid ()) { PSECURITY_ATTRIBUTES sec_attribs = sec_user_nih (sa_buf); ciresrv.moreinfo->envp = build_env (envp, envblock, ciresrv.moreinfo->envc, diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 1f6fab536..1bce92f0b 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -2093,9 +2093,8 @@ seteuid32 (__uid32_t uid) failed: cygheap->user.token = sav_token; cygheap->user.impersonated = sav_impersonated; - if ( cygheap->user.token != INVALID_HANDLE_VALUE && - cygheap->user.impersonated && - !ImpersonateLoggedOnUser (cygheap->user.token)) + if (cygheap->user.issetuid () + && !ImpersonateLoggedOnUser (cygheap->user.token)) system_printf ("Impersonating in seteuid failed: %E"); return -1; } @@ -2144,8 +2143,7 @@ setegid32 (__gid32_t gid) myself->gid = gid; /* If impersonated, update primary group and revert */ - if (cygheap->user.token != INVALID_HANDLE_VALUE - && cygheap->user.impersonated) + if (cygheap->user.issetuid ()) { if (!SetTokenInformation (cygheap->user.token, TokenPrimaryGroup, @@ -2166,8 +2164,7 @@ setegid32 (__gid32_t gid) "TokenPrimaryGroup): %E"); CloseHandle (ptok); } - if (cygheap->user.token != INVALID_HANDLE_VALUE - && cygheap->user.impersonated + if (cygheap->user.issetuid () && !ImpersonateLoggedOnUser (cygheap->user.token)) system_printf ("Impersonating in setegid failed: %E"); return 0; -- cgit v1.2.3