File fix_sockaddr_overflow_in_ipsec_doi.c.diff of Package ipsec-tools
References: bnc#506710
Acked-by: Jiri Bohac <jbohac@suse.cz>
http://cvsweb.netbsd.org/bsdweb.cgi/src/crypto/dist/ipsec-tools/src/racoon/ipsec_doi.c.diff?r1=1.36&r2=1.37&f=h&f=u
===================================================================
RCS file: /ftp/cvs/cvsroot/src/crypto/dist/ipsec-tools/src/racoon/ipsec_doi.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -p -r1.36 -r1.37
--- a/src/racoon/ipsec_doi.c 2008/07/14 05:45:15 1.36
+++ a/src/racoon/ipsec_doi.c 2008/10/29 18:49:45 1.37
@@ -4486,20 +4486,29 @@ ipsecdoi_id2str(id)
char *dat;
static char buf[BUFLEN];
struct ipsecdoi_id_b *id_b = (struct ipsecdoi_id_b *)id->v;
- struct sockaddr saddr;
+ struct sockaddr_storage saddr_storage;
+ struct sockaddr *saddr;
+ struct sockaddr_in *saddr_in;
+ struct sockaddr_in6 *saddr_in6;
u_int plen = 0;
+ saddr = (struct sockaddr *)&saddr_storage;
+ saddr_in = (struct sockaddr_in *)&saddr_storage;
+ saddr_in6 = (struct sockaddr_in6 *)&saddr_storage;
+
+
switch (id_b->type) {
case IPSECDOI_ID_IPV4_ADDR:
case IPSECDOI_ID_IPV4_ADDR_SUBNET:
case IPSECDOI_ID_IPV4_ADDR_RANGE:
#ifndef __linux__
- saddr.sa_len = sizeof(struct sockaddr_in);
+ saddr->sa_len = sizeof(struct sockaddr_in);
#endif
- saddr.sa_family = AF_INET;
- ((struct sockaddr_in *)&saddr)->sin_port = IPSEC_PORT_ANY;
- memcpy(&((struct sockaddr_in *)&saddr)->sin_addr,
+ saddr->sa_family = AF_INET;
+
+ saddr_in->sin_port = IPSEC_PORT_ANY;
+ memcpy(&saddr_in->sin_addr,
id->v + sizeof(*id_b), sizeof(struct in_addr));
break;
#ifdef INET6
@@ -4508,12 +4517,17 @@ ipsecdoi_id2str(id)
case IPSECDOI_ID_IPV6_ADDR_RANGE:
#ifndef __linux__
- saddr.sa_len = sizeof(struct sockaddr_in6);
+ saddr->sa_len = sizeof(struct sockaddr_in6);
#endif
- saddr.sa_family = AF_INET6;
- ((struct sockaddr_in6 *)&saddr)->sin6_port = IPSEC_PORT_ANY;
- memcpy(&((struct sockaddr_in6 *)&saddr)->sin6_addr,
+ saddr->sa_family = AF_INET6;
+
+ saddr_in6->sin6_port = IPSEC_PORT_ANY;
+ memcpy(&saddr_in6->sin6_addr,
id->v + sizeof(*id_b), sizeof(struct in6_addr));
+ saddr_in6->sin6_scope_id =
+ (IN6_IS_ADDR_LINKLOCAL(&saddr_in6->sin6_addr)
+ ? ((struct sockaddr_in6 *)id_b)->sin6_scope_id
+ : 0);
break;
#endif
}
@@ -4523,7 +4537,7 @@ ipsecdoi_id2str(id)
#ifdef INET6
case IPSECDOI_ID_IPV6_ADDR:
#endif
- len = snprintf( buf, BUFLEN, "%s", saddrwop2str(&saddr));
+ len = snprintf( buf, BUFLEN, "%s", saddrwop2str(saddr));
break;
case IPSECDOI_ID_IPV4_ADDR_SUBNET:
@@ -4579,42 +4593,46 @@ ipsecdoi_id2str(id)
plen += l;
}
- len = snprintf( buf, BUFLEN, "%s/%i", saddrwop2str(&saddr), plen);
+ len = snprintf( buf, BUFLEN, "%s/%i", saddrwop2str(saddr), plen);
}
break;
case IPSECDOI_ID_IPV4_ADDR_RANGE:
- len = snprintf( buf, BUFLEN, "%s-", saddrwop2str(&saddr));
+ len = snprintf( buf, BUFLEN, "%s-", saddrwop2str(saddr));
#ifndef __linux__
- saddr.sa_len = sizeof(struct sockaddr_in);
+ saddr->sa_len = sizeof(struct sockaddr_in);
#endif
- saddr.sa_family = AF_INET;
- ((struct sockaddr_in *)&saddr)->sin_port = IPSEC_PORT_ANY;
- memcpy(&((struct sockaddr_in *)&saddr)->sin_addr,
+ saddr->sa_family = AF_INET;
+ saddr_in->sin_port = IPSEC_PORT_ANY;
+ memcpy(&saddr_in->sin_addr,
id->v + sizeof(*id_b) + sizeof(struct in_addr),
sizeof(struct in_addr));
- len += snprintf( buf + len, BUFLEN - len, "%s", saddrwop2str(&saddr));
+ len += snprintf( buf + len, BUFLEN - len, "%s", saddrwop2str(saddr));
break;
#ifdef INET6
case IPSECDOI_ID_IPV6_ADDR_RANGE:
- len = snprintf( buf, BUFLEN, "%s-", saddrwop2str(&saddr));
+ len = snprintf( buf, BUFLEN, "%s-", saddrwop2str(saddr));
#ifndef __linux__
- saddr.sa_len = sizeof(struct sockaddr_in6);
+ saddr->sa_len = sizeof(struct sockaddr_in6);
#endif
- saddr.sa_family = AF_INET6;
- ((struct sockaddr_in6 *)&saddr)->sin6_port = IPSEC_PORT_ANY;
- memcpy(&((struct sockaddr_in6 *)&saddr)->sin6_addr,
+ saddr->sa_family = AF_INET6;
+ saddr_in6->sin6_port = IPSEC_PORT_ANY;
+ memcpy(&saddr_in6->sin6_addr,
id->v + sizeof(*id_b) + sizeof(struct in6_addr),
sizeof(struct in6_addr));
+ saddr_in6->sin6_scope_id =
+ (IN6_IS_ADDR_LINKLOCAL(&saddr_in6->sin6_addr)
+ ? ((struct sockaddr_in6 *)id_b)->sin6_scope_id
+ : 0);
- len += snprintf( buf + len, BUFLEN - len, "%s", saddrwop2str(&saddr));
+ len += snprintf( buf + len, BUFLEN - len, "%s", saddrwop2str(saddr));
break;
#endif