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 release/2.28/master updated. glibc-2.28-57-gb5a9a19


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, release/2.28/master has been updated
       via  b5a9a19b82bb00b5419162f49331a7580ac06b4e (commit)
       via  4c2dada5070c9adc93e548826333c8be34f0c50a (commit)
       via  874c28c9f5d14586ab71cd4af6899b11753caf25 (commit)
       via  9dd07a91dba984c223730af30741565cb9bd88d5 (commit)
       via  4718b053dfef495a4d5189e4210bc66106873522 (commit)
      from  5f1ae50a78d3f66b195668f1b863832d85d27f2f (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=b5a9a19b82bb00b5419162f49331a7580ac06b4e

commit b5a9a19b82bb00b5419162f49331a7580ac06b4e
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]
    
    (cherry picked from commit 899478c2bfa00c5df8d8bedb52effbb065700278)

diff --git a/ChangeLog b/ChangeLog
index e6451fe..44202d9 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=4c2dada5070c9adc93e548826333c8be34f0c50a

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

    support: Implement <support/descriptors.h> to track file descriptors
    
    (cherry picked from commit f255336a9301619519045548acb2e1027065a837)

diff --git a/ChangeLog b/ChangeLog
index 2951523..e6451fe 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-01  Florian Weimer  <fweimer@redhat.com>
 
 	* support/support_capture_subprocess.c
diff --git a/support/Makefile b/support/Makefile
index 6439d18..550fdba 100644
--- a/support/Makefile
+++ b/support/Makefile
@@ -44,6 +44,7 @@ libsupport-routines = \
   support_capture_subprocess \
   support_capture_subprocess_check \
   support_chroot \
+  support_descriptors \
   support_enter_mount_namespace \
   support_enter_network_namespace \
   support_format_address_family \
@@ -158,6 +159,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 b3a4645..10468b7 100644
--- a/support/check.h
+++ b/support/check.h
@@ -170,6 +170,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>

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

commit 874c28c9f5d14586ab71cd4af6899b11753caf25
Author: Florian Weimer <fweimer@redhat.com>
Date:   Sat Dec 1 21:43:36 2018 +0100

    support: Close original descriptors in support_capture_subprocess
    
    (cherry picked from commit 02cd5c1a8d033d7f91fea12a66bb44d1bbf85f76)

diff --git a/ChangeLog b/ChangeLog
index a979f53..2951523 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2018-12-01  Florian Weimer  <fweimer@redhat.com>
+
+	* support/support_capture_subprocess.c
+	(support_capture_subprocess): Check that pipe descriptors have
+	expected values.  Close original pipe descriptors in subprocess.
+
 2018-11-28  Florian Weimer  <fweimer@redhat.com>
 
 	* support/support.h (support_quote_string): Do not use str
diff --git a/support/support_capture_subprocess.c b/support/support_capture_subprocess.c
index 6d2029e..93f6ea3 100644
--- a/support/support_capture_subprocess.c
+++ b/support/support_capture_subprocess.c
@@ -59,8 +59,12 @@ support_capture_subprocess (void (*callback) (void *), void *closure)
 
   int stdout_pipe[2];
   xpipe (stdout_pipe);
+  TEST_VERIFY (stdout_pipe[0] > STDERR_FILENO);
+  TEST_VERIFY (stdout_pipe[1] > STDERR_FILENO);
   int stderr_pipe[2];
   xpipe (stderr_pipe);
+  TEST_VERIFY (stderr_pipe[0] > STDERR_FILENO);
+  TEST_VERIFY (stderr_pipe[1] > STDERR_FILENO);
 
   TEST_VERIFY (fflush (stdout) == 0);
   TEST_VERIFY (fflush (stderr) == 0);
@@ -72,6 +76,8 @@ support_capture_subprocess (void (*callback) (void *), void *closure)
       xclose (stderr_pipe[0]);
       xdup2 (stdout_pipe[1], STDOUT_FILENO);
       xdup2 (stderr_pipe[1], STDERR_FILENO);
+      xclose (stdout_pipe[1]);
+      xclose (stderr_pipe[1]);
       callback (closure);
       _exit (0);
     }

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

commit 9dd07a91dba984c223730af30741565cb9bd88d5
Author: Florian Weimer <fweimer@redhat.com>
Date:   Wed Nov 28 07:00:48 2018 +0100

    support_quote_string: Do not use str parameter name
    
    This avoids a build failure if this identifier is used as a macro
    in a test.
    
    (cherry picked from commit 47d8d9a2172f827a8dde7695f415aa6f78a82d0e)

diff --git a/ChangeLog b/ChangeLog
index aaeb1fc..a979f53 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-11-28  Florian Weimer  <fweimer@redhat.com>
+
+	* support/support.h (support_quote_string): Do not use str
+	parameter name.
+
 2018-11-27  Florian Weimer  <fweimer@redhat.com>
 
 	* support/support.h (support_quote_string): Declare.
diff --git a/support/support.h b/support/support.h
index 4d9f752..4ea92e1 100644
--- a/support/support.h
+++ b/support/support.h
@@ -65,10 +65,10 @@ void support_write_file_string (const char *path, const char *contents);
    the result).  */
 char *support_quote_blob (const void *blob, size_t length);
 
-/* Quote the contents of the at STR, in such a way that the result
+/* Quote the contents of the string, in such a way that the result
    string can be included in a C literal (in single/double quotes,
    without putting the quotes into the result).  */
-char *support_quote_string (const char *str);
+char *support_quote_string (const char *);
 
 /* Error-checking wrapper functions which terminate the process on
    error.  */

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

commit 4718b053dfef495a4d5189e4210bc66106873522
Author: Florian Weimer <fweimer@redhat.com>
Date:   Tue Nov 27 21:35:56 2018 +0100

    support: Implement support_quote_string
    
    Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
    (cherry picked from commit c74a91deaa5de416237c02bbb3e41bda76ca4c7b)

diff --git a/ChangeLog b/ChangeLog
index 67213d4..aaeb1fc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2018-11-27  Florian Weimer  <fweimer@redhat.com>
+
+	* support/support.h (support_quote_string): Declare.
+	* support/support_quote_string.c: New file.
+	* support/tst-support_quote_string.c: Likewise.
+	* support/Makefile (libsupport-routines): Add
+	support_quote_string.
+	(tests): Add tst-support_quote_string.
+
 2018-12-10  Florian Weimer  <fweimer@redhat.com>
 
 	[BZ #23972]
diff --git a/support/Makefile b/support/Makefile
index 50470fb..6439d18 100644
--- a/support/Makefile
+++ b/support/Makefile
@@ -55,6 +55,7 @@ libsupport-routines = \
   support_isolate_in_subprocess \
   support_openpty \
   support_quote_blob \
+  support_quote_string \
   support_record_failure \
   support_run_diff \
   support_shared_allocate \
@@ -159,6 +160,7 @@ tests = \
   tst-support_capture_subprocess \
   tst-support_format_dns_packet \
   tst-support_quote_blob \
+  tst-support_quote_string \
   tst-support_record_failure \
   tst-test_compare \
   tst-test_compare_blob \
diff --git a/support/support.h b/support/support.h
index b61fe07..4d9f752 100644
--- a/support/support.h
+++ b/support/support.h
@@ -65,6 +65,11 @@ void support_write_file_string (const char *path, const char *contents);
    the result).  */
 char *support_quote_blob (const void *blob, size_t length);
 
+/* Quote the contents of the at STR, in such a way that the result
+   string can be included in a C literal (in single/double quotes,
+   without putting the quotes into the result).  */
+char *support_quote_string (const char *str);
+
 /* Error-checking wrapper functions which terminate the process on
    error.  */
 
diff --git a/support/support_quote_string.c b/support/support_quote_string.c
new file mode 100644
index 0000000..d324371
--- /dev/null
+++ b/support/support_quote_string.c
@@ -0,0 +1,26 @@
+/* Quote a string so that it can be used in C literals.
+   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 <string.h>
+#include <support/support.h>
+
+char *
+support_quote_string (const char *str)
+{
+  return support_quote_blob (str, strlen (str));
+}
diff --git a/support/tst-support_quote_string.c b/support/tst-support_quote_string.c
new file mode 100644
index 0000000..3c00475
--- /dev/null
+++ b/support/tst-support_quote_string.c
@@ -0,0 +1,60 @@
+/* Test the support_quote_string function.
+   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 <support/check.h>
+#include <support/support.h>
+#include <string.h>
+#include <stdlib.h>
+
+static int
+do_test (void)
+{
+  char *p = support_quote_string ("");
+  TEST_COMPARE (strlen (p), 0);
+  free (p);
+  p = support_quote_string ("X");
+  TEST_COMPARE (strlen (p), 1);
+  TEST_COMPARE (p[0], 'X');
+  free (p);
+
+  /* Check escaping of backslash-escaped characters, and lack of
+     escaping for other shell meta-characters.  */
+  p = support_quote_string ("$()*?`@[]{}~\'\"X");
+  TEST_COMPARE (strcmp (p, "$()*?`@[]{}~\\'\\\"X"), 0);
+  free (p);
+
+  /* Check lack of escaping for letters and digits.  */
+#define LETTERS_AND_DIGTS                       \
+  "abcdefghijklmnopqrstuvwxyz"                  \
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZ"                  \
+  "0123456789"
+  p = support_quote_string (LETTERS_AND_DIGTS "@");
+  TEST_COMPARE (strcmp (p, LETTERS_AND_DIGTS "@"), 0);
+  free (p);
+
+  /* Check escaping of control characters and other non-printable
+     characters.  */
+  p = support_quote_string ("\r\n\t\a\b\f\v\1\177\200\377@");
+  TEST_COMPARE (strcmp (p, "\\r\\n\\t\\a\\b\\f\\v\\001"
+                        "\\177\\200\\377@"), 0);
+  free (p);
+
+  return 0;
+}
+
+#include <support/test-driver.c>

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

Summary of changes:
 ChangeLog                            |   38 +++++
 inet/Makefile                        |    2 +-
 inet/tst-if_index-long.c             |   61 ++++++++
 support/Makefile                     |    4 +
 support/check.h                      |    4 +
 support/descriptors.h                |   47 ++++++
 support/support.h                    |    5 +
 support/support_capture_subprocess.c |    6 +
 support/support_descriptors.c        |  274 ++++++++++++++++++++++++++++++++++
 support/support_quote_string.c       |   26 ++++
 support/support_record_failure.c     |    8 +
 support/tst-support_descriptors.c    |  198 ++++++++++++++++++++++++
 support/tst-support_quote_string.c   |   60 ++++++++
 13 files changed, 732 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/support_quote_string.c
 create mode 100644 support/tst-support_descriptors.c
 create mode 100644 support/tst-support_quote_string.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]