Bug 234523

Summary: elf_aux_info() doesn't expose all AT_* vectors
Product: Base System Reporter: Jan Beich <jbeich>
Component: binAssignee: Mitchell Horne <mhorne>
Status: In Progress ---    
Severity: Affects Only Me CC: cem, mhorne
Priority: ---    
Version: CURRENT   
Hardware: Any   
OS: Any   

Description Jan Beich freebsd_committer 2018-12-31 11:20:12 UTC
KERN_PROC_AUXV allows accessing arbitrary AT_* vectors but libc exposes only few via elf_aux_info(3). For example, one may want to rely on libc caching AT_EXECPATH instead of retrieving KERN_PROC_PATHNAME directly.

  $ cat elf_aux_info.c
  #include <sys/auxv.h>
  #include <limits.h>
  #include <stdio.h>

  int main()
  {
      char exe[PATH_MAX + 1] = {0};
      elf_aux_info(AT_EXECPATH, &exe, sizeof(exe));
      printf("%s\n", exe);
      return 0;
  }

  $ make elf_aux_info
  $ ./elf_aux_info

  $

vs.

  $ cat getauxval_naive.c
  #include <sys/param.h>
  #include <sys/sysctl.h>
  #include <elf.h>
  #include <errno.h>
  #include <unistd.h>
  #include <stdio.h>

  static unsigned long getauxval(unsigned long type) {
    Elf_Auxinfo auxv[AT_COUNT];
    size_t len = sizeof(auxv);
    int mib[] = {
      CTL_KERN,
      KERN_PROC,
      KERN_PROC_AUXV,
      getpid(),
    };

    if (sysctl(mib, nitems(mib), auxv, &len, NULL, 0) != -1) {
      for (size_t i = 0; i < nitems(auxv); i++)
	if ((unsigned long)auxv[i].a_type == type)
	  return auxv[i].a_un.a_val;

      errno = ENOENT;
    }
    return 0;
  }

  int main()
  {
      printf("%s\n", (char *)getauxval(AT_EXECPATH));
      return 0;
  }

  $ make getauxval_naive
  $ ./getauxval_naive
  /home/foo/getauxval_naive
  $