]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - resolv/tst-resolv-res_init-skeleton.c
elf: Refuse to dlopen PIE objects [BZ #24323]
[thirdparty/glibc.git] / resolv / tst-resolv-res_init-skeleton.c
index f98e9f40305d48976c4cf5828f5f00c96262d4c2..678f396c4c3596deaa8fed4093e412b222b54953 100644 (file)
@@ -1,5 +1,5 @@
 /* Test parsing of /etc/resolv.conf.  Genric version.
-   Copyright (C) 2017 Free Software Foundation, Inc.
+   Copyright (C) 2017-2019 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -24,7 +24,6 @@
 #include <errno.h>
 #include <gnu/lib-names.h>
 #include <netdb.h>
-#include <resolv/resolv-internal.h> /* For DEPRECATED_RES_USE_INET6.  */
 #include <resolv/resolv_context.h>
 #include <stdio.h>
 #include <stdlib.h>
    res_init.  */
 static const char *const test_hostname = "www.example.com";
 
-/* Path to the test root directory.  */
-static char *path_chroot;
-
-/* Path to resolv.conf under path_chroot (outside the chroot).  */
-static char *path_resolv_conf;
+struct support_chroot *chroot_env;
 
 static void
 prepare (int argc, char **argv)
 {
-  path_chroot = xasprintf ("%s/tst-resolv-res_init-XXXXXX", test_dir);
-  if (mkdtemp (path_chroot) == NULL)
-    FAIL_EXIT1 ("mkdtemp (\"%s\"): %m", path_chroot);
-  add_temp_file (path_chroot);
-
-  /* Create the /etc directory in the chroot environment.  */
-  char *path_etc = xasprintf ("%s/etc", path_chroot);
-  xmkdir (path_etc, 0777);
-  add_temp_file (path_etc);
-
-  /* Create an empty resolv.conf file.  */
-  path_resolv_conf = xasprintf ("%s/resolv.conf", path_etc);
-  add_temp_file (path_resolv_conf);
-  support_write_file_string (path_resolv_conf, "");
-
-  free (path_etc);
-
-  /* valgrind needs a temporary directory in the chroot.  */
-  {
-    char *path_tmp = xasprintf ("%s/tmp", path_chroot);
-    xmkdir (path_tmp, 0777);
-    add_temp_file (path_tmp);
-    free (path_tmp);
-  }
+  chroot_env = support_chroot_create
+    ((struct support_chroot_configuration)
+     {
+       .resolv_conf = "",
+     });
 }
 
 /* Verify that the chroot environment has been set up.  */
 static void
 check_chroot_working (void *closure)
 {
-  xchroot (path_chroot);
+  xchroot (chroot_env->path_chroot);
   FILE *fp = xfopen (_PATH_RESCONF, "r");
   xfclose (fp);
 
@@ -143,7 +119,6 @@ print_resp (FILE *fp, res_state resp)
         if (resp->retry != RES_DFLRETRY)
           fprintf (fp, " attempts:%d", resp->retry);
         print_option_flag (fp, &options, RES_USEVC, "use-vc");
-        print_option_flag (fp, &options, DEPRECATED_RES_USE_INET6, "inet6");
         print_option_flag (fp, &options, RES_ROTATE, "rotate");
         print_option_flag (fp, &options, RES_USE_EDNS0, "edns0");
         print_option_flag (fp, &options, RES_SNGLKUP,
@@ -151,6 +126,7 @@ print_resp (FILE *fp, res_state resp)
         print_option_flag (fp, &options, RES_SNGLKUPREOP,
                            "single-request-reopen");
         print_option_flag (fp, &options, RES_NOTLDQUERY, "no-tld-query");
+        print_option_flag (fp, &options, RES_NORELOAD, "no-reload");
         fputc ('\n', fp);
         if (options != 0)
           fprintf (fp, "; error: unresolved option bits: 0x%x\n", options);
@@ -306,6 +282,10 @@ struct test_case
   /* Setting for the RES_OPTIONS environment variable.  NULL if the
      variable is not to be set.  */
   const char *res_options;
+
+  /* Override the system host name.  NULL means that no change is made
+     and the default is used (test_hostname).  */
+  const char *hostname;
 };
 
 enum test_init
@@ -340,7 +320,7 @@ setup_nss_dns_and_chroot (void)
   /* Load nss_dns outside of the chroot.  */
   if (dlopen (LIBNSS_DNS_SO, RTLD_LAZY) == NULL)
     FAIL_EXIT1 ("could not load " LIBNSS_DNS_SO ": %s", dlerror ());
-  xchroot (path_chroot);
+  xchroot (chroot_env->path_chroot);
   /* Force the use of nss_dns.  */
   __nss_configure_lookup ("hosts", "dns");
 }
@@ -357,17 +337,29 @@ run_res_init (void *closure)
     setenv ("LOCALDOMAIN", ctx->t->localdomain, 1);
   if (ctx->t->res_options != NULL)
     setenv ("RES_OPTIONS", ctx->t->res_options, 1);
+  if (ctx->t->hostname != NULL)
+    {
+#ifdef CLONE_NEWUTS
+      /* This test needs its own namespace, to avoid changing the host
+         name for the parent, too.  */
+      TEST_VERIFY_EXIT (unshare (CLONE_NEWUTS) == 0);
+      if (sethostname (ctx->t->hostname, strlen (ctx->t->hostname)) != 0)
+        FAIL_EXIT1 ("sethostname (\"%s\"): %m", ctx->t->hostname);
+#else
+      FAIL_UNSUPPORTED ("clone (CLONE_NEWUTS) not supported");
+#endif
+    }
 
   switch (ctx->init)
     {
     case test_init:
-      xchroot (path_chroot);
+      xchroot (chroot_env->path_chroot);
       TEST_VERIFY (res_init () == 0);
       print_resp (stdout, &_res);
       return;
 
     case test_ninit:
-      xchroot (path_chroot);
+      xchroot (chroot_env->path_chroot);
       res_state resp = xmalloc (sizeof (*resp));
       memset (resp, 0, sizeof (*resp));
       TEST_VERIFY (res_ninit (resp) == 0);
@@ -377,7 +369,7 @@ run_res_init (void *closure)
       return;
 
     case test_mkquery:
-      xchroot (path_chroot);
+      xchroot (chroot_env->path_chroot);
       unsigned char buf[512];
       TEST_VERIFY (res_mkquery (QUERY, "www.example",
                                 C_IN, ns_t_a, NULL, 0,
@@ -433,6 +425,12 @@ struct test_case test_cases[] =
      "nameserver 127.0.0.1\n"
      "; nameserver[0]: [127.0.0.1]:53\n"
     },
+    {.name = "empty file, no-dot hostname",
+     .conf = "",
+     .expected = "nameserver 127.0.0.1\n"
+     "; nameserver[0]: [127.0.0.1]:53\n",
+     .hostname = "example",
+    },
     {.name = "empty file with LOCALDOMAIN",
      .conf = "",
      .expected = "search example.net\n"
@@ -461,8 +459,7 @@ struct test_case test_cases[] =
      .res_options = "edns0 attempts:5",
     },
     {.name = "basic",
-     .conf = "domain example.net\n"
-     "search corp.example.com example.com\n"
+     .conf =  "search corp.example.com example.com\n"
      "nameserver 192.0.2.1\n",
      .expected = "search corp.example.com example.com\n"
      "; search[0]: corp.example.com\n"
@@ -470,6 +467,38 @@ struct test_case test_cases[] =
      "nameserver 192.0.2.1\n"
      "; nameserver[0]: [192.0.2.1]:53\n"
     },
+    {.name = "basic with no-dot hostname",
+     .conf = "search corp.example.com example.com\n"
+     "nameserver 192.0.2.1\n",
+     .expected = "search corp.example.com example.com\n"
+     "; search[0]: corp.example.com\n"
+     "; search[1]: example.com\n"
+     "nameserver 192.0.2.1\n"
+     "; nameserver[0]: [192.0.2.1]:53\n",
+     .hostname = "example",
+    },
+    {.name = "basic no-reload",
+     .conf = "options no-reload\n"
+     "search corp.example.com example.com\n"
+     "nameserver 192.0.2.1\n",
+     .expected = "options no-reload\n"
+     "search corp.example.com example.com\n"
+     "; search[0]: corp.example.com\n"
+     "; search[1]: example.com\n"
+     "nameserver 192.0.2.1\n"
+     "; nameserver[0]: [192.0.2.1]:53\n"
+    },
+    {.name = "basic no-reload via RES_OPTIONS",
+     .conf = "search corp.example.com example.com\n"
+     "nameserver 192.0.2.1\n",
+     .expected = "options no-reload\n"
+     "search corp.example.com example.com\n"
+     "; search[0]: corp.example.com\n"
+     "; search[1]: example.com\n"
+     "nameserver 192.0.2.1\n"
+     "; nameserver[0]: [192.0.2.1]:53\n",
+     .res_options = "no-reload"
+    },
     {.name = "whitespace",
      .conf = "# This test covers comment and whitespace processing "
      " (trailing whitespace,\n"
@@ -529,7 +558,7 @@ struct test_case test_cases[] =
      "nameserver 192.0.2.1\n"
      "nameserver ::1\n"
      "nameserver 192.0.2.2\n",
-     .expected = "options ndots:3 timeout:19 attempts:5 inet6 edns0\n"
+     .expected = "options ndots:3 timeout:19 attempts:5 edns0\n"
      "search corp.example.com example.com\n"
      "; search[0]: corp.example.com\n"
      "; search[1]: example.com\n"
@@ -722,18 +751,7 @@ test_file_contents (const struct test_case *t)
 }
 
 /* Special tests which do not follow the general pattern.  */
-enum { special_tests_count = 7 };
-
-#if TEST_THREAD
-/* Called from test number 3-6 to trigger reloading of the
-   configuration.  */
-static void *
-special_test_call_res_init (void *closure)
-{
-  TEST_VERIFY (res_init () == 0);
-  return NULL;
-}
-#endif
+enum { special_tests_count = 11 };
 
 /* Implementation of special tests.  */
 static void
@@ -744,7 +762,7 @@ special_test_callback (void *closure)
   TEST_VERIFY (test_index < special_tests_count);
   if (test_verbose > 0)
     printf ("info: special test %u\n", test_index);
-  xchroot (path_chroot);
+  xchroot (chroot_env->path_chroot);
 
   switch (test_index)
     {
@@ -800,20 +818,29 @@ special_test_callback (void *closure)
     case 4:
     case 5:
     case 6:
-      /* Test res_init change broadcast.  This requires a second
-         thread to trigger the reload.  */
-#if TEST_THREAD
       support_write_file_string (_PATH_RESCONF,
                                  "options edns0\n"
                                  "nameserver 192.0.2.1\n");
+      goto reload_tests;
+    case 7: /* 7 and the following tests are with no-reload.  */
+    case 8:
+    case 9:
+    case 10:
+        support_write_file_string (_PATH_RESCONF,
+                                   "options edns0 no-reload\n"
+                                   "nameserver 192.0.2.1\n");
+        /* Fall through.  */
+    reload_tests:
       for (int iteration = 0; iteration < 2; ++iteration)
         {
           switch (test_index)
             {
             case 3:
+            case 7:
               TEST_VERIFY (res_init () == 0);
               break;
             case 4:
+            case 8:
               {
                 unsigned char buf[512];
                 TEST_VERIFY
@@ -822,37 +849,44 @@ special_test_callback (void *closure)
               }
               break;
             case 5:
+            case 9:
               gethostbyname (test_hostname);
               break;
             case 6:
+            case 10:
               {
                 struct addrinfo *ai;
                 (void) getaddrinfo (test_hostname, NULL, NULL, &ai);
               }
               break;
             }
-          if (iteration == 0)
+          /* test_index == 7 is res_init and performs a reload even
+             with no-reload.  */
+          if (iteration == 0 || test_index > 7)
             {
               TEST_VERIFY (_res.options & RES_USE_EDNS0);
               TEST_VERIFY (!(_res.options & RES_ROTATE));
+              if (test_index < 7)
+                TEST_VERIFY (!(_res.options & RES_NORELOAD));
+              else
+                TEST_VERIFY (_res.options & RES_NORELOAD);
               TEST_VERIFY (_res.nscount == 1);
+              /* File change triggers automatic reloading.  */
               support_write_file_string (_PATH_RESCONF,
                                          "options rotate\n"
                                          "nameserver 192.0.2.1\n"
                                          "nameserver 192.0.2.2\n");
-              xpthread_join (xpthread_create
-                             (NULL, special_test_call_res_init, NULL));
             }
           else
             {
-              /* edns0 was dropped, but the flag is not cleared.  See
-                 bug 21701.  */
-              /* TEST_VERIFY (!(_res.options & RES_USE_EDNS0)); */
+              if (test_index != 3 && test_index != 7)
+                /* test_index 3, 7 are res_init; this function does
+                   not reset flags.  See bug 21701.  */
+                TEST_VERIFY (!(_res.options & RES_USE_EDNS0));
               TEST_VERIFY (_res.options & RES_ROTATE);
               TEST_VERIFY (_res.nscount == 2);
             }
         }
-#endif
       break;
     }
 }
@@ -1008,7 +1042,8 @@ do_test (void)
       TEST_VERIFY (test_cases[i].conf != NULL);
       TEST_VERIFY (test_cases[i].expected != NULL);
 
-      support_write_file_string (path_resolv_conf, test_cases[i].conf);
+      support_write_file_string (chroot_env->path_resolv_conf,
+                                 test_cases[i].conf);
 
       test_file_contents (&test_cases[i]);
 
@@ -1018,24 +1053,24 @@ do_test (void)
         {
           if (test_verbose > 0)
             printf ("info:  special test: missing file\n");
-          TEST_VERIFY (unlink (path_resolv_conf) == 0);
+          TEST_VERIFY (unlink (chroot_env->path_resolv_conf) == 0);
           test_file_contents (&test_cases[i]);
 
           if (test_verbose > 0)
             printf ("info:  special test: dangling symbolic link\n");
-          TEST_VERIFY (symlink ("does-not-exist", path_resolv_conf) == 0);
+          TEST_VERIFY (symlink ("does-not-exist", chroot_env->path_resolv_conf) == 0);
           test_file_contents (&test_cases[i]);
-          TEST_VERIFY (unlink (path_resolv_conf) == 0);
+          TEST_VERIFY (unlink (chroot_env->path_resolv_conf) == 0);
 
           if (test_verbose > 0)
             printf ("info:  special test: unreadable file\n");
-          support_write_file_string (path_resolv_conf, "");
-          TEST_VERIFY (chmod (path_resolv_conf, 0) == 0);
+          support_write_file_string (chroot_env->path_resolv_conf, "");
+          TEST_VERIFY (chmod (chroot_env->path_resolv_conf, 0) == 0);
           test_file_contents (&test_cases[i]);
 
           /* Restore the empty file.  */
-          TEST_VERIFY (unlink (path_resolv_conf) == 0);
-          support_write_file_string (path_resolv_conf, "");
+          TEST_VERIFY (unlink (chroot_env->path_resolv_conf) == 0);
+          support_write_file_string (chroot_env->path_resolv_conf, "");
         }
     }
 
@@ -1051,10 +1086,7 @@ do_test (void)
       xwaitpid (server, NULL, 0);
     }
 
-  free (path_chroot);
-  path_chroot = NULL;
-  free (path_resolv_conf);
-  path_resolv_conf = NULL;
+  support_chroot_free (chroot_env);
   return 0;
 }