Index: lib/libc/gen/auxv.3 =================================================================== --- lib/libc/gen/auxv.3 +++ lib/libc/gen/auxv.3 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 25, 2019 +.Dd August 3, 2019 .Dt ELF_AUX_INFO 3 .Os .Sh NAME @@ -45,23 +45,60 @@ The following values, defined in .In sys/elf_common.h can be requested: -.Bl -tag -width AT_OSRELDATE +.Bl -tag -width AT_PAGESIZESLEN +.It AT_BASE +The ELF interpreter's base address. .It AT_CANARY The canary value for SSP. +.It AT_CANARYLEN +Length of the AT_CANARY value in bytes. +.It AT_ENTRY +The ELF interpreter's entry point. +.It AT_EGID +Effective group ID under which the process is executing (unused). +.It AT_EHDRFLAGS +Value of the ELF header's e_flags field. +.It AT_EXECFD +File descriptor of the program to load. +.It AT_EXECPATH +Filesystem path of the program to load. +.It AT_EUID +The effective user ID under which the process is executing (unused). +.It AT_FLAGS +Process flags. +.It AT_GID +The real ID of the group that executed the process (unused). .It AT_HWCAP -CPU / hardware feature flags. +CPU / hardware feature flags. The values are architecture-dependent +and found in +.In machine/elf.h . .It AT_HWCAP2 -CPU / hardware feature flags. +CPU / hardware feature flags. The values are architecture-dependent +and found in +.In machine/elf.h . .It AT_NCPUS Number of CPUs. .It AT_OSRELDATE Kernel OSRELDATE. .It AT_PAGESIZES Vector of page sizes. +.It AT_PAGESIZESLEN +Length of the AT_PAGESIZES vector in bytes. .It AT_PAGESZ Page size in bytes. +.It AT_PHDR +Program header of program already loaded. +.It AT_PHENT +Size of each program header entry. +.It AT_PHNUM +Number of program header entries. +.It AT_STACKPROT +Stack protection flags. The values are defined in +.In vm/vm.h . .It AT_TIMEKEEP Pointer to VDSO timehands (for library internal use). +.It AT_UID +The real ID of the user that executed the process (unused). .El .Sh RETURN VALUES Returns zero on success, or an error number on failure. @@ -80,7 +117,5 @@ function appeared in .Fx 12.0 . .Sh BUGS -Only a small subset of available auxiliary info vector items are -accessible with this function. Some items require a "right-sized" buffer while others just require a "big enough" buffer. Index: lib/libc/gen/auxv.c =================================================================== --- lib/libc/gen/auxv.c +++ lib/libc/gen/auxv.c @@ -70,9 +70,15 @@ static pthread_once_t aux_once = PTHREAD_ONCE_INIT; static int pagesize, osreldate, canary_len, ncpus, pagesizes_len; static bool hwcap_present, hwcap2_present; -static char *canary, *pagesizes; +static bool execfd_present, stackprot_present; +static bool egid_present, euid_present, gid_present, uid_present; +static char *canary, *execpath, *pagesizes; static void *timekeep; static u_long hwcap, hwcap2; +static u_long base, e_hdr, entry, flags; +static u_long phdr, phent, phnum; +static u_long egid, euid, gid, uid; +static int execfd, execpath_len, stackprot; static void init_aux(void) @@ -81,6 +87,10 @@ for (aux = __elf_aux_vector; aux->a_type != AT_NULL; aux++) { switch (aux->a_type) { + case AT_BASE: + base = (u_long)(aux->a_un.a_val); + break; + case AT_CANARY: canary = (char *)(aux->a_un.a_ptr); break; @@ -89,6 +99,43 @@ canary_len = aux->a_un.a_val; break; + case AT_EGID: + egid_present = true; + egid = aux->a_un.a_val; + break; + + case AT_EHDRFLAGS: + e_hdr = (u_long)(aux->a_un.a_val); + break; + + case AT_ENTRY: + entry = (u_long)(aux->a_un.a_ptr); + break; + + case AT_EUID: + euid_present = true; + euid = aux->a_un.a_val; + break; + + case AT_EXECFD: + execfd_present = true; + execfd = aux->a_un.a_val; + break; + + case AT_EXECPATH: + execpath = (char *)(aux->a_un.a_ptr); + execpath_len = strlen(execpath) + 1; + break; + + case AT_FLAGS: + flags = (u_long)(aux->a_un.a_val); + break; + + case AT_GID: + gid_present = true; + gid = aux->a_un.a_val; + break; + case AT_HWCAP: hwcap_present = true; hwcap = (u_long)(aux->a_un.a_val); @@ -115,13 +162,35 @@ pagesize = aux->a_un.a_val; break; + case AT_PHDR: + phdr = (u_long)(aux->a_un.a_val); + break; + + case AT_PHENT: + phent = (u_long)(aux->a_un.a_val); + break; + + case AT_PHNUM: + phnum = (u_long)(aux->a_un.a_val); + break; + case AT_OSRELDATE: osreldate = aux->a_un.a_val; break; + case AT_STACKPROT: + stackprot_present = true; + stackprot = aux->a_un.a_val; + break; + case AT_TIMEKEEP: timekeep = aux->a_un.a_ptr; break; + + case AT_UID: + uid_present = true; + uid = aux->a_un.a_val; + break; } } } @@ -139,6 +208,16 @@ _once(&aux_once, init_aux); switch (aux) { + case AT_BASE: + if (buflen >= sizeof(u_long)) { + if (base != 0) { + *(u_long *)buf = base; + res = 0; + } else + res = ENOENT; + } else + res = EINVAL; + break; case AT_CANARY: if (canary_len >= buflen) { if (canary != NULL) { @@ -151,6 +230,90 @@ } else res = EINVAL; break; + case AT_CANARYLEN: + if (buflen >= sizeof(int)) { + if (canary_len != 0) { + *(int *)buf = canary_len; + res = 0; + } else + res = ENOENT; + } else + res = EINVAL; + break; + case AT_EGID: + if (buflen >= sizeof(u_long)) { + if (egid_present) { + *(u_long *)buf = egid; + res = 0; + } else + res = ENOENT; + } else + res = EINVAL; + break; + case AT_EHDRFLAGS: + if (buflen >= sizeof(u_long)) { + *(u_long *)buf = e_hdr; + res = 0; + } else + res = EINVAL; + break; + case AT_ENTRY: + if (buflen >= sizeof(u_long)) { + if (entry != 0) { + *(u_long *)buf = entry; + res = 0; + } else + res = ENOENT; + } else + res = EINVAL; + break; + case AT_EUID: + if (buflen >= sizeof(u_long)) { + if (euid_present) { + *(u_long *)buf = euid; + res = 0; + } else + res = ENOENT; + } else + res = EINVAL; + break; + case AT_EXECFD: + if (buflen >= sizeof(u_long)) { + if (execfd_present) { + *(u_long *)buf = execfd; + res = 0; + } else + res = ENOENT; + } else + res = EINVAL; + break; + case AT_EXECPATH: + if (buflen >= execpath_len) { + if (execpath != NULL) { + memcpy(buf, execpath, execpath_len); + res = 0; + } else + res = ENOENT; + } else + res = EINVAL; + break; + case AT_FLAGS: + if (buflen >= sizeof(u_long)) { + *(u_long *)buf = flags; + res = 0; + } else + res = EINVAL; + break; + case AT_GID: + if (buflen >= sizeof(u_long)) { + if (gid_present) { + *(u_long *)buf = gid; + res = 0; + } else + res = ENOENT; + } else + res = EINVAL; + break; case AT_HWCAP: if (buflen == sizeof(u_long)) { if (hwcap_present) { @@ -191,6 +354,16 @@ } else res = EINVAL; break; + case AT_PAGESIZESLEN: + if (buflen >= sizeof(int)) { + if (pagesizes_len != 0) { + *(int *)buf = pagesizes_len; + res = 0; + } else + res = ENOENT; + } else + res = EINVAL; + break; case AT_PAGESZ: if (buflen == sizeof(int)) { if (pagesize != 0) { @@ -201,6 +374,36 @@ } else res = EINVAL; break; + case AT_PHDR: + if (buflen >= sizeof(u_long)) { + if (phdr != 0) { + *(u_long *)buf = phdr; + res = 0; + } else + res = ENOENT; + } else + res = EINVAL; + break; + case AT_PHENT: + if (buflen >= sizeof(u_long)) { + if (phent != 0) { + *(u_long *)buf = phent; + res = 0; + } else + res = ENOENT; + } else + res = EINVAL; + break; + case AT_PHNUM: + if (buflen >= sizeof(u_long)) { + if (phnum != 0) { + *(u_long *)buf = phnum; + res = 0; + } else + res = ENOENT; + } else + res = EINVAL; + break; case AT_OSRELDATE: if (buflen == sizeof(int)) { if (osreldate != 0) { @@ -211,6 +414,16 @@ } else res = EINVAL; break; + case AT_STACKPROT: + if (buflen >= sizeof(int)) { + if (stackprot_present) { + *(int *)buf = stackprot; + res = 0; + } else + res = ENOENT; + } else + res = EINVAL; + break; case AT_TIMEKEEP: if (buflen == sizeof(void *)) { if (timekeep != NULL) { @@ -221,6 +434,16 @@ } else res = EINVAL; break; + case AT_UID: + if (buflen >= sizeof(u_long)) { + if (uid_present) { + *(u_long *)buf = uid; + res = 0; + } else + res = ENOENT; + } else + res = EINVAL; + break; default: res = ENOENT; break;