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
openSUSE Build Service is sponsored by