This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch master updated. glibc-2.28.9000-362-g899478c


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  899478c2bfa00c5df8d8bedb52effbb065700278 (commit)
       via  f255336a9301619519045548acb2e1027065a837 (commit)
      from  35caceb145ff23340edcd67dd813bfd95f1ff6e6 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=899478c2bfa00c5df8d8bedb52effbb065700278

commit 899478c2bfa00c5df8d8bedb52effbb065700278
Author: Florian Weimer <fweimer@redhat.com>
Date:   Thu Dec 6 15:39:50 2018 +0100

    inet/tst-if_index-long: New test case for CVE-2018-19591 [BZ #23927]

diff --git a/ChangeLog b/ChangeLog
index 266cd67..8e52b40 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2018-12-07  Florian Weimer  <fweimer@redhat.com>
 
+	[BZ #23927]
+	CVE-2018-19591
+	* inet/tst-if_index-long.c: New file.
+	* inet/Makefile (tests): Add tst-if_index-long.
+
+2018-12-07  Florian Weimer  <fweimer@redhat.com>
+
 	* support/check.h (support_record_failure_is_failed): Declare.
 	* support/descriptors.h: New file.
 	* support/support_descriptors.c: Likewise.
diff --git a/inet/Makefile b/inet/Makefile
index 09f5ba7..7782913 100644
--- a/inet/Makefile
+++ b/inet/Makefile
@@ -52,7 +52,7 @@ aux := check_pf check_native ifreq
 tests := htontest test_ifindex tst-ntoa tst-ether_aton tst-network \
 	 tst-gethnm test-ifaddrs bug-if1 test-inet6_opt tst-ether_line \
 	 tst-getni1 tst-getni2 tst-inet6_rth tst-checks tst-checks-posix \
-	 tst-sockaddr test-hnto-types
+	 tst-sockaddr test-hnto-types tst-if_index-long
 
 # tst-deadline must be linked statically so that we can access
 # internal functions.
diff --git a/inet/tst-if_index-long.c b/inet/tst-if_index-long.c
new file mode 100644
index 0000000..3dc7487
--- /dev/null
+++ b/inet/tst-if_index-long.c
@@ -0,0 +1,61 @@
+/* Check for descriptor leak in if_nametoindex with a long interface name.
+   Copyright (C) 2018 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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* This test checks for a descriptor leak in case of a long interface
+   name (CVE-2018-19591, bug 23927).  */
+
+#include <errno.h>
+#include <net/if.h>
+#include <netdb.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/descriptors.h>
+#include <support/support.h>
+
+static int
+do_test (void)
+{
+  struct support_descriptors *descrs = support_descriptors_list ();
+
+  /* Prepare a name which is just as long as required for trigging the
+     bug.  */
+  char name[IFNAMSIZ + 1];
+  memset (name, 'A', IFNAMSIZ);
+  name[IFNAMSIZ] = '\0';
+  TEST_COMPARE (strlen (name), IFNAMSIZ);
+  struct ifreq ifr;
+  TEST_COMPARE (strlen (name), sizeof (ifr.ifr_name));
+
+  /* Test directly via if_nametoindex.  */
+  TEST_COMPARE (if_nametoindex (name), 0);
+  TEST_COMPARE (errno, ENODEV);
+  support_descriptors_check (descrs);
+
+  /* Same test via getaddrinfo.  */
+  char *host = xasprintf ("fea0::%%%s", name);
+  struct addrinfo hints = { .ai_flags = AI_NUMERICHOST, };
+  struct addrinfo *ai;
+  TEST_COMPARE (getaddrinfo (host, NULL, &hints, &ai), EAI_NONAME);
+  support_descriptors_check (descrs);
+
+  support_descriptors_free (descrs);
+
+  return 0;
+}
+
+#include <support/test-driver.c>

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=f255336a9301619519045548acb2e1027065a837

commit f255336a9301619519045548acb2e1027065a837
Author: Florian Weimer <fweimer@redhat.com>
Date:   Thu Dec 6 15:39:42 2018 +0100

    support: Implement <support/descriptors.h> to track file descriptors

diff --git a/ChangeLog b/ChangeLog
index eabd7e7..266cd67 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2018-12-07  Florian Weimer  <fweimer@redhat.com>
+
+	* support/check.h (support_record_failure_is_failed): Declare.
+	* support/descriptors.h: New file.
+	* support/support_descriptors.c: Likewise.
+	* support/tst-support_descriptors.c: Likewise.
+	* support/support_record_failure.c
+	(support_record_failure_is_failed): New function.
+	* support/Makefile (libsupport-routines): Add support_descriptors.
+	(tests): Add tst-support_descriptors.
+
 2018-12-05  Zack Weinberg  <zackw@panix.com>
 	    Gabriel F. T. Gomes  <gabriel@inconstante.eti.br>
 
diff --git a/support/Makefile b/support/Makefile
index a253698..93a5143 100644
--- a/support/Makefile
+++ b/support/Makefile
@@ -46,6 +46,7 @@ libsupport-routines = \
   support_chroot \
   support_copy_file_range \
   support_descriptor_supports_holes \
+  support_descriptors \
   support_enter_mount_namespace \
   support_enter_network_namespace \
   support_format_address_family \
@@ -195,6 +196,7 @@ tests = \
   tst-support-namespace \
   tst-support_blob_repeat \
   tst-support_capture_subprocess \
+  tst-support_descriptors \
   tst-support_format_dns_packet \
   tst-support_quote_blob \
   tst-support_quote_string \
diff --git a/support/check.h b/support/check.h
index e676528..7ea9a86 100644
--- a/support/check.h
+++ b/support/check.h
@@ -183,6 +183,10 @@ int support_report_failure (int status)
 /* Internal function used to test the failure recording framework.  */
 void support_record_failure_reset (void);
 
+/* Returns true or false depending on whether there have been test
+   failures or not.  */
+int support_record_failure_is_failed (void);
+
 __END_DECLS
 
 #endif /* SUPPORT_CHECK_H */
diff --git a/support/descriptors.h b/support/descriptors.h
new file mode 100644
index 0000000..8ec4cbb
--- /dev/null
+++ b/support/descriptors.h
@@ -0,0 +1,47 @@
+/* Monitoring file descriptor usage.
+   Copyright (C) 2018 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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef SUPPORT_DESCRIPTORS_H
+#define SUPPORT_DESCRIPTORS_H
+
+#include <stdio.h>
+
+/* Opaque pointer, for capturing file descriptor lists.  */
+struct support_descriptors;
+
+/* Record the currently open file descriptors and store them in the
+   returned list.  Terminate the process if the listing operation
+   fails.  */
+struct support_descriptors *support_descriptors_list (void);
+
+/* Deallocate the list of descriptors.  */
+void support_descriptors_free (struct support_descriptors *);
+
+/* Write the list of descriptors to STREAM, adding PREFIX to each
+   line.  */
+void support_descriptors_dump (struct support_descriptors *,
+                               const char *prefix, FILE *stream);
+
+/* Check for file descriptor leaks and other file descriptor changes:
+   Compare the current list of descriptors with the passed list.
+   Record a test failure if there are additional open descriptors,
+   descriptors have been closed, or if a change in file descriptor can
+   be detected.  */
+void support_descriptors_check (struct support_descriptors *);
+
+#endif /* SUPPORT_DESCRIPTORS_H */
diff --git a/support/support_descriptors.c b/support/support_descriptors.c
new file mode 100644
index 0000000..d66cf55
--- /dev/null
+++ b/support/support_descriptors.c
@@ -0,0 +1,274 @@
+/* Monitoring file descriptor usage.
+   Copyright (C) 2018 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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <dirent.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+#include <xunistd.h>
+
+struct procfs_descriptor
+{
+  int fd;
+  char *link_target;
+  dev_t dev;
+  ino64_t ino;
+};
+
+/* Used with qsort.  */
+static int
+descriptor_compare (const void *l, const void *r)
+{
+  const struct procfs_descriptor *left = l;
+  const struct procfs_descriptor *right = r;
+  /* Cannot overflow due to limited file descriptor range.  */
+  return left->fd - right->fd;
+}
+
+#define DYNARRAY_STRUCT descriptor_list
+#define DYNARRAY_ELEMENT struct procfs_descriptor
+#define DYNARRAY_PREFIX descriptor_list_
+#define DYNARRAY_ELEMENT_FREE(e) free ((e)->link_target)
+#define DYNARRAY_INITIAL_SIZE 0
+#include <malloc/dynarray-skeleton.c>
+
+struct support_descriptors
+{
+  struct descriptor_list list;
+};
+
+struct support_descriptors *
+support_descriptors_list (void)
+{
+  struct support_descriptors *result = xmalloc (sizeof (*result));
+  descriptor_list_init (&result->list);
+
+  DIR *fds = opendir ("/proc/self/fd");
+  if (fds == NULL)
+    FAIL_EXIT1 ("opendir (\"/proc/self/fd\"): %m");
+
+  while (true)
+    {
+      errno = 0;
+      struct dirent64 *e = readdir64 (fds);
+      if (e == NULL)
+        {
+          if (errno != 0)
+            FAIL_EXIT1 ("readdir: %m");
+          break;
+        }
+
+      if (e->d_name[0] == '.')
+        continue;
+
+      char *endptr;
+      long int fd = strtol (e->d_name, &endptr, 10);
+      if (*endptr != '\0' || fd < 0 || fd > INT_MAX)
+        FAIL_EXIT1 ("readdir: invalid file descriptor name: /proc/self/fd/%s",
+                    e->d_name);
+
+      /* Skip the descriptor which is used to enumerate the
+         descriptors.  */
+      if (fd == dirfd (fds))
+        continue;
+
+      char *target;
+      {
+        char *path = xasprintf ("/proc/self/fd/%ld", fd);
+        target = xreadlink (path);
+        free (path);
+      }
+      struct stat64 st;
+      if (fstat64 (fd, &st) != 0)
+        FAIL_EXIT1 ("readdir: fstat64 (%ld) failed: %m", fd);
+
+      struct procfs_descriptor *item = descriptor_list_emplace (&result->list);
+      if (item == NULL)
+        FAIL_EXIT1 ("descriptor_list_emplace: %m");
+      item->fd = fd;
+      item->link_target = target;
+      item->dev = st.st_dev;
+      item->ino = st.st_ino;
+    }
+
+  closedir (fds);
+
+  /* Perform a merge join between descrs and current.  This assumes
+     that the arrays are sorted by file descriptor.  */
+
+  qsort (descriptor_list_begin (&result->list),
+         descriptor_list_size (&result->list),
+         sizeof (struct procfs_descriptor), descriptor_compare);
+
+  return result;
+}
+
+void
+support_descriptors_free (struct support_descriptors *descrs)
+{
+  descriptor_list_free (&descrs->list);
+  free (descrs);
+}
+
+void
+support_descriptors_dump (struct support_descriptors *descrs,
+                          const char *prefix, FILE *fp)
+{
+  struct procfs_descriptor *end = descriptor_list_end (&descrs->list);
+  for (struct procfs_descriptor *d = descriptor_list_begin (&descrs->list);
+       d != end; ++d)
+    {
+      char *quoted = support_quote_string (d->link_target);
+      fprintf (fp, "%s%d: target=\"%s\" major=%lld minor=%lld ino=%lld\n",
+               prefix, d->fd, quoted,
+               (long long int) major (d->dev),
+               (long long int) minor (d->dev),
+               (long long int) d->ino);
+      free (quoted);
+    }
+}
+
+static void
+dump_mismatch (bool *first,
+               struct support_descriptors *descrs,
+               struct support_descriptors *current)
+{
+  if (*first)
+    *first = false;
+  else
+    return;
+
+  puts ("error: Differences found in descriptor set");
+  puts ("Reference descriptor set:");
+  support_descriptors_dump (descrs, "  ", stdout);
+  puts ("Current descriptor set:");
+  support_descriptors_dump (current, "  ", stdout);
+  puts ("Differences:");
+}
+
+static void
+report_closed_descriptor (bool *first,
+                          struct support_descriptors *descrs,
+                          struct support_descriptors *current,
+                          struct procfs_descriptor *left)
+{
+  support_record_failure ();
+  dump_mismatch (first, descrs, current);
+  printf ("error: descriptor %d was closed\n", left->fd);
+}
+
+static void
+report_opened_descriptor (bool *first,
+                          struct support_descriptors *descrs,
+                          struct support_descriptors *current,
+                          struct procfs_descriptor *right)
+{
+  support_record_failure ();
+  dump_mismatch (first, descrs, current);
+  char *quoted = support_quote_string (right->link_target);
+  printf ("error: descriptor %d was opened (\"%s\")\n", right->fd, quoted);
+  free (quoted);
+}
+
+void
+support_descriptors_check (struct support_descriptors *descrs)
+{
+  struct support_descriptors *current = support_descriptors_list ();
+
+  /* Perform a merge join between descrs and current.  This assumes
+     that the arrays are sorted by file descriptor.  */
+
+  struct procfs_descriptor *left = descriptor_list_begin (&descrs->list);
+  struct procfs_descriptor *left_end = descriptor_list_end (&descrs->list);
+  struct procfs_descriptor *right = descriptor_list_begin (&current->list);
+  struct procfs_descriptor *right_end = descriptor_list_end (&current->list);
+
+  bool first = true;
+  while (left != left_end && right != right_end)
+    {
+      if (left->fd == right->fd)
+        {
+          if (strcmp (left->link_target, right->link_target) != 0)
+            {
+              support_record_failure ();
+              char *left_quoted = support_quote_string (left->link_target);
+              char *right_quoted = support_quote_string (right->link_target);
+              dump_mismatch (&first, descrs, current);
+              printf ("error: descriptor %d changed from \"%s\" to \"%s\"\n",
+                      left->fd, left_quoted, right_quoted);
+              free (left_quoted);
+              free (right_quoted);
+            }
+          if (left->dev != right->dev)
+            {
+              support_record_failure ();
+              dump_mismatch (&first, descrs, current);
+              printf ("error: descriptor %d changed device"
+                      " from %lld:%lld to %lld:%lld\n",
+                      left->fd,
+                      (long long int) major (left->dev),
+                      (long long int) minor (left->dev),
+                      (long long int) major (right->dev),
+                      (long long int) minor (right->dev));
+            }
+          if (left->ino != right->ino)
+            {
+              support_record_failure ();
+              dump_mismatch (&first, descrs, current);
+              printf ("error: descriptor %d changed ino from %lld to %lld\n",
+                      left->fd,
+                      (long long int) left->ino, (long long int) right->ino);
+            }
+          ++left;
+          ++right;
+        }
+      else if (left->fd < right->fd)
+        {
+          /* Gap on the right.  */
+          report_closed_descriptor (&first, descrs, current, left);
+          ++left;
+        }
+      else
+        {
+          /* Gap on the left.  */
+          TEST_VERIFY_EXIT (left->fd > right->fd);
+          report_opened_descriptor (&first, descrs, current, right);
+          ++right;
+        }
+    }
+
+  while (left != left_end)
+    {
+      /* Closed descriptors (more descriptors on the left).  */
+      report_closed_descriptor (&first, descrs, current, left);
+      ++left;
+    }
+
+  while (right != right_end)
+    {
+      /* Opened descriptors (more descriptors on the right).  */
+      report_opened_descriptor (&first, descrs, current, right);
+      ++right;
+    }
+
+  support_descriptors_free (current);
+}
diff --git a/support/support_record_failure.c b/support/support_record_failure.c
index 356798f..17ab1d8 100644
--- a/support/support_record_failure.c
+++ b/support/support_record_failure.c
@@ -104,3 +104,11 @@ support_record_failure_reset (void)
   __atomic_store_n (&state->failed, 0, __ATOMIC_RELAXED);
   __atomic_add_fetch (&state->counter, 0, __ATOMIC_RELAXED);
 }
+
+int
+support_record_failure_is_failed (void)
+{
+  /* Relaxed MO is sufficient because we need (blocking) external
+     synchronization for reliable test error reporting anyway.  */
+  return __atomic_load_n (&state->failed, __ATOMIC_RELAXED);
+}
diff --git a/support/tst-support_descriptors.c b/support/tst-support_descriptors.c
new file mode 100644
index 0000000..5e9e824
--- /dev/null
+++ b/support/tst-support_descriptors.c
@@ -0,0 +1,198 @@
+/* Tests for monitoring file descriptor usage.
+   Copyright (C) 2018 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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/capture_subprocess.h>
+#include <support/check.h>
+#include <support/descriptors.h>
+#include <support/support.h>
+#include <support/xunistd.h>
+
+/* This is the next free descriptor that the subprocess will pick.  */
+static int free_descriptor;
+
+static void
+subprocess_no_change (void *closure)
+{
+  struct support_descriptors *descrs = support_descriptors_list ();
+  int fd = xopen ("/dev/null", O_WRONLY, 0);
+  TEST_COMPARE (fd, free_descriptor);
+  xclose (fd);
+  support_descriptors_free (descrs);
+}
+
+static void
+subprocess_closed_descriptor (void *closure)
+{
+  int fd = xopen ("/dev/null", O_WRONLY, 0);
+  TEST_COMPARE (fd, free_descriptor);
+  struct support_descriptors *descrs = support_descriptors_list ();
+  xclose (fd);
+  support_descriptors_check (descrs); /* Will report failure.  */
+  puts ("EOT");
+  support_descriptors_free (descrs);
+}
+
+static void
+subprocess_opened_descriptor (void *closure)
+{
+  struct support_descriptors *descrs = support_descriptors_list ();
+  int fd = xopen ("/dev/null", O_WRONLY, 0);
+  TEST_COMPARE (fd, free_descriptor);
+  support_descriptors_check (descrs); /* Will report failure.  */
+  puts ("EOT");
+  support_descriptors_free (descrs);
+}
+
+static void
+subprocess_changed_descriptor (void *closure)
+{
+  int fd = xopen ("/dev/null", O_WRONLY, 0);
+  TEST_COMPARE (fd, free_descriptor);
+  struct support_descriptors *descrs = support_descriptors_list ();
+  xclose (fd);
+  TEST_COMPARE (xopen ("/dev", O_DIRECTORY | O_RDONLY, 0), fd);
+  support_descriptors_check (descrs); /* Will report failure.  */
+  puts ("EOT");
+  support_descriptors_free (descrs);
+}
+
+static void
+report_subprocess_output (const char *name,
+                          struct support_capture_subprocess *proc)
+{
+  printf ("info: BEGIN %s output\n"
+          "%s"
+          "info: END %s output\n",
+          name, proc->out.buffer, name);
+}
+
+/* Use an explicit flag to preserve failure status across
+   support_record_failure_reset calls.  */
+static bool good = true;
+
+static void
+test_run (void)
+{
+  struct support_capture_subprocess proc = support_capture_subprocess
+    (&subprocess_no_change, NULL);
+  support_capture_subprocess_check (&proc, "subprocess_no_change",
+                                    0, sc_allow_none);
+  support_capture_subprocess_free (&proc);
+
+  char *expected = xasprintf ("\nDifferences:\n"
+                              "error: descriptor %d was closed\n"
+                              "EOT\n",
+                              free_descriptor);
+  good = good && !support_record_failure_is_failed ();
+  proc = support_capture_subprocess (&subprocess_closed_descriptor, NULL);
+  good = good && support_record_failure_is_failed ();
+  support_record_failure_reset (); /* Discard the reported error.  */
+  report_subprocess_output ("subprocess_closed_descriptor", &proc);
+  TEST_VERIFY (strstr (proc.out.buffer, expected) != NULL);
+  support_capture_subprocess_check (&proc, "subprocess_closed_descriptor",
+                                    0, sc_allow_stdout);
+  support_capture_subprocess_free (&proc);
+  free (expected);
+
+  expected = xasprintf ("\nDifferences:\n"
+                        "error: descriptor %d was opened (\"/dev/null\")\n"
+                        "EOT\n",
+                        free_descriptor);
+  good = good && !support_record_failure_is_failed ();
+  proc = support_capture_subprocess (&subprocess_opened_descriptor, NULL);
+  good = good && support_record_failure_is_failed ();
+  support_record_failure_reset (); /* Discard the reported error.  */
+  report_subprocess_output ("subprocess_opened_descriptor", &proc);
+  TEST_VERIFY (strstr (proc.out.buffer, expected) != NULL);
+  support_capture_subprocess_check (&proc, "subprocess_opened_descriptor",
+                                    0, sc_allow_stdout);
+  support_capture_subprocess_free (&proc);
+  free (expected);
+
+  expected = xasprintf ("\nDifferences:\n"
+                        "error: descriptor %d changed from \"/dev/null\""
+                        " to \"/dev\"\n"
+                        "error: descriptor %d changed ino ",
+                        free_descriptor, free_descriptor);
+  good = good && !support_record_failure_is_failed ();
+  proc = support_capture_subprocess (&subprocess_changed_descriptor, NULL);
+  good = good && support_record_failure_is_failed ();
+  support_record_failure_reset (); /* Discard the reported error.  */
+  report_subprocess_output ("subprocess_changed_descriptor", &proc);
+  TEST_VERIFY (strstr (proc.out.buffer, expected) != NULL);
+  support_capture_subprocess_check (&proc, "subprocess_changed_descriptor",
+                                    0, sc_allow_stdout);
+  support_capture_subprocess_free (&proc);
+  free (expected);
+}
+
+static int
+do_test (void)
+{
+  puts ("info: initial descriptor set");
+  {
+    struct support_descriptors *descrs = support_descriptors_list ();
+    support_descriptors_dump (descrs, "info:  ", stdout);
+    support_descriptors_free (descrs);
+  }
+
+  free_descriptor = xopen ("/dev/null", O_WRONLY, 0);
+  puts ("info: descriptor set with additional free descriptor");
+  {
+    struct support_descriptors *descrs = support_descriptors_list ();
+    support_descriptors_dump (descrs, "info:  ", stdout);
+    support_descriptors_free (descrs);
+  }
+  TEST_VERIFY (free_descriptor >= 3);
+  xclose (free_descriptor);
+
+  /* Initial test run without a sentinel descriptor.  The presence of
+     such a descriptor exercises different conditions in the list
+     comparison in support_descriptors_check.  */
+  test_run ();
+
+  /* Allocate a sentinel descriptor at the end of the descriptor list,
+     after free_descriptor.  */
+  int sentinel_fd;
+  {
+    int fd = xopen ("/dev/full", O_WRONLY, 0);
+    TEST_COMPARE (fd, free_descriptor);
+    sentinel_fd = dup (fd);
+    TEST_VERIFY_EXIT (sentinel_fd > fd);
+    xclose (fd);
+  }
+  puts ("info: descriptor set with sentinel descriptor");
+  {
+    struct support_descriptors *descrs = support_descriptors_list ();
+    support_descriptors_dump (descrs, "info:  ", stdout);
+    support_descriptors_free (descrs);
+  }
+
+  /* Second test run with sentinel descriptor.  */
+  test_run ();
+
+  xclose (sentinel_fd);
+
+  return !good;
+}
+
+#include <support/test-driver.c>

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                         |   18 +++
 inet/Makefile                     |    2 +-
 inet/tst-if_index-long.c          |   61 ++++++++
 support/Makefile                  |    2 +
 support/check.h                   |    4 +
 support/descriptors.h             |   47 +++++++
 support/support_descriptors.c     |  274 +++++++++++++++++++++++++++++++++++++
 support/support_record_failure.c  |    8 +
 support/tst-support_descriptors.c |  198 ++++++++++++++++++++++++++
 9 files changed, 613 insertions(+), 1 deletions(-)
 create mode 100644 inet/tst-if_index-long.c
 create mode 100644 support/descriptors.h
 create mode 100644 support/support_descriptors.c
 create mode 100644 support/tst-support_descriptors.c


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]