about summary refs log tree commit diff
path: root/sysdeps
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2007-03-15 20:05:19 +0000
committerUlrich Drepper <drepper@redhat.com>2007-03-15 20:05:19 +0000
commit6cb988fa7b81cd5f850c3f31fbae318a1df63521 (patch)
tree26930174d009a8c58f2ed1b5f3e9f9ff089e09c6 /sysdeps
parent02c906999c8500a43005e47f5810883b3a5189d8 (diff)
downloadglibc-6cb988fa7b81cd5f850c3f31fbae318a1df63521.tar.gz
glibc-6cb988fa7b81cd5f850c3f31fbae318a1df63521.tar.xz
glibc-6cb988fa7b81cd5f850c3f31fbae318a1df63521.zip
[BZ #4181]
2007-03-15  Jakub Jelinek  <jakub@redhat.com>
	[BZ #4181]
	* inet/inet6_opt.c (add_padding): Only insert padding if npad > 0.
	(inet6_opt_append): Don't check extlen is big enough if extbuf
	is NULL.
	(inet6_opt_finish): Likewise.
	* inet/Makefile (tests): Add test-inet6_opt.
	* inet/test-inet6_opt.c: New test.

	* sysdeps/unix/sysv/linux/ifaddrs.c (__netlink_request): Never
	reallocate the buffer, instead fail for MSG_TRUNC or for EBUSY
	NLMSG_ERR.  Instead use a page sized buffer.
	* sysdeps/unix/sysv/linux/check_pf.c (make_request): Use page sized
	buffer.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/unix/sysv/linux/check_pf.c42
-rw-r--r--sysdeps/unix/sysv/linux/ifaddrs.c104
2 files changed, 51 insertions, 95 deletions
diff --git a/sysdeps/unix/sysv/linux/check_pf.c b/sysdeps/unix/sysv/linux/check_pf.c
index 13ccd7acb4..caf3155259 100644
--- a/sysdeps/unix/sysv/linux/check_pf.c
+++ b/sysdeps/unix/sysv/linux/check_pf.c
@@ -1,5 +1,5 @@
 /* Determine protocol families for which interfaces exist.  Linux version.
-   Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2006, 2007 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
@@ -71,17 +71,38 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
   memset (&nladdr, '\0', sizeof (nladdr));
   nladdr.nl_family = AF_NETLINK;
 
+#ifdef PAGE_SIZE
+  /* Help the compiler optimize out the malloc call if PAGE_SIZE
+     is constant and smaller or equal to PTHREAD_STACK_MIN/4.  */
+  const size_t buf_size = PAGE_SIZE;
+#else
+  const size_t buf_size = __getpagesize ();
+#endif
+  bool use_malloc = false;
+  char *buf;
+
+  if (__libc_use_alloca (buf_size))
+    buf = alloca (buf_size);
+  else
+    {
+      buf = malloc (buf_size);
+      if (buf != NULL)
+	use_malloc = true;
+      else
+	goto out_fail;
+    }
+
+  struct iovec iov = { buf, buf_size };
+
   if (TEMP_FAILURE_RETRY (__sendto (fd, (void *) &req, sizeof (req), 0,
 				    (struct sockaddr *) &nladdr,
 				    sizeof (nladdr))) < 0)
-    return -1;
+    goto out_fail;
 
   *seen_ipv4 = false;
   *seen_ipv6 = false;
 
   bool done = false;
-  char buf[4096];
-  struct iovec iov = { buf, sizeof (buf) };
   struct in6ailist
   {
     struct in6addrinfo info;
@@ -101,10 +122,10 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
 
       ssize_t read_len = TEMP_FAILURE_RETRY (__recvmsg (fd, &msg, 0));
       if (read_len < 0)
-	return -1;
+	goto out_fail;
 
       if (msg.msg_flags & MSG_TRUNC)
-	return -1;
+	goto out_fail;
 
       struct nlmsghdr *nlmh;
       for (nlmh = (struct nlmsghdr *) buf;
@@ -186,7 +207,7 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
     {
       *in6ai = malloc (in6ailistlen * sizeof (**in6ai));
       if (*in6ai == NULL)
-	return -1;
+	goto out_fail;
 
       *in6ailen = in6ailistlen;
 
@@ -198,6 +219,13 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
       while (in6ailist != NULL);
     }
 
+  if (use_malloc)
+    free (buf);
+  return 0;
+
+out_fail:
+  if (use_malloc)
+    free (buf);
   return 0;
 }
 
diff --git a/sysdeps/unix/sysv/linux/ifaddrs.c b/sysdeps/unix/sysv/linux/ifaddrs.c
index 6c0f6b3dce..02e6935538 100644
--- a/sysdeps/unix/sysv/linux/ifaddrs.c
+++ b/sysdeps/unix/sysv/linux/ifaddrs.c
@@ -122,37 +122,36 @@ int
 __netlink_request (struct netlink_handle *h, int type)
 {
   struct netlink_res *nlm_next;
-  struct netlink_res **new_nlm_list;
-  static volatile size_t buf_size = 4096;
-  char *buf;
   struct sockaddr_nl nladdr;
   struct nlmsghdr *nlmh;
   ssize_t read_len;
   bool done = false;
-  bool use_malloc = false;
 
-  if (__netlink_sendreq (h, type) < 0)
-    return -1;
+#ifdef PAGE_SIZE
+  /* Help the compiler optimize out the malloc call if PAGE_SIZE
+     is constant and smaller or equal to PTHREAD_STACK_MIN/4.  */
+  const size_t buf_size = PAGE_SIZE;
+#else
+  const size_t buf_size = __getpagesize ();
+#endif
+  bool use_malloc = false;
+  char *buf;
 
-  size_t this_buf_size = buf_size;
-  size_t orig_this_buf_size = this_buf_size;
-  if (__libc_use_alloca (this_buf_size))
-    buf = alloca (this_buf_size);
+  if (__libc_use_alloca (buf_size))
+    buf = alloca (buf_size);
   else
     {
-      buf = malloc (this_buf_size);
+      buf = malloc (buf_size);
       if (buf != NULL)
 	use_malloc = true;
       else
 	goto out_fail;
     }
 
-  struct iovec iov = { buf, this_buf_size };
+  struct iovec iov = { buf, buf_size };
 
-  if (h->nlm_list != NULL)
-    new_nlm_list = &h->end_ptr->next;
-  else
-    new_nlm_list = &h->nlm_list;
+  if (__netlink_sendreq (h, type) < 0)
+    goto out_fail;
 
   while (! done)
     {
@@ -172,48 +171,7 @@ __netlink_request (struct netlink_handle *h, int type)
 	continue;
 
       if (__builtin_expect (msg.msg_flags & MSG_TRUNC, 0))
-	{
-	  if (this_buf_size >= SIZE_MAX / 2)
-	    goto out_fail;
-
-	  nlm_next = *new_nlm_list;
-	  while (nlm_next != NULL)
-	    {
-	      struct netlink_res *tmpptr;
-
-	      tmpptr = nlm_next->next;
-	      free (nlm_next);
-	      nlm_next = tmpptr;
-	    }
-	  *new_nlm_list = NULL;
-
-	  if (__libc_use_alloca (2 * this_buf_size))
-	    buf = extend_alloca (buf, this_buf_size, 2 * this_buf_size);
-	  else
-	    {
-	      this_buf_size *= 2;
-
-	      char *new_buf = realloc (use_malloc ? buf : NULL, this_buf_size);
-	      if (new_buf == NULL)
-		goto out_fail;
-	      buf = new_buf;
-
-	      use_malloc = true;
-	    }
-	  buf_size = this_buf_size;
-
-	  iov.iov_base = buf;
-	  iov.iov_len = this_buf_size;
-
-	  /* Increase sequence number, so that we can distinguish
-	     between old and new request messages.  */
-	  h->seq++;
-
-	  if (__netlink_sendreq (h, type) < 0)
-	    goto out_fail;
-
-	  continue;
-	}
+	goto out_fail;
 
       size_t count = 0;
       size_t remaining_len = read_len;
@@ -237,36 +195,6 @@ __netlink_request (struct netlink_handle *h, int type)
 	      struct nlmsgerr *nlerr = (struct nlmsgerr *) NLMSG_DATA (nlmh);
 	      if (nlmh->nlmsg_len < NLMSG_LENGTH (sizeof (struct nlmsgerr)))
 		errno = EIO;
-	      else if (nlerr->error == -EBUSY
-		       && orig_this_buf_size != this_buf_size)
-		{
-		  /* If EBUSY and MSG_TRUNC was seen, try again with a new
-		     netlink socket.  */
-		  struct netlink_handle hold = *h;
-		  if (__netlink_open (h) < 0)
-		    {
-		      *h = hold;
-		      goto out_fail;
-		    }
-		  __netlink_close (&hold);
-		  orig_this_buf_size = this_buf_size;
-		  nlm_next = *new_nlm_list;
-		  while (nlm_next != NULL)
-		    {
-		      struct netlink_res *tmpptr;
-
-		      tmpptr = nlm_next->next;
-		      free (nlm_next);
-		      nlm_next = tmpptr;
-		    }
-		  *new_nlm_list = NULL;
-		  count = 0;
-		  h->seq++;
-
-		  if (__netlink_sendreq (h, type) < 0)
-		    goto out_fail;
-		  break;
-		}
 	      else
 		errno = -nlerr->error;
 	      goto out_fail;