(root)/
glibc-2.38/
elf/
tst-audit22.c
       1  /* Check DTAUDIT and vDSO interaction.
       2     Copyright (C) 2021-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <errno.h>
      20  #include <getopt.h>
      21  #include <limits.h>
      22  #include <inttypes.h>
      23  #include <string.h>
      24  #include <stdlib.h>
      25  #include <support/capture_subprocess.h>
      26  #include <support/check.h>
      27  #include <support/xstdio.h>
      28  #include <support/support.h>
      29  #include <sys/auxv.h>
      30  
      31  static int restart;
      32  #define CMDLINE_OPTIONS \
      33    { "restart", no_argument, &restart, 1 },
      34  
      35  static uintptr_t vdso_addr;
      36  
      37  static int
      38  handle_restart (void)
      39  {
      40    fprintf (stderr, "vdso: %p\n", (void*) vdso_addr);
      41    return 0;
      42  }
      43  
      44  static uintptr_t
      45  parse_address (const char *str)
      46  {
      47    void *r;
      48    TEST_COMPARE (sscanf (str, "%p\n", &r), 1);
      49    return (uintptr_t) r;
      50  }
      51  
      52  static inline bool
      53  startswith (const char *str, const char *pre)
      54  {
      55    size_t lenpre = strlen (pre);
      56    size_t lenstr = strlen (str);
      57    return lenstr >= lenpre && memcmp (pre, str, lenpre) == 0;
      58  }
      59  
      60  static int
      61  do_test (int argc, char *argv[])
      62  {
      63    vdso_addr = getauxval (AT_SYSINFO_EHDR);
      64    if (vdso_addr == 0)
      65      FAIL_UNSUPPORTED ("getauxval (AT_SYSINFO_EHDR) returned 0");
      66  
      67    /* We must have either:
      68       - One our fource parameters left if called initially:
      69         + path to ld.so         optional
      70         + "--library-path"      optional
      71         + the library path      optional
      72         + the application name  */
      73    if (restart)
      74      return handle_restart ();
      75  
      76    char *spargv[9];
      77    int i = 0;
      78    for (; i < argc - 1; i++)
      79      spargv[i] = argv[i + 1];
      80    spargv[i++] = (char *) "--direct";
      81    spargv[i++] = (char *) "--restart";
      82    spargv[i] = NULL;
      83  
      84    setenv ("LD_AUDIT", "tst-auditmod22.so", 0);
      85    struct support_capture_subprocess result
      86      = support_capture_subprogram (spargv[0], spargv);
      87    support_capture_subprocess_check (&result, "tst-audit22", 0, sc_allow_stderr);
      88  
      89    /* The respawned process should always print the vDSO address (otherwise it
      90       will fails as unsupported).  However, on some architectures the audit
      91       module might see the vDSO with l_addr being 0, meaning a fixed mapping
      92       (linux-gate.so).  In this case we don't check its value against
      93       AT_SYSINFO_EHDR one.  */
      94    uintptr_t vdso_process = 0;
      95    bool vdso_audit_found = false;
      96    uintptr_t vdso_audit = 0;
      97  
      98    FILE *out = fmemopen (result.err.buffer, result.err.length, "r");
      99    TEST_VERIFY (out != NULL);
     100    char *buffer = NULL;
     101    size_t buffer_length = 0;
     102    while (xgetline (&buffer, &buffer_length, out))
     103      {
     104        if (startswith (buffer, "vdso: "))
     105  	vdso_process = parse_address (buffer + strlen ("vdso: "));
     106        else if (startswith (buffer, "vdso found: "))
     107  	{
     108  	  vdso_audit = parse_address (buffer + strlen ("vdso found: "));
     109            vdso_audit_found = true;
     110  	}
     111      }
     112  
     113    TEST_COMPARE (vdso_audit_found, true);
     114    if (vdso_audit != 0)
     115      TEST_COMPARE (vdso_process, vdso_audit);
     116  
     117    free (buffer);
     118    xfclose (out);
     119  
     120    return 0;
     121  }
     122  
     123  #define TEST_FUNCTION_ARGV do_test
     124  #include <support/test-driver.c>