1  /* Check DT_AUDIT with dlmopen.
       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 <array_length.h>
      20  #include <getopt.h>
      21  #include <string.h>
      22  #include <stdlib.h>
      23  #include <unistd.h>
      24  #include <gnu/lib-names.h>
      25  #include <support/capture_subprocess.h>
      26  #include <support/check.h>
      27  #include <support/xdlfcn.h>
      28  #include <support/xstdio.h>
      29  #include <support/support.h>
      30  
      31  static int restart;
      32  #define CMDLINE_OPTIONS \
      33    { "restart", no_argument, &restart, 1 },
      34  
      35  static int
      36  handle_restart (void)
      37  {
      38    {
      39      void *h = xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW);
      40  
      41      pid_t (*s) (void) = xdlsym (h, "getpid");
      42      TEST_COMPARE (s (), getpid ());
      43  
      44      xdlclose (h);
      45    }
      46  
      47    {
      48      void *h = xdlmopen (LM_ID_NEWLM, "tst-audit18mod.so", RTLD_NOW);
      49  
      50      int (*foo) (void) = xdlsym (h, "foo");
      51      TEST_COMPARE (foo (), 10);
      52  
      53      xdlclose (h);
      54    }
      55  
      56    return 0;
      57  }
      58  
      59  static int
      60  do_test (int argc, char *argv[])
      61  {
      62    /* We must have either:
      63       - One our fource parameters left if called initially:
      64         + path to ld.so         optional
      65         + "--library-path"      optional
      66         + the library path      optional
      67         + the application name  */
      68  
      69    if (restart)
      70      return handle_restart ();
      71  
      72    char *spargv[9];
      73    int i = 0;
      74    for (; i < argc - 1; i++)
      75      spargv[i] = argv[i + 1];
      76    spargv[i++] = (char *) "--direct";
      77    spargv[i++] = (char *) "--restart";
      78    spargv[i] = NULL;
      79  
      80    setenv ("LD_AUDIT", "tst-auditmod18.so", 0);
      81    struct support_capture_subprocess result
      82      = support_capture_subprogram (spargv[0], spargv);
      83    support_capture_subprocess_check (&result, "tst-audit18", 0, sc_allow_stderr);
      84  
      85    struct
      86    {
      87      const char *name;
      88      bool found;
      89    } audit_iface[] =
      90    {
      91      { "la_version", false },
      92      { "la_objsearch", false },
      93      { "la_activity", false },
      94      { "la_objopen", false },
      95      { "la_objclose", false },
      96      { "la_preinit", false },
      97  #if __WORDSIZE == 32
      98      { "la_symbind32", false },
      99  #elif __WORDSIZE == 64
     100      { "la_symbind64", false },
     101  #endif
     102    };
     103  
     104    /* Some hooks are called more than once but the test only check if any
     105       is called at least once.  */
     106    FILE *out = fmemopen (result.err.buffer, result.err.length, "r");
     107    TEST_VERIFY (out != NULL);
     108    char *buffer = NULL;
     109    size_t buffer_length = 0;
     110    while (xgetline (&buffer, &buffer_length, out))
     111      {
     112        for (int i = 0; i < array_length (audit_iface); i++)
     113  	if (strncmp (buffer, audit_iface[i].name,
     114  		     strlen (audit_iface[i].name)) == 0)
     115  	  audit_iface[i].found = true;
     116      }
     117    free (buffer);
     118    xfclose (out);
     119  
     120    for (int i = 0; i < array_length (audit_iface); i++)
     121      TEST_COMPARE (audit_iface[i].found, true);
     122  
     123    support_capture_subprocess_free (&result);
     124  
     125    return 0;
     126  }
     127  
     128  #define TEST_FUNCTION_ARGV do_test
     129  #include <support/test-driver.c>