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.24-534-g5c6e674


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  5c6e6747356f5d473c2c62e818bc24432ddef3e2 (commit)
      from  a36451ff4142b63a76cea9e52ffe4687290071a4 (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=5c6e6747356f5d473c2c62e818bc24432ddef3e2

commit 5c6e6747356f5d473c2c62e818bc24432ddef3e2
Author: Florian Weimer <fweimer@redhat.com>
Date:   Tue Dec 27 16:44:15 2016 +0100

    sunrpc: Always obtain AF_INET addresses from NSS [BZ #20964]
    
    The new __libc_rpc_gethostbyname function calls gethostbyname2_r
    with an AF_INET argument and is therefore not affected by the
    RES_USE_INET6 flag.
    
    Validated with the following test program, with and without
    RES_OPTIONS=inet6, against a NFS server.  (Link with -lrpcsvc.)
    
    #include <rpc/clnt.h>
    #include <rpcsvc/mount.h>
    #include <stdio.h>
    #include <string.h>
    
    static void
    usage (char **argv)
    {
      printf ("usage:\n"
              "  %1$s HOST getrpcport\n"
              "  %1$s HOST callrpc\n"
              "  %1$s HOST clnt_create\n",
              argv[0]);
    }
    
    static void
    dump_exports (struct exportnode *exports)
    {
      while (exports != NULL)
        {
          printf ("%s\n", exports->ex_dir);
          exports = exports->ex_next;
        }
    }
    
    int
    main (int argc, char **argv)
    {
      if (argc != 3)
        {
          usage (argv);
          return 1;
        }
    
      const char *host = argv[1];
      const char *command = argv[2];
    
      if (strcmp (command, "getrpcport") == 0)
        {
          int port = getrpcport (host, MOUNTPROG, MOUNTVERS, IPPROTO_UDP);
          printf ("getrpcport: %d\n", port);
        }
      else if (strcmp (command, "callrpc") == 0)
        {
          struct exportnode *exports = NULL;
          int ret = callrpc (host, MOUNTPROG, MOUNTVERS, MOUNTPROC_EXPORT,
                             (xdrproc_t) xdr_void, NULL,
                             (xdrproc_t) xdr_exports, (char *)&exports);
          if (ret != 0)
            {
              clnt_perrno (ret);
              puts ("");
              return 1;
            }
          dump_exports (exports);
        }
      else if (strcmp (command, "clnt_create") == 0)
        {
          CLIENT *client = clnt_create
            (host, MOUNTPROG, MOUNTVERS, "udp");
          if (client == NULL)
            {
              printf ("error: clnt_create failed\n");
              return 1;
            }
          struct exportnode *exports = NULL;
          int ret = CLNT_CALL (client, MOUNTPROC_EXPORT,
                               (xdrproc_t) xdr_void, NULL,
                               (xdrproc_t) xdr_exports, (char *)&exports,
                               ((struct timeval) {15, 0}));
          if (ret != 0)
            {
              clnt_perrno (ret);
              puts ("");
              return 1;
            }
          dump_exports (exports);
        }
      else
        {
          usage (argv);
          return 1;
        }
    
      return 0;
    }

diff --git a/ChangeLog b/ChangeLog
index 9854d6b..55fa54f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
 2016-12-27  Florian Weimer  <fweimer@redhat.com>
 
+	[BZ #20964]
+	sunrpc: Always obtain AF_INET addresses from NSS.
+	* include/rpc/rpc.h (__libc_rpc_gethostbyname): Declare.
+	* sunrpc/rpc_gethostbyname.c: New file.
+	* sunrpc/Makefile (routines): Add it.
+	* sunrpc/clnt_gen.c (clnt_create): Use __libc_rpc_gethostbyname.
+	* sunrpc/clnt_simp.c (callrpc): Likewise.
+	* sunrpc/getrpcport.c (getrpcport): Likewise.
+
+2016-12-27  Florian Weimer  <fweimer@redhat.com>
+
 	* sunrpc/rpcinfo.c: Remove.
 	* sunrpc/Makefile: Remove comments referring to rpcinfo.
 
diff --git a/include/rpc/rpc.h b/include/rpc/rpc.h
index 4c9ee82..60c7896 100644
--- a/include/rpc/rpc.h
+++ b/include/rpc/rpc.h
@@ -57,6 +57,12 @@ libc_hidden_proto (__rpc_thread_svc_pollfd)
 libc_hidden_proto (__rpc_thread_svc_fdset)
 libc_hidden_proto (__rpc_thread_createerr)
 
+/* Perform a host name lookup for NAME and return the first IPv4
+   address in *ADDR.  Return 0 on success and -1 on error (and set an
+   RPC error).  */
+int __libc_rpc_gethostbyname (const char *host, struct sockaddr_in *addr)
+  attribute_hidden;
+
 #endif /* _RPC_THREAD_SAFE_ */
 
 # endif /* !_ISOMAC */
diff --git a/sunrpc/Makefile b/sunrpc/Makefile
index da6dffa..f7c593a 100644
--- a/sunrpc/Makefile
+++ b/sunrpc/Makefile
@@ -78,7 +78,8 @@ routines := auth_none authuxprot bindrsvprt clnt_raw clnt_simp \
 	    des_crypt des_impl des_soft key_prot openchild rtime svcauth_des \
 	    getrpcent getrpcbyname getrpcbynumber \
 	    getrpcent_r getrpcbyname_r getrpcbynumber_r \
-	    clnt_unix svc_unix create_xid $(need-export-routines)
+	    clnt_unix svc_unix create_xid $(need-export-routines) \
+	    rpc_gethostbyname
 ifneq ($(link-obsolete-rpc),yes)
 # We only add the RPC for compatibility to libc.so.
 shared-only-routines = $(routines)
diff --git a/sunrpc/clnt_gen.c b/sunrpc/clnt_gen.c
index df34672..8dffaa9 100644
--- a/sunrpc/clnt_gen.c
+++ b/sunrpc/clnt_gen.c
@@ -45,9 +45,6 @@ CLIENT *
 clnt_create (const char *hostname, u_long prog, u_long vers,
 	     const char *proto)
 {
-  struct hostent hostbuf, *h;
-  size_t hstbuflen;
-  char *hsttmpbuf;
   struct protoent protobuf, *p;
   size_t prtbuflen;
   char *prttmpbuf;
@@ -56,7 +53,6 @@ clnt_create (const char *hostname, u_long prog, u_long vers,
   int sock;
   struct timeval tv;
   CLIENT *client;
-  int herr;
 
   if (strcmp (proto, "unix") == 0)
     {
@@ -78,37 +74,8 @@ clnt_create (const char *hostname, u_long prog, u_long vers,
       return client;
     }
 
-  hstbuflen = 1024;
-  hsttmpbuf = __alloca (hstbuflen);
-  while (__gethostbyname_r (hostname, &hostbuf, hsttmpbuf, hstbuflen,
-			    &h, &herr) != 0
-	 || h == NULL)
-    if (herr != NETDB_INTERNAL || errno != ERANGE)
-      {
-	get_rpc_createerr().cf_stat = RPC_UNKNOWNHOST;
-	return NULL;
-      }
-    else
-      {
-	/* Enlarge the buffer.  */
-	hstbuflen *= 2;
-	hsttmpbuf = __alloca (hstbuflen);
-      }
-
-  if (h->h_addrtype != AF_INET)
-    {
-      /*
-       * Only support INET for now
-       */
-      struct rpc_createerr *ce = &get_rpc_createerr ();
-      ce->cf_stat = RPC_SYSTEMERROR;
-      ce->cf_error.re_errno = EAFNOSUPPORT;
-      return NULL;
-    }
-  sin.sin_family = h->h_addrtype;
-  sin.sin_port = 0;
-  __bzero (sin.sin_zero, sizeof (sin.sin_zero));
-  memcpy ((char *) &sin.sin_addr, h->h_addr, h->h_length);
+  if (__libc_rpc_gethostbyname (hostname, &sin) != 0)
+    return NULL;
 
   prtbuflen = 1024;
   prttmpbuf = __alloca (prtbuflen);
diff --git a/sunrpc/clnt_simp.c b/sunrpc/clnt_simp.c
index d612df0..0ecb64c 100644
--- a/sunrpc/clnt_simp.c
+++ b/sunrpc/clnt_simp.c
@@ -61,7 +61,6 @@ callrpc (const char *host, u_long prognum, u_long versnum, u_long procnum,
   struct callrpc_private_s *crp = callrpc_private;
   struct sockaddr_in server_addr;
   enum clnt_stat clnt_stat;
-  struct hostent hostbuf, *hp;
   struct timeval timeout, tottimeout;
 
   if (crp == 0)
@@ -84,10 +83,6 @@ callrpc (const char *host, u_long prognum, u_long versnum, u_long procnum,
     }
   else
     {
-      size_t buflen;
-      char *buffer;
-      int herr;
-
       crp->valid = 0;
       if (crp->socket != RPC_ANYSOCK)
 	{
@@ -100,25 +95,11 @@ callrpc (const char *host, u_long prognum, u_long versnum, u_long procnum,
 	  crp->client = NULL;
 	}
 
-      buflen = 1024;
-      buffer = __alloca (buflen);
-      while (__gethostbyname_r (host, &hostbuf, buffer, buflen,
-				&hp, &herr) != 0
-	     || hp == NULL)
-	if (herr != NETDB_INTERNAL || errno != ERANGE)
-	  return (int) RPC_UNKNOWNHOST;
-	else
-	  {
-	    /* Enlarge the buffer.  */
-	    buflen *= 2;
-	    buffer = __alloca (buflen);
-	  }
+      if (__libc_rpc_gethostbyname (host, &server_addr) != 0)
+	return (int) get_rpc_createerr().cf_stat;
 
       timeout.tv_usec = 0;
       timeout.tv_sec = 5;
-      memcpy ((char *) &server_addr.sin_addr, hp->h_addr, hp->h_length);
-      server_addr.sin_family = AF_INET;
-      server_addr.sin_port = 0;
       if ((crp->client = clntudp_create (&server_addr, (u_long) prognum,
 			  (u_long) versnum, timeout, &crp->socket)) == NULL)
 	return (int) get_rpc_createerr().cf_stat;
diff --git a/sunrpc/getrpcport.c b/sunrpc/getrpcport.c
index 07ee8c0..8fde0a9 100644
--- a/sunrpc/getrpcport.c
+++ b/sunrpc/getrpcport.c
@@ -1,3 +1,21 @@
+/* Obtain the RPC port number for an RPC service on a host.
+   Copyright (C) 2016 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; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
 /*
  * Copyright (c) 2010, Oracle America, Inc.
  *
@@ -43,26 +61,8 @@ int
 getrpcport (const char *host, u_long prognum, u_long versnum, u_int proto)
 {
   struct sockaddr_in addr;
-  struct hostent hostbuf, *hp;
-  size_t buflen;
-  char *buffer;
-  int herr;
-
-  buflen = 1024;
-  buffer = __alloca (buflen);
-  while (__gethostbyname_r (host, &hostbuf, buffer, buflen, &hp, &herr) != 0
-	 || hp == NULL)
-    if (herr != NETDB_INTERNAL || errno != ERANGE)
-      return 0;
-    else
-      {
-	/* Enlarge the buffer.  */
-	buflen *= 2;
-	buffer = __alloca (buflen);
-      }
 
-  memcpy ((char *) &addr.sin_addr, hp->h_addr, hp->h_length);
-  addr.sin_family = AF_INET;
-  addr.sin_port = 0;
+  if (__libc_rpc_gethostbyname (host, &addr) != 0)
+    return 0;
   return pmap_getport (&addr, prognum, versnum, proto);
 }
diff --git a/sunrpc/rpc_gethostbyname.c b/sunrpc/rpc_gethostbyname.c
new file mode 100644
index 0000000..a2ee960
--- /dev/null
+++ b/sunrpc/rpc_gethostbyname.c
@@ -0,0 +1,73 @@
+/* IPv4-only variant of gethostbyname.
+   Copyright (C) 2016 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; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <netdb.h>
+#include <rpc/rpc.h>
+#include <scratch_buffer.h>
+#include <string.h>
+
+int
+__libc_rpc_gethostbyname (const char *host, struct sockaddr_in *addr)
+{
+  struct hostent hostbuf;
+  struct hostent *hp = NULL;
+  int herr;
+  struct scratch_buffer tmpbuf;
+  scratch_buffer_init (&tmpbuf);
+
+  while (__gethostbyname2_r (host, AF_INET,
+                             &hostbuf, tmpbuf.data, tmpbuf.length, &hp,
+                             &herr) != 0
+         || hp == NULL)
+    if (herr != NETDB_INTERNAL || errno != ERANGE)
+      {
+        struct rpc_createerr *ce = &get_rpc_createerr ();
+        ce->cf_stat = RPC_UNKNOWNHOST;
+        scratch_buffer_free (&tmpbuf);
+        return -1;
+      }
+    else
+      {
+        if (!scratch_buffer_grow (&tmpbuf))
+          {
+            /* If memory allocation failed, allocating the RPC error
+               structure might could as well, so this could lead to a
+               crash.  */
+            struct rpc_createerr *ce = &get_rpc_createerr ();
+            ce->cf_stat = RPC_SYSTEMERROR;
+            ce->cf_error.re_errno = ENOMEM;
+            return -1;
+          }
+      }
+
+  if (hp->h_addrtype != AF_INET || hp->h_length != sizeof (addr->sin_addr))
+    {
+      struct rpc_createerr *ce = &get_rpc_createerr ();
+      ce->cf_stat = RPC_SYSTEMERROR;
+      ce->cf_error.re_errno = EAFNOSUPPORT;
+      scratch_buffer_free (&tmpbuf);
+      return -1;
+    }
+
+  addr->sin_family = AF_INET;
+  addr->sin_port = htons (0);
+  memcpy (&addr->sin_addr, hp->h_addr, sizeof (addr->sin_addr));
+  scratch_buffer_free (&tmpbuf);
+  return 0;
+}

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

Summary of changes:
 ChangeLog                  |   11 ++++++
 include/rpc/rpc.h          |    6 +++
 sunrpc/Makefile            |    3 +-
 sunrpc/clnt_gen.c          |   37 +---------------------
 sunrpc/clnt_simp.c         |   23 +------------
 sunrpc/getrpcport.c        |   40 ++++++++++++------------
 sunrpc/rpc_gethostbyname.c |   73 ++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 116 insertions(+), 77 deletions(-)
 create mode 100644 sunrpc/rpc_gethostbyname.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]