about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2012-11-09 18:21:59 +0000
committerJoseph Myers <joseph@codesourcery.com>2012-11-09 18:21:59 +0000
commitfb1ae1eede65c9b7227d8f3da2e27fd720b8b711 (patch)
treed1f65cb9773c6ac0121ca7897fcbfd59af969b4a
parent554066b83b1a0d14e6e7a24a45ef3f65342aae76 (diff)
downloadglibc-fb1ae1eede65c9b7227d8f3da2e27fd720b8b711.tar.gz
glibc-fb1ae1eede65c9b7227d8f3da2e27fd720b8b711.tar.xz
glibc-fb1ae1eede65c9b7227d8f3da2e27fd720b8b711.zip
Fix sunrpc 64-bit (especially big-endian) issues (bug 14821).
-rw-r--r--ChangeLog9
-rw-r--r--NEWS2
-rw-r--r--sunrpc/clnt_tcp.c41
-rw-r--r--sunrpc/clnt_udp.c30
-rw-r--r--sunrpc/clnt_unix.c41
5 files changed, 66 insertions, 57 deletions
diff --git a/ChangeLog b/ChangeLog
index 7eb7e8f777..7808ff83b7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2012-11-09  Joseph Myers  <joseph@codesourcery.com>
+
+	[BZ #14821]
+	* sunrpc/clnt_tcp.c (clnttcp_control): Access values at fixed
+	offset in buffer as u_int32_t not u_long.  Consistently use memcpy
+	for copies of such integer values.
+	* sunrpc/clnt_udp.c (clntudp_control): Likewise.
+	* sunrpc/clnt_unix.c (clntunix_control): Likewise.
+
 2012-11-09  Andreas Jaeger  <aj@suse.de>
 
 	* sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h: Remove all
diff --git a/NEWS b/NEWS
index f6af227141..fa49ee5f3b 100644
--- a/NEWS
+++ b/NEWS
@@ -19,7 +19,7 @@ Version 2.17
   14562, 14568, 14576, 14579, 14583, 14587, 14595, 14602, 14610, 14621,
   14638, 14645, 14648, 14652, 14660, 14661, 14669, 14683, 14694, 14716,
   14743, 14767, 14783, 14784, 14785, 14793, 14796, 14797, 14801, 14805,
-  14807, 14809, 14811, 14815.
+  14807, 14809, 14811, 14815, 14821.
 
 * Support for STT_GNU_IFUNC symbols added for s390 and s390x.
   Optimized versions of memcpy, memset, and memcmp added for System z10 and
diff --git a/sunrpc/clnt_tcp.c b/sunrpc/clnt_tcp.c
index 6bd4c8c0cd..ec85930e44 100644
--- a/sunrpc/clnt_tcp.c
+++ b/sunrpc/clnt_tcp.c
@@ -364,8 +364,8 @@ static bool_t
 clnttcp_control (CLIENT *cl, int request, char *info)
 {
   struct ct_data *ct = (struct ct_data *) cl->cl_private;
-  u_long *mcall_ptr;
   u_long ul;
+  u_int32_t ui32;
 
 
   switch (request)
@@ -395,24 +395,15 @@ clnttcp_control (CLIENT *cl, int request, char *info)
        * first element in the call structure *.
        * This will get the xid of the PREVIOUS call
        */
-#if 0
-      /* This original code has aliasing issues.  */
-      *(u_long *)info = ntohl (*(u_long *)ct->ct_mcall);
-#else
-      mcall_ptr = (u_long *)ct->ct_mcall;
-      ul = ntohl (*mcall_ptr);
+      memcpy (&ui32, ct->ct_mcall, sizeof (ui32));
+      ul = ntohl (ui32);
       memcpy (info, &ul, sizeof (ul));
-#endif
       break;
     case CLSET_XID:
       /* This will set the xid of the NEXT call */
-#if 0
-      /* This original code has aliasing issues.  */
-      *(u_long *)ct->ct_mcall =  htonl (*(u_long *)info - 1);
-#else
-      ul = ntohl (*(u_long *)info - 1);
-      memcpy (ct->ct_mcall, &ul, sizeof (ul));
-#endif
+      memcpy (&ul, info, sizeof (ul));
+      ui32 = htonl (ul - 1);
+      memcpy (ct->ct_mcall, &ui32, sizeof (ui32));
       /* decrement by 1 as clnttcp_call() increments once */
       break;
     case CLGET_VERS:
@@ -422,12 +413,14 @@ clnttcp_control (CLIENT *cl, int request, char *info)
        * begining of the RPC header. MUST be changed if the
        * call_struct is changed
        */
-      *(u_long *)info = ntohl (*(u_long *)(ct->ct_mcall +
-					   4 * BYTES_PER_XDR_UNIT));
+      memcpy (&ui32, ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT, sizeof (ui32));
+      ul = ntohl (ui32);
+      memcpy (info, &ul, sizeof (ul));
       break;
     case CLSET_VERS:
-      *(u_long *)(ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT)
-	= htonl (*(u_long *)info);
+      memcpy (&ul, info, sizeof (ul));
+      ui32 = htonl (ul);
+      memcpy (ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT, &ui32, sizeof (ui32));
       break;
     case CLGET_PROG:
       /*
@@ -436,12 +429,14 @@ clnttcp_control (CLIENT *cl, int request, char *info)
        * begining of the RPC header. MUST be changed if the
        * call_struct is changed
        */
-      *(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall +
-					  3 * BYTES_PER_XDR_UNIT));
+      memcpy (&ui32, ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT, sizeof (ui32));
+      ul = ntohl (ui32);
+      memcpy (info, &ul, sizeof (ul));
       break;
     case CLSET_PROG:
-      *(u_long *)(ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT)
-	= htonl(*(u_long *)info);
+      memcpy (&ul, info, sizeof (ul));
+      ui32 = htonl (ul);
+      memcpy (ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT, &ui32, sizeof (ui32));
       break;
     /* The following are only possible with TI-RPC */
     case CLGET_RETRY_TIMEOUT:
diff --git a/sunrpc/clnt_udp.c b/sunrpc/clnt_udp.c
index 7ecf2ef5a5..8890cc6cfc 100644
--- a/sunrpc/clnt_udp.c
+++ b/sunrpc/clnt_udp.c
@@ -547,6 +547,8 @@ static bool_t
 clntudp_control (CLIENT *cl, int request, char *info)
 {
   struct cu_data *cu = (struct cu_data *) cl->cl_private;
+  u_long ul;
+  u_int32_t ui32;
 
   switch (request)
     {
@@ -580,11 +582,15 @@ clntudp_control (CLIENT *cl, int request, char *info)
        * first element in the call structure *.
        * This will get the xid of the PREVIOUS call
        */
-      *(u_long *)info = ntohl(*(u_long *)cu->cu_outbuf);
+      memcpy (&ui32, cu->cu_outbuf, sizeof (ui32));
+      ul = ntohl (ui32);
+      memcpy (info, &ul, sizeof (ul));
       break;
     case CLSET_XID:
       /* This will set the xid of the NEXT call */
-      *(u_long *)cu->cu_outbuf =  htonl(*(u_long *)info - 1);
+      memcpy (&ul, info, sizeof (ul));
+      ui32 = htonl (ul - 1);
+      memcpy (cu->cu_outbuf, &ui32, sizeof (ui32));
       /* decrement by 1 as clntudp_call() increments once */
       break;
     case CLGET_VERS:
@@ -594,12 +600,14 @@ clntudp_control (CLIENT *cl, int request, char *info)
        * begining of the RPC header. MUST be changed if the
        * call_struct is changed
        */
-      *(u_long *)info = ntohl(*(u_long *)(cu->cu_outbuf +
-					  4 * BYTES_PER_XDR_UNIT));
+      memcpy (&ui32, cu->cu_outbuf + 4 * BYTES_PER_XDR_UNIT, sizeof (ui32));
+      ul = ntohl (ui32);
+      memcpy (info, &ul, sizeof (ul));
       break;
     case CLSET_VERS:
-      *(u_long *)(cu->cu_outbuf + 4 * BYTES_PER_XDR_UNIT)
-	= htonl(*(u_long *)info);
+      memcpy (&ul, info, sizeof (ul));
+      ui32 = htonl (ul);
+      memcpy (cu->cu_outbuf + 4 * BYTES_PER_XDR_UNIT, &ui32, sizeof (ui32));
       break;
     case CLGET_PROG:
       /*
@@ -608,12 +616,14 @@ clntudp_control (CLIENT *cl, int request, char *info)
        * begining of the RPC header. MUST be changed if the
        * call_struct is changed
        */
-      *(u_long *)info = ntohl(*(u_long *)(cu->cu_outbuf +
-					  3 * BYTES_PER_XDR_UNIT));
+      memcpy (&ui32, cu->cu_outbuf + 3 * BYTES_PER_XDR_UNIT, sizeof (ui32));
+      ul = ntohl (ui32);
+      memcpy (info, &ul, sizeof (ul));
       break;
     case CLSET_PROG:
-      *(u_long *)(cu->cu_outbuf + 3 * BYTES_PER_XDR_UNIT)
-	= htonl(*(u_long *)info);
+      memcpy (&ul, info, sizeof (ul));
+      ui32 = htonl (ul);
+      memcpy (cu->cu_outbuf + 3 * BYTES_PER_XDR_UNIT, &ui32, sizeof (ui32));
       break;
     /* The following are only possible with TI-RPC */
     case CLGET_SVC_ADDR:
diff --git a/sunrpc/clnt_unix.c b/sunrpc/clnt_unix.c
index 776ceab484..9b5d7ca822 100644
--- a/sunrpc/clnt_unix.c
+++ b/sunrpc/clnt_unix.c
@@ -338,8 +338,8 @@ static bool_t
 clntunix_control (CLIENT *cl, int request, char *info)
 {
   struct ct_data *ct = (struct ct_data *) cl->cl_private;
-  u_long *mcall_ptr;
   u_long ul;
+  u_int32_t ui32;
 
   switch (request)
     {
@@ -367,24 +367,15 @@ clntunix_control (CLIENT *cl, int request, char *info)
        * first element in the call structure *.
        * This will get the xid of the PREVIOUS call
        */
-#if 0
-      /* This original code has aliasing issues.  */
-      *(u_long *) info = ntohl (*(u_long *)ct->ct_mcall);
-#else
-      mcall_ptr = (u_long *)ct->ct_mcall;
-      ul = ntohl (*mcall_ptr);
+      memcpy (&ui32, ct->ct_mcall, sizeof (ui32));
+      ul = ntohl (ui32);
       memcpy (info, &ul, sizeof (ul));
-#endif
       break;
     case CLSET_XID:
       /* This will set the xid of the NEXT call */
-#if 0
-      /* This original code has aliasing issues.  */
-      *(u_long *) ct->ct_mcall =  htonl (*(u_long *)info - 1);
-#else
-      ul = ntohl (*(u_long *)info - 1);
-      memcpy (ct->ct_mcall, &ul, sizeof (ul));
-#endif
+      memcpy (&ul, info, sizeof (ul));
+      ui32 = htonl (ul - 1);
+      memcpy (ct->ct_mcall, &ui32, sizeof (ui32));
       /* decrement by 1 as clntunix_call() increments once */
       break;
     case CLGET_VERS:
@@ -394,12 +385,14 @@ clntunix_control (CLIENT *cl, int request, char *info)
        * begining of the RPC header. MUST be changed if the
        * call_struct is changed
        */
-      *(u_long *) info = ntohl (*(u_long *) (ct->ct_mcall
-					     + 4 * BYTES_PER_XDR_UNIT));
+      memcpy (&ui32, ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT, sizeof (ui32));
+      ul = ntohl (ui32);
+      memcpy (info, &ul, sizeof (ul));
       break;
     case CLSET_VERS:
-      *(u_long *) (ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT)
-	= htonl (*(u_long *) info);
+      memcpy (&ul, info, sizeof (ul));
+      ui32 = htonl (ul);
+      memcpy (ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT, &ui32, sizeof (ui32));
       break;
     case CLGET_PROG:
       /*
@@ -408,12 +401,14 @@ clntunix_control (CLIENT *cl, int request, char *info)
        * begining of the RPC header. MUST be changed if the
        * call_struct is changed
        */
-      *(u_long *) info = ntohl (*(u_long *) (ct->ct_mcall
-					     + 3 * BYTES_PER_XDR_UNIT));
+      memcpy (&ui32, ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT, sizeof (ui32));
+      ul = ntohl (ui32);
+      memcpy (info, &ul, sizeof (ul));
       break;
     case CLSET_PROG:
-      *(u_long *) (ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT)
-	= htonl(*(u_long *) info);
+      memcpy (&ul, info, sizeof (ul));
+      ui32 = htonl (ul);
+      memcpy (ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT, &ui32, sizeof (ui32));
       break;
     /* The following are only possible with TI-RPC */
     case CLGET_RETRY_TIMEOUT: