Index: libexec/rtld-elf/rtld.c =================================================================== --- libexec/rtld-elf/rtld.c +++ libexec/rtld-elf/rtld.c @@ -384,6 +384,7 @@ caddr_t imgentry; char buf[MAXPATHLEN]; int argc, fd, i, phnum, rtld_argc; + int bsdflags; #ifdef __powerpc__ int old_auxv_format = 1; #endif @@ -445,11 +446,15 @@ main_argc = argc; main_argv = argv; - if (aux_info[AT_BSDFLAGS] != NULL && - (aux_info[AT_BSDFLAGS]->a_un.a_val & ELF_BSDF_SIGFASTBLK) != 0) - ld_fast_sigblock = true; - - trust = !issetugid(); + bsdflags = 0; + if (aux_info[AT_BSDFLAGS] != NULL) + bsdflags = aux_info[AT_BSDFLAGS]->a_un.a_val; + if ((bsdflags & ELF_BSDF_SIGFASTBLK) != 0) + ld_fast_sigblock = true; + if ((bsdflags & ELF_BSDF_ISSETUGID_PASSED) != 0) + trust = (bsdflags & ELF_BSDF_ISSETUGID) == 0; + else + trust = !issetugid(); md_abi_variant_hook(aux_info); Index: sys/kern/imgact_elf.c =================================================================== --- sys/kern/imgact_elf.c +++ sys/kern/imgact_elf.c @@ -69,6 +69,7 @@ #include #include #include +#include #include #include @@ -1332,7 +1333,7 @@ { Elf_Auxargs *args = (Elf_Auxargs *)imgp->auxargs; Elf_Auxinfo *argarray, *pos; - int error; + int error, bsdflags; argarray = pos = malloc(AT_COUNT * sizeof(*pos), M_TEMP, M_WAITOK | M_ZERO); @@ -1371,8 +1372,13 @@ AUXARGS_ENTRY(pos, AT_HWCAP, *imgp->sysent->sv_hwcap); if (imgp->sysent->sv_hwcap2 != NULL) AUXARGS_ENTRY(pos, AT_HWCAP2, *imgp->sysent->sv_hwcap2); - AUXARGS_ENTRY(pos, AT_BSDFLAGS, __elfN(sigfastblock) ? - ELF_BSDF_SIGFASTBLK : 0); + bsdflags = 0; + if (__elfN(sigfastblock)) + bsdflags |= ELF_BSDF_SIGFASTBLK; + bsdflags |= ELF_BSDF_ISSETUGID_PASSED; + if (kern_issetugid(imgp->proc)) + bsdflags |= ELF_BSDF_ISSETUGID; + AUXARGS_ENTRY(pos, AT_BSDFLAGS, bsdflags); AUXARGS_ENTRY(pos, AT_NULL, 0); free(imgp->auxargs, M_TEMP); Index: sys/kern/kern_prot.c =================================================================== --- sys/kern/kern_prot.c +++ sys/kern/kern_prot.c @@ -1218,6 +1218,21 @@ return (error1 ? error1 : error2 ? error2 : error3); } +int +kern_issetugid(struct proc *p) + +{ + /* + * Note: OpenBSD sets a P_SUGIDEXEC flag set at execve() time, + * we use P_SUGID because we consider changing the owners as + * "tainting" as well. + * This is significant for procs that start as root and "become" + * a user without an exec - programs cannot know *everything* + * that libc *might* have put in their data segment. + */ + return ((p->p_flag & P_SUGID) != 0); +} + #ifndef _SYS_SYSPROTO_H_ struct issetugid_args { int dummy; @@ -1229,15 +1244,7 @@ { struct proc *p = td->td_proc; - /* - * Note: OpenBSD sets a P_SUGIDEXEC flag set at execve() time, - * we use P_SUGID because we consider changing the owners as - * "tainting" as well. - * This is significant for procs that start as root and "become" - * a user without an exec - programs cannot know *everything* - * that libc *might* have put in their data segment. - */ - td->td_retval[0] = (p->p_flag & P_SUGID) ? 1 : 0; + td->td_retval[0] = kern_issetugid(p); return (0); } Index: sys/sys/elf_common.h =================================================================== --- sys/sys/elf_common.h +++ sys/sys/elf_common.h @@ -1458,5 +1458,7 @@ #define R_X86_64_IRELATIVE 37 #define ELF_BSDF_SIGFASTBLK 0x0001 /* Kernel supports fast sigblock */ +#define ELF_BSDF_ISSETUGID_PASSED 0x0002 +#define ELF_BSDF_ISSETUGID 0x0004 /* The process changed privileges without exec */ #endif /* !_SYS_ELF_COMMON_H_ */ Index: sys/sys/syscallsubr.h =================================================================== --- sys/sys/syscallsubr.h +++ sys/sys/syscallsubr.h @@ -149,6 +149,7 @@ int kern_getsockopt(struct thread *td, int s, int level, int name, void *optval, enum uio_seg valseg, socklen_t *valsize); int kern_ioctl(struct thread *td, int fd, u_long com, caddr_t data); +int kern_issetugid(struct proc *p); int kern_jail(struct thread *td, struct jail *j); int kern_jail_get(struct thread *td, struct uio *options, int flags); int kern_jail_set(struct thread *td, struct uio *options, int flags);