void test_self(void) { /* We're supposed to be setuid. Verify. */ int status; pid_t childpid; subtest = 1; if (issetugid() != 1) e(1); childpid = fork(); if (childpid == -1) e(2); else if (childpid == 0) { /* We're the child and should inherit the tainted status of the parent */ if (issetugid() != 1) e(3); /* Let's change to the bin user */ if (setuid((uid_t) 2) != 0) e(4); if (getuid() != (uid_t) 2) e(5); /* At this point, taint status should not have changed. */ if (issetugid() != 1) e(6); exit(EXIT_SUCCESS); } else { /* We're the parent. Wait for the child to finish */ wait(&status); } }
// Set the fallBackToHome parameter to true if we should fall back to the HOME environment variable if all else fails. Otherwise return NULL. static CFURLRef _CFCopyHomeDirURLForUser(const char *username, bool fallBackToHome) { const char *fixedHomePath = issetugid() ? NULL : __CFgetenv("CFFIXED_USER_HOME"); const char *homePath = NULL; // Calculate the home directory we will use // First try CFFIXED_USER_HOME (only if not setugid), then fall back to the upwd, then fall back to HOME environment variable CFURLRef home = NULL; if (!issetugid() && fixedHomePath) home = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, (uint8_t *)fixedHomePath, strlen(fixedHomePath), true); if (!home) { struct passwd *upwd = NULL; if (username) { upwd = getpwnam(username); } else { uid_t euid; __CFGetUGIDs(&euid, NULL); upwd = getpwuid(euid ?: getuid()); } if (upwd && upwd->pw_dir) { home = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, (uint8_t *)upwd->pw_dir, strlen(upwd->pw_dir), true); } } if (fallBackToHome && !home) homePath = __CFgetenv("HOME"); if (fallBackToHome && !home && homePath) home = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, (uint8_t *)homePath, strlen(homePath), true); return home; }
/* * hesiod_init -- * initialize a hesiod_p. */ int hesiod_init(void **context) { struct hesiod_p *ctx; const char *p, *configname; int serrno; _DIAGASSERT(context != NULL); ctx = calloc(1, sizeof(struct hesiod_p)); if (ctx) { *context = ctx; /* * don't permit overrides from environment * for set.id programs */ if (issetugid()) configname = NULL; else configname = getenv("HESIOD_CONFIG"); if (!configname) configname = _PATH_HESIOD_CONF; if (read_config_file(ctx, configname) >= 0) { /* * The default rhs can be overridden by an * environment variable, unless set.id. */ if (issetugid()) p = NULL; else p = getenv("HES_DOMAIN"); if (p) { if (ctx->rhs) free(ctx->rhs); ctx->rhs = malloc(strlen(p) + 2); if (ctx->rhs) { *ctx->rhs = '.'; strcpy(ctx->rhs + 1, (*p == '.') ? p + 1 : p); return 0; } else errno = ENOMEM; } else return 0; } } else errno = ENOMEM; serrno = errno; if (ctx) { if (ctx->lhs) free(ctx->lhs); if (ctx->rhs) free(ctx->rhs); free(ctx); } errno = serrno; return -1; }
void test_effugid(void) { /* Test taint status with different effective uid and gid */ pid_t childpid; int status; subtest = 6; /* Start with effective uid */ childpid = fork(); if (childpid == (pid_t) -1) e(1); else if (childpid == 0) { /* We're the child */ /* We should be tainted */ if (issetugid() != 1) e(2); /* Now execute a program without set{u,g}id; should not be tainted */ system("chmod 755 nobits"); if (execute("nobits", "0000") != 0) e(3); /* Change effective uid into current+42 and try nobits again. This time * it should be tainted */ if (seteuid(geteuid() + 42) != 0) e(4); if (execute("nobits", "0000") != 1) e(5); exit(EXIT_SUCCESS); } else { /* We're the parent, wait for the child to finish */ wait(&status); } /* Now test effective gid */ childpid = fork(); if (childpid == (pid_t) -1) e(1); else if (childpid == 0) { /* We're the child */ /* We should be tainted */ if (issetugid() != 1) e(2); /* Now execute a program without set{u,g}id; should not be tainted */ system("chmod 755 nobits"); if (execute("nobits", "0000") != 0) e(3); /* Change effective gid into current+42 and try nobits again. This time * it should be tainted */ if (seteuid(getegid() + 42) != 0) e(4); if (execute("nobits", "0000") != 1) e(5); exit(EXIT_SUCCESS); } else { /* We're the parent, wait for the child to finish */ wait(&status); } }
/* * Set the current process's credentials to match the passed credential. */ static int cred_set(struct cred *cred) { int error; error = setresuid(cred->cr_ruid, cred->cr_euid, cred->cr_svuid); if (error) return (error); error = setugid(cred->cr_issetugid); if (error) { perror("__setugid"); return (error); } #ifdef CHECK_CRED_SET { uid_t ruid, euid, svuid; error = getresuid(&ruid, &euid, &svuid); if (error) { perror("getresuid"); return (-1); } assert(ruid == cred->cr_ruid); assert(euid == cred->cr_euid); assert(svuid == cred->cr_svuid); assert(cred->cr_issetugid == issetugid()); } #endif /* !CHECK_CRED_SET */ return (0); }
struct mio_hdl * mio_open(const char *str, unsigned int mode, int nbio) { static char portany[] = MIO_PORTANY; struct mio_hdl *hdl; #ifdef DEBUG _sndio_debug_init(); #endif if ((mode & (MIO_OUT | MIO_IN)) == 0) return NULL; if (str == NULL) /* backward compat */ str = portany; if (strcmp(str, portany) == 0 && !issetugid()) { str = getenv("MIDIDEVICE"); if (str == NULL) str = portany; } if (strcmp(str, portany) == 0) { hdl = _mio_aucat_open("midithru/0", mode, nbio); if (hdl != NULL) return hdl; return _mio_rmidi_open("rmidi/0", mode, nbio); } if (_sndio_parsetype(str, "snd") || _sndio_parsetype(str, "midithru") || _sndio_parsetype(str, "midi")) return _mio_aucat_open(str, mode, nbio); if (_sndio_parsetype(str, "rmidi")) return _mio_rmidi_open(str, mode, nbio); DPRINTF("mio_open: %s: unknown device type\n", str); return NULL; }
void test_pid(void) { pid_t pid; int sc; pid = getpid(); printf( "getpid = %d\n", pid ); pid = __getpid(); printf( "__getpid = %d\n", pid ); pid = getppid(); printf( "getppid = %d\n", pid ); puts( "setsid - EPERM" ); pid = setsid(); rtems_test_assert( pid == -1 ); rtems_test_assert( errno == EPERM ); sc = issetugid(); rtems_test_assert( sc == 0 ); puts( "getpgrp - return local node - OK" ); pid = getpgrp(); printf( "getpgrp returned %d\n", pid ); }
struct sio_hdl * sio_open(const char *str, unsigned int mode, int nbio) { static char devany[] = SIO_DEVANY; struct sio_hdl *hdl; const char *p; #ifdef DEBUG _sndio_debug_init(); #endif if ((mode & (SIO_PLAY | SIO_REC)) == 0) return NULL; if (str == NULL) /* backward compat */ str = devany; if (strcmp(str, devany) == 0 && !issetugid()) { str = getenv("AUDIODEVICE"); if (str == NULL) str = devany; } if (strcmp(str, devany) == 0) { hdl = _sio_aucat_open("/0", mode, nbio); if (hdl != NULL) return hdl; return _sio_sun_open("/0", mode, nbio); } if ((p = _sndio_parsetype(str, "snd")) != NULL || (p = _sndio_parsetype(str, "aucat")) != NULL) return _sio_aucat_open(p, mode, nbio); if ((p = _sndio_parsetype(str, "rsnd")) != NULL || (p = _sndio_parsetype(str, "sun")) != NULL) { return _sio_sun_open(p, mode, nbio); } DPRINTF("sio_open: %s: unknown device type\n", str); return NULL; }
int _citrus_load_module(_citrus_module_t *rhandle, const char *encname) { const char *p; char path[PATH_MAX]; void *handle; int maj, min; if (_pathI18nModule == NULL) { p = getenv("PATH_I18NMODULE"); if (p != NULL && !issetugid()) { _pathI18nModule = strdup(p); if (_pathI18nModule == NULL) return (ENOMEM); } else _pathI18nModule = _PATH_I18NMODULE; } (void)snprintf(path, sizeof(path), "lib%s", encname); maj = I18NMODULE_MAJOR; min = -1; p = _findshlib(path, &maj, &min); if (!p) return (EINVAL); handle = libc_dlopen(p, RTLD_LAZY); if (!handle) { printf("%s", dlerror()); return (EINVAL); } *rhandle = (_citrus_module_t)handle; return (0); }
static void uu_die_internal(int status, const char *format, va_list alist) { uu_warn_internal(errno, format, alist); #ifdef DEBUG { char *cp; #if 0 if (!issetugid()) { #else if (!!(geteuid() == 0)) { #endif cp = getenv("UU_DIE_ABORTS"); if (cp != NULL && *cp != '\0') abort(); } } #endif exit(status); } void uu_vdie(const char *format, va_list alist) { uu_die_internal(UU_EXIT_FATAL, format, alist); }
Bool Id_IsSetUGid(void) { #if defined(__APPLE__) || defined(__FreeBSD__) || defined(sun) uid_t ruid = getuid(); uid_t euid = geteuid(); gid_t rgid = getgid(); gid_t egid = getegid(); return issetugid() == 1 || ruid != euid || rgid != egid; #elif defined(__linux__) uid_t ruid, euid, suid; gid_t rgid, egid, sgid; /* We want to make sure that this call always succeeds. */ if (IdGetRESUid(&ruid, &euid, &suid) != 0 || IdGetRESGid(&rgid, &egid, &sgid) != 0) { return TRUE; /* Conservative */ } return IdIsSetUGid() || ruid != euid || ruid != suid || rgid != egid || rgid != sgid; #else return TRUE; /* Conservative */ #endif }
int main(int argc, const char *argv[]) { struct kinfo_proc kproc; struct passwd *pw; if ((pw = getpwnam(_SETUID_REGRESS_USER)) == NULL) err(1, "unknown user \"%s\"", _SETUID_REGRESS_USER); /* * From the setuid man page: * The setuid() function sets the real and effective user IDs * and the saved set-user-ID of the current process */ if (setuid(pw->pw_uid) == -1) err(1, "setuid"); checkuids(pw->pw_uid, pw->pw_uid, pw->pw_uid, "getresuid"); /* should only respond to setuid upon exec */ if (issetugid()) errx(1, "process incorrectly marked as issetugid()"); if (read_kproc_pid(&kproc, getpid()) == -1) err(1, "kproc read failed"); if (!(kproc.p_psflags & PS_SUGID)) errx(1, "PS_SUGID not set"); if (kproc.p_psflags & PS_SUGIDEXEC) errx(1, "PS_SUGIDEXEC incorrectly set"); exit(0); }
const char *_CFProcessPath(void) { if (__CFProcessPath) return __CFProcessPath; #if DEPLOYMENT_TARGET_MACOSX if (!issetugid()) { const char *path = (char *)__CFgetenv("CFProcessPath"); if (path) { __CFProcessPath = strdup(path); __CFprogname = strrchr(__CFProcessPath, PATH_SEP); __CFprogname = (__CFprogname ? __CFprogname + 1 : __CFProcessPath); return __CFProcessPath; } } #endif uint32_t size = CFMaxPathSize; char buffer[size]; if (0 == _NSGetExecutablePath(buffer, &size)) { __CFProcessPath = strdup(buffer); __CFprogname = strrchr(__CFProcessPath, PATH_SEP); __CFprogname = (__CFprogname ? __CFprogname + 1 : __CFProcessPath); } if (!__CFProcessPath) { __CFProcessPath = ""; __CFprogname = __CFProcessPath; } return __CFProcessPath; }
char * secure_getenv (char const *name) { #if HAVE___SECURE_GETENV /* glibc */ return __secure_getenv (name); #elif HAVE_ISSETUGID /* OS X, FreeBSD, NetBSD, OpenBSD */ if (issetugid ()) return NULL; return getenv (name); #elif HAVE_GETUID && HAVE_GETEUID && HAVE_GETGID && HAVE_GETEGID /* other Unix */ if (geteuid () != getuid () || getegid () != getgid ()) return NULL; return getenv (name); #elif (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ /* native Windows */ /* On native Windows, there is no such concept as setuid or setgid binaries. - Programs launched as system services have high privileges, but they don't inherit environment variables from a user. - Programs launched by a user with "Run as Administrator" have high privileges and use the environment variables, but the user has been asked whether he agrees. - Programs launched by a user without "Run as Administrator" cannot gain high privileges, therefore there is no risk. */ return getenv (name); #else return NULL; #endif }
static int tmp(void) { sigset_t set, oset; size_t len; int fd; char *envtmp; char path[PATH_MAX]; #if HAVE_ISSETUGID if (issetugid()) envtmp = NULL; else #endif envtmp = getenv("TMPDIR"); len = snprintf(path, sizeof(path), "%s/bt.XXXXXX", envtmp ? envtmp : _PATH_TMP); if (len >= sizeof(path)) return -1; (void)sigfillset(&set); (void)sigprocmask(SIG_BLOCK, &set, &oset); if ((fd = mkstemp(path)) != -1) { (void)unlink(path); (void)fcntl(fd, F_SETFD, FD_CLOEXEC); } (void)sigprocmask(SIG_SETMASK, &oset, NULL); return(fd); }
XPC_RETURNS_RETAINED static xpc_pipe_t _od_xpc_pipe(bool resetPipe) { static dispatch_once_t once; xpc_pipe_t result = NULL; #ifdef __i386__ if (xpc_pipe_create == NULL) { _si_disable_opendirectory(); return NULL; } #endif dispatch_once(&once, ^(void) { char *rc_xbs; /* if this is a build environment we ignore opendirectoryd */ rc_xbs = getenv("RC_XBS"); if ((issetugid() == 0) && (rc_xbs != NULL) && (strcmp(rc_xbs, "YES") == 0)) { _si_opendirectory_disabled = 1; return; } pthread_atfork(_od_fork_prepare, _od_fork_parent, _od_fork_child); });
/* * Check for environment variables altering the configuration as described * in resolv.conf(5). Although not documented there, this feature is disabled * for setuid/setgid programs. */ static void asr_ctx_envopts(struct asr_ctx *ac) { char buf[4096], *e; size_t s; if (issetugid()) { ac->ac_options |= RES_NOALIASES; return; } if ((e = getenv("RES_OPTIONS")) != NULL) { strlcpy(buf, "options ", sizeof buf); strlcat(buf, e, sizeof buf); s = strlcat(buf, "\n", sizeof buf); if (s < sizeof buf) asr_ctx_parse(ac, buf); } if ((e = getenv("LOCALDOMAIN")) != NULL) { strlcpy(buf, "search ", sizeof buf); strlcat(buf, e, sizeof buf); s = strlcat(buf, "\n", sizeof buf); if (s < sizeof buf) asr_ctx_parse(ac, buf); } }
int acl_unsafe(void) { return (geteuid() != getuid() #ifdef HAS_ISSETUGID || issetugid() #endif || getgid() != getegid()); }
int main (void) { int status; status = issetugid (); return 0; }
/* * expand tilde from the passwd file. */ static const Char * globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob) { struct passwd *pwd; char *h; const Char *p; Char *b, *eb; if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE)) return pattern; /* * Copy up to the end of the string or / */ eb = &patbuf[patbuf_len - 1]; for (p = pattern + 1, h = (char *) patbuf; h < (char *)eb && *p && *p != SLASH; *h++ = *p++) continue; *h = EOS; if (((char *) patbuf)[0] == EOS) { /* * handle a plain ~ or ~/ by expanding $HOME first (iff * we're not running setuid or setgid) and then trying * the password file */ if (issetugid() != 0 || (h = getenv("HOME")) == NULL) { if (((h = getlogin()) != NULL && (pwd = getpwnam(h)) != NULL) || (pwd = getpwuid(getuid())) != NULL) h = pwd->pw_dir; else return pattern; } } else { /* * Expand a ~user */ if ((pwd = getpwnam((char*) patbuf)) == NULL) return pattern; else h = pwd->pw_dir; } /* Copy the home directory */ for (b = patbuf; b < eb && *h; *b++ = *h++) continue; /* Append the rest of the pattern */ while (b < eb && (*b++ = *p++) != EOS) continue; *b = EOS; return patbuf; }
char * tempnam(const char *dir, const char *pfx) { int sverrno, len; char *f, *name; if (!(name = malloc(PATH_MAX))) return(NULL); if (!pfx) pfx = "tmp."; if (issetugid() == 0 && (f = getenv("TMPDIR")) && *f != '\0') { len = snprintf(name, PATH_MAX, "%s%s%sXXXXXXXXXX", f, f[strlen(f) - 1] == '/' ? "" : "/", pfx); if (len < 0 || len >= PATH_MAX) { errno = ENAMETOOLONG; return(NULL); } if ((f = _mktemp(name))) return(f); } if (dir != NULL) { f = *dir ? (char *)dir : "."; len = snprintf(name, PATH_MAX, "%s%s%sXXXXXXXXXX", f, f[strlen(f) - 1] == '/' ? "" : "/", pfx); if (len < 0 || len >= PATH_MAX) { errno = ENAMETOOLONG; return(NULL); } if ((f = _mktemp(name))) return(f); } f = P_tmpdir; len = snprintf(name, PATH_MAX, "%s%sXXXXXXXXX", f, pfx); if (len < 0 || len >= PATH_MAX) { errno = ENAMETOOLONG; return(NULL); } if ((f = _mktemp(name))) return(f); f = _PATH_TMP; len = snprintf(name, PATH_MAX, "%s%sXXXXXXXXX", f, pfx); if (len < 0 || len >= PATH_MAX) { errno = ENAMETOOLONG; return(NULL); } if ((f = _mktemp(name))) return(f); sverrno = errno; free(name); errno = sverrno; return(NULL); }
/* * "Started with special privileges" means "started out set-UID or set-GID", * or run as the root user or group. */ gboolean started_with_special_privs(void) { g_assert(init_process_policies_called); #ifdef HAVE_ISSETUGID return issetugid(); #else return (ruid != euid || rgid != egid || ruid == 0 || rgid == 0); #endif }
void umem_error_enter(const char *error_str) { #ifndef UMEM_STANDALONE if (umem_output && !issetugid()) (void) write(UMEM_ERRFD, error_str, strlen(error_str)); #endif umem_log_enter(error_str, 1); }
char * secure_getenv (char const *name) { #if HAVE___SECURE_GETENV return __secure_getenv (name); #else if (issetugid ()) return 0; return getenv (name); #endif }
_nc_env_access(void) { #if HAVE_ISSETUGID if (issetugid()) return FALSE; #elif HAVE_GETEUID && HAVE_GETEGID if (getuid() != geteuid() || getgid() != getegid()) return FALSE; #endif return getuid() != 0 && geteuid() != 0; /* ...finally, disallow root */ }
/* * Return a process credential describing the current process. */ static int cred_get(struct cred *cred) { int error; error = getresuid(&cred->cr_ruid, &cred->cr_euid, &cred->cr_svuid); if (error) return (error); cred->cr_issetugid = issetugid(); return (0); }
/* * set the debug level from an environment string. Bogus values are * silently ignored. */ void _rthread_debug_init(void) { char *envp; char *rem; if (issetugid()) return; envp = getenv(RTHREAD_ENV_DEBUG); if (envp) { _rthread_debug_level = (int) strtol(envp, &rem, 0); if (*rem || _rthread_debug_level < 0) _rthread_debug_level = 0; } }
static void * poll_init(struct event_base *base) { struct pollop *pollop; /* Disable poll when this environment variable is set */ if (!issetugid() && getenv("EVENT_NOPOLL")) return (NULL); if (!(pollop = calloc(1, sizeof(struct pollop)))) return (NULL); evsignal_init(base); return (pollop); }
static __inline void init_cache(void) { rwlock_wrlock(&lock); if (!isinit) { _CITRUS_HASH_INIT(&shared_pool, CI_HASH_SIZE); TAILQ_INIT(&shared_unused); shared_max_reuse = -1; if (!issetugid() && getenv(CI_ENV_MAX_REUSE)) shared_max_reuse = atoi(getenv(CI_ENV_MAX_REUSE)); if (shared_max_reuse < 0) shared_max_reuse = CI_INITIAL_MAX_REUSE; isinit = true; } rwlock_unlock(&lock); }
static void uu_die_internal(int status, const char *format, va_list alist) { uu_warn_internal(errno, format, alist); #ifdef DEBUG { char *cp; if (!issetugid()) { cp = getenv("UU_DIE_ABORTS"); if (cp != NULL && *cp != '\0') abort(); } } #endif exit(status); }