pkgsrc-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[pkgsrc/trunk]: pkgsrc/net/libfetch/files Fix strict aliasing issue which GCC...
details: https://anonhg.NetBSD.org/pkgsrc/rev/b8fd218aa359
branches: trunk
changeset: 396966:b8fd218aa359
user: tnn <tnn%pkgsrc.org@localhost>
date: Thu Aug 06 14:02:38 2009 +0000
description:
Fix strict aliasing issue which GCC 4.4 complained about.
While we know that "struct sockaddr_storage" has been engineered to alias
to all the sockaddr structs, the compiler does not know about this.
Thus, code like this may be unsafe to use:
struct sockaddr_storage ss;
struct sockaddr_in *sin = &ss;
sin->sin_port = 0; /* dereferencing here breaks ISO C aliasing rules */
A workaround is to wrap the struct in a union, e.g:
union anonymous {
struct sockaddr_storage ss;
struct sockaddr_in sin;
} u;
u.sin.sin_port = 0;
--
Approved by: joerg
diffstat:
net/libfetch/files/ftp.c | 81 +++++++++++++++++++++++------------------------
1 files changed, 40 insertions(+), 41 deletions(-)
diffs (188 lines):
diff -r 2c8ef7526deb -r b8fd218aa359 net/libfetch/files/ftp.c
--- a/net/libfetch/files/ftp.c Thu Aug 06 13:54:03 2009 +0000
+++ b/net/libfetch/files/ftp.c Thu Aug 06 14:02:38 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ftp.c,v 1.27 2009/02/22 19:11:48 joerg Exp $ */
+/* $NetBSD: ftp.c,v 1.28 2009/08/06 14:02:38 tnn Exp $ */
/*-
* Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
* Copyright (c) 2008, 2009 Joerg Sonnenberger <joerg%NetBSD.org@localhost>
@@ -620,9 +620,12 @@
ftp_transfer(conn_t *conn, const char *oper, const char *file, const char *op_arg,
int mode, off_t offset, const char *flags)
{
- struct sockaddr_storage sa;
- struct sockaddr_in6 *sin6;
- struct sockaddr_in *sin4;
+ union anonymous {
+ struct sockaddr_storage ss;
+ struct sockaddr sa;
+ struct sockaddr_in6 sin6;
+ struct sockaddr_in sin4;
+ } u;
const char *bindaddr;
const char *filename;
int filenamelen, type;
@@ -650,16 +653,16 @@
goto ouch;
/* find our own address, bind, and listen */
- l = sizeof(sa);
- if (getsockname(conn->sd, (struct sockaddr *)&sa, &l) == -1)
+ l = sizeof(u.ss);
+ if (getsockname(conn->sd, &u.sa, &l) == -1)
goto sysouch;
- if (sa.ss_family == AF_INET6)
- unmappedaddr((struct sockaddr_in6 *)&sa, &l);
+ if (u.ss.ss_family == AF_INET6)
+ unmappedaddr(&u.sin6, &l);
retry_mode:
/* open data socket */
- if ((sd = socket(sa.ss_family, SOCK_STREAM, IPPROTO_TCP)) == -1) {
+ if ((sd = socket(u.ss.ss_family, SOCK_STREAM, IPPROTO_TCP)) == -1) {
fetch_syserr();
return (NULL);
}
@@ -673,7 +676,7 @@
/* send PASV command */
if (verbose)
fetch_info("setting passive mode");
- switch (sa.ss_family) {
+ switch (u.ss.ss_family) {
case AF_INET:
if ((e = ftp_cmd(conn, "PASV")) != FTP_PASSIVE_MODE)
goto ouch;
@@ -746,28 +749,26 @@
goto sysouch;
/* construct sockaddr for data socket */
- l = sizeof(sa);
- if (getpeername(conn->sd, (struct sockaddr *)&sa, &l) == -1)
+ l = sizeof(u.ss);
+ if (getpeername(conn->sd, &u.sa, &l) == -1)
goto sysouch;
- if (sa.ss_family == AF_INET6)
- unmappedaddr((struct sockaddr_in6 *)&sa, &l);
- switch (sa.ss_family) {
+ if (u.ss.ss_family == AF_INET6)
+ unmappedaddr(&u.sin6, &l);
+ switch (u.ss.ss_family) {
case AF_INET6:
- sin6 = (struct sockaddr_in6 *)&sa;
if (e == FTP_EPASSIVE_MODE)
- sin6->sin6_port = htons(port);
+ u.sin6.sin6_port = htons(port);
else {
- memcpy(&sin6->sin6_addr, addr + 2, 16);
- memcpy(&sin6->sin6_port, addr + 19, 2);
+ memcpy(&u.sin6.sin6_addr, addr + 2, 16);
+ memcpy(&u.sin6.sin6_port, addr + 19, 2);
}
break;
case AF_INET:
- sin4 = (struct sockaddr_in *)&sa;
if (e == FTP_EPASSIVE_MODE)
- sin4->sin_port = htons(port);
+ u.sin4.sin_port = htons(port);
else {
- memcpy(&sin4->sin_addr, addr, 4);
- memcpy(&sin4->sin_port, addr + 4, 2);
+ memcpy(&u.sin4.sin_addr, addr, 4);
+ memcpy(&u.sin4.sin_port, addr + 4, 2);
}
break;
default:
@@ -780,9 +781,9 @@
fetch_info("opening data connection");
bindaddr = getenv("FETCH_BIND_ADDRESS");
if (bindaddr != NULL && *bindaddr != '\0' &&
- fetch_bind(sd, sa.ss_family, bindaddr) != 0)
+ fetch_bind(sd, u.ss.ss_family, bindaddr) != 0)
goto sysouch;
- if (connect(sd, (struct sockaddr *)&sa, l) == -1)
+ if (connect(sd, &u.sa, l) == -1)
goto sysouch;
/* make the server initiate the transfer */
@@ -806,9 +807,9 @@
char *ap;
char hname[INET6_ADDRSTRLEN];
- switch (sa.ss_family) {
+ switch (u.ss.ss_family) {
case AF_INET6:
- ((struct sockaddr_in6 *)&sa)->sin6_port = 0;
+ u.sin6.sin6_port = 0;
#ifdef IPV6_PORTRANGE
arg = low ? IPV6_PORTRANGE_DEFAULT : IPV6_PORTRANGE_HIGH;
if (setsockopt(sd, IPPROTO_IPV6, IPV6_PORTRANGE,
@@ -817,7 +818,7 @@
#endif
break;
case AF_INET:
- ((struct sockaddr_in *)&sa)->sin_port = 0;
+ u.sin4.sin_port = 0;
#ifdef IP_PORTRANGE
arg = low ? IP_PORTRANGE_DEFAULT : IP_PORTRANGE_HIGH;
if (setsockopt(sd, IPPROTO_IP, IP_PORTRANGE,
@@ -828,19 +829,18 @@
}
if (verbose)
fetch_info("binding data socket");
- if (bind(sd, (struct sockaddr *)&sa, l) == -1)
+ if (bind(sd, &u.sa, l) == -1)
goto sysouch;
if (listen(sd, 1) == -1)
goto sysouch;
/* find what port we're on and tell the server */
- if (getsockname(sd, (struct sockaddr *)&sa, &l) == -1)
+ if (getsockname(sd, &u.sa, &l) == -1)
goto sysouch;
- switch (sa.ss_family) {
+ switch (u.ss.ss_family) {
case AF_INET:
- sin4 = (struct sockaddr_in *)&sa;
- a = ntohl(sin4->sin_addr.s_addr);
- p = ntohs(sin4->sin_port);
+ a = ntohl(u.sin4.sin_addr.s_addr);
+ p = ntohs(u.sin4.sin_port);
e = ftp_cmd(conn, "PORT %d,%d,%d,%d,%d,%d",
(a >> 24) & 0xff, (a >> 16) & 0xff,
(a >> 8) & 0xff, a & 0xff,
@@ -849,18 +849,17 @@
case AF_INET6:
#define UC(b) (((int)b)&0xff)
e = -1;
- sin6 = (struct sockaddr_in6 *)&sa;
- sin6->sin6_scope_id = 0;
- if (getnameinfo((struct sockaddr *)&sa, l,
+ u.sin6.sin6_scope_id = 0;
+ if (getnameinfo(&u.sa, l,
hname, sizeof(hname),
NULL, 0, NI_NUMERICHOST) == 0) {
e = ftp_cmd(conn, "EPRT |%d|%s|%d|", 2, hname,
- htons(sin6->sin6_port));
+ htons(u.sin6.sin6_port));
if (e == -1)
goto ouch;
}
if (e != FTP_OK) {
- ap = (char *)&sin6->sin6_addr;
+ ap = (char *)&u.sin6.sin6_addr;
e = ftp_cmd(conn,
"LPRT %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
6, 16,
@@ -869,8 +868,8 @@
UC(ap[8]), UC(ap[9]), UC(ap[10]), UC(ap[11]),
UC(ap[12]), UC(ap[13]), UC(ap[14]), UC(ap[15]),
2,
- (ntohs(sin6->sin6_port) >> 8) & 0xff,
- ntohs(sin6->sin6_port) & 0xff);
+ (ntohs(u.sin6.sin6_port) >> 8) & 0xff,
+ ntohs(u.sin6.sin6_port) & 0xff);
}
break;
default:
Home |
Main Index |
Thread Index |
Old Index