Thu Oct 17 23:58:05 2013 UTC ()
Avoid casting gymnastics that lead to pointer aliasing by introducing an
inline function.


(christos)
diff -r1.23 -r1.24 src/lib/libc/rpc/clnt_vc.c

cvs diff -r1.23 -r1.24 src/lib/libc/rpc/clnt_vc.c (expand / switch to unified diff)

--- src/lib/libc/rpc/clnt_vc.c 2013/05/07 21:08:45 1.23
+++ src/lib/libc/rpc/clnt_vc.c 2013/10/17 23:58:05 1.24
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: clnt_vc.c,v 1.23 2013/05/07 21:08:45 christos Exp $ */ 1/* $NetBSD: clnt_vc.c,v 1.24 2013/10/17 23:58:05 christos Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2010, Oracle America, Inc. 4 * Copyright (c) 2010, Oracle America, Inc.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are 7 * modification, are permitted provided that the following conditions are
8 * met: 8 * met:
9 * 9 *
10 * * Redistributions of source code must retain the above copyright 10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above 12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following 13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials 14 * disclaimer in the documentation and/or other materials
@@ -28,27 +28,27 @@ @@ -28,27 +28,27 @@
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35#if defined(LIBC_SCCS) && !defined(lint) 35#if defined(LIBC_SCCS) && !defined(lint)
36#if 0 36#if 0
37static char *sccsid = "@(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro"; 37static char *sccsid = "@(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro";
38static char *sccsid = "@(#)clnt_tcp.c 2.2 88/08/01 4.0 RPCSRC"; 38static char *sccsid = "@(#)clnt_tcp.c 2.2 88/08/01 4.0 RPCSRC";
39static char sccsid[] = "@(#)clnt_vc.c 1.19 89/03/16 Copyr 1988 Sun Micro"; 39static char sccsid[] = "@(#)clnt_vc.c 1.19 89/03/16 Copyr 1988 Sun Micro";
40#else 40#else
41__RCSID("$NetBSD: clnt_vc.c,v 1.23 2013/05/07 21:08:45 christos Exp $"); 41__RCSID("$NetBSD: clnt_vc.c,v 1.24 2013/10/17 23:58:05 christos Exp $");
42#endif 42#endif
43#endif 43#endif
44  44
45/* 45/*
46 * clnt_tcp.c, Implements a TCP/IP based, client side RPC. 46 * clnt_tcp.c, Implements a TCP/IP based, client side RPC.
47 * 47 *
48 * Copyright (C) 1984, Sun Microsystems, Inc. 48 * Copyright (C) 1984, Sun Microsystems, Inc.
49 * 49 *
50 * TCP based RPC supports 'batched calls'. 50 * TCP based RPC supports 'batched calls'.
51 * A sequence of calls may be batched-up in a send buffer. The rpc call 51 * A sequence of calls may be batched-up in a send buffer. The rpc call
52 * return immediately to the client even though the call was not necessarily 52 * return immediately to the client even though the call was not necessarily
53 * sent. The batching occurs if the results' xdr routine is NULL (0) AND 53 * sent. The batching occurs if the results' xdr routine is NULL (0) AND
54 * the rpc timeout value is zero (see clnt.h, rpc). 54 * the rpc timeout value is zero (see clnt.h, rpc).
@@ -134,26 +134,53 @@ extern mutex_t clnt_fd_lock; @@ -134,26 +134,53 @@ extern mutex_t clnt_fd_lock;
134static cond_t *vc_cv; 134static cond_t *vc_cv;
135#define release_fd_lock(fd, mask) { \ 135#define release_fd_lock(fd, mask) { \
136 mutex_lock(&clnt_fd_lock); \ 136 mutex_lock(&clnt_fd_lock); \
137 vc_fd_locks[fd] = 0; \ 137 vc_fd_locks[fd] = 0; \
138 mutex_unlock(&clnt_fd_lock); \ 138 mutex_unlock(&clnt_fd_lock); \
139 thr_sigsetmask(SIG_SETMASK, &(mask), NULL); \ 139 thr_sigsetmask(SIG_SETMASK, &(mask), NULL); \
140 cond_signal(&vc_cv[fd]); \ 140 cond_signal(&vc_cv[fd]); \
141} 141}
142#else 142#else
143#define release_fd_lock(fd,mask) 143#define release_fd_lock(fd,mask)
144#define __rpc_lock_value 0 144#define __rpc_lock_value 0
145#endif 145#endif
146 146
 147static __inline void
 148htonlp(void *dst, const void *src)
 149{
 150#if 0
 151 uint32_t tmp;
 152 memcpy(&tmp, src, sizeof(tmp));
 153 tmp = htonl(tmp);
 154 memcpy(dst, &tmp, sizeof(tmp));
 155#else
 156 /* We are aligned, so we think */
 157 *(uint32_t *)dst = htonl(*(const uint32_t *)src);
 158#endif
 159}
 160
 161static __inline void
 162ntohlp(void *dst, const void *src)
 163{
 164#if 0
 165 uint32_t tmp;
 166 memcpy(&tmp, src, sizeof(tmp));
 167 tmp = ntohl(tmp);
 168 memcpy(dst, &tmp, sizeof(tmp));
 169#else
 170 /* We are aligned, so we think */
 171 *(uint32_t *)dst = htonl(*(const uint32_t *)src);
 172#endif
 173}
147 174
148/* 175/*
149 * Create a client handle for a connection. 176 * Create a client handle for a connection.
150 * Default options are set, which the user can change using clnt_control()'s. 177 * Default options are set, which the user can change using clnt_control()'s.
151 * The rpc/vc package does buffering similar to stdio, so the client 178 * The rpc/vc package does buffering similar to stdio, so the client
152 * must pick send and receive buffer sizes, 0 => use the default. 179 * must pick send and receive buffer sizes, 0 => use the default.
153 * NB: fd is copied into a private area. 180 * NB: fd is copied into a private area.
154 * NB: The rpch->cl_auth is set null authentication. Caller may wish to 181 * NB: The rpch->cl_auth is set null authentication. Caller may wish to
155 * set this something more useful. 182 * set this something more useful.
156 * 183 *
157 * fd should be an open socket 184 * fd should be an open socket
158 */ 185 */
159CLIENT * 186CLIENT *
@@ -568,69 +595,60 @@ clnt_vc_control( @@ -568,69 +595,60 @@ clnt_vc_control(
568 case CLGET_SVC_ADDR: 595 case CLGET_SVC_ADDR:
569 /* The caller should not free this memory area */ 596 /* The caller should not free this memory area */
570 *(struct netbuf *)(void *)info = ct->ct_addr; 597 *(struct netbuf *)(void *)info = ct->ct_addr;
571 break; 598 break;
572 case CLSET_SVC_ADDR: /* set to new address */ 599 case CLSET_SVC_ADDR: /* set to new address */
573 release_fd_lock(ct->ct_fd, mask); 600 release_fd_lock(ct->ct_fd, mask);
574 return (FALSE); 601 return (FALSE);
575 case CLGET_XID: 602 case CLGET_XID:
576 /* 603 /*
577 * use the knowledge that xid is the 604 * use the knowledge that xid is the
578 * first element in the call structure 605 * first element in the call structure
579 * This will get the xid of the PREVIOUS call 606 * This will get the xid of the PREVIOUS call
580 */ 607 */
581 *(u_int32_t *)(void *)info = 608 ntohlp(info, &ct->ct_u.ct_mcalli);
582 ntohl(*(u_int32_t *)(void *)&ct->ct_u.ct_mcalli); 
583 break; 609 break;
584 case CLSET_XID: 610 case CLSET_XID:
585 /* This will set the xid of the NEXT call */ 611 /* This will set the xid of the NEXT call */
586 *(u_int32_t *)(void *)&ct->ct_u.ct_mcalli = 612 htonlp(&ct->ct_u.ct_mcalli, (const char *)info +
587 htonl(*((u_int32_t *)(void *)info) + 1); 613 sizeof(uint32_t));
588 /* increment by 1 as clnt_vc_call() decrements once */ 614 /* increment by 1 as clnt_vc_call() decrements once */
589 break; 615 break;
590 case CLGET_VERS: 616 case CLGET_VERS:
591 /* 617 /*
592 * This RELIES on the information that, in the call body, 618 * This RELIES on the information that, in the call body,
593 * the version number field is the fifth field from the 619 * the version number field is the fifth field from the
594 * begining of the RPC header. MUST be changed if the 620 * begining of the RPC header. MUST be changed if the
595 * call_struct is changed 621 * call_struct is changed
596 */ 622 */
597 *(u_int32_t *)(void *)info = 623 ntohlp(info, ct->ct_u.ct_mcallc + 4 * BYTES_PER_XDR_UNIT);
598 ntohl(*(u_int32_t *)(void *)(ct->ct_u.ct_mcallc + 
599 4 * BYTES_PER_XDR_UNIT)); 
600 break; 624 break;
601 625
602 case CLSET_VERS: 626 case CLSET_VERS:
603 *(u_int32_t *)(void *)(ct->ct_u.ct_mcallc + 627 htonlp(ct->ct_u.ct_mcallc + 4 * BYTES_PER_XDR_UNIT, info);
604 4 * BYTES_PER_XDR_UNIT) = 
605 htonl(*(u_int32_t *)(void *)info); 
606 break; 628 break;
607 629
608 case CLGET_PROG: 630 case CLGET_PROG:
609 /* 631 /*
610 * This RELIES on the information that, in the call body, 632 * This RELIES on the information that, in the call body,
611 * the program number field is the fourth field from the 633 * the program number field is the fourth field from the
612 * begining of the RPC header. MUST be changed if the 634 * begining of the RPC header. MUST be changed if the
613 * call_struct is changed 635 * call_struct is changed
614 */ 636 */
615 *(u_int32_t *)(void *)info = 637 ntohlp(info, ct->ct_u.ct_mcallc + 3 * BYTES_PER_XDR_UNIT);
616 ntohl(*(u_int32_t *)(void *)(ct->ct_u.ct_mcallc + 
617 3 * BYTES_PER_XDR_UNIT)); 
618 break; 638 break;
619 639
620 case CLSET_PROG: 640 case CLSET_PROG:
621 *(u_int32_t *)(void *)(ct->ct_u.ct_mcallc + 641 htonlp(ct->ct_u.ct_mcallc + 3 * BYTES_PER_XDR_UNIT, info);
622 3 * BYTES_PER_XDR_UNIT) = 
623 htonl(*(u_int32_t *)(void *)info); 
624 break; 642 break;
625 643
626 default: 644 default:
627 release_fd_lock(ct->ct_fd, mask); 645 release_fd_lock(ct->ct_fd, mask);
628 return (FALSE); 646 return (FALSE);
629 } 647 }
630 release_fd_lock(ct->ct_fd, mask); 648 release_fd_lock(ct->ct_fd, mask);
631 return (TRUE); 649 return (TRUE);
632} 650}
633 651
634 652
635static void 653static void
636clnt_vc_destroy(CLIENT *cl) 654clnt_vc_destroy(CLIENT *cl)