kern/185996: For IPv6, ipsec_address returns pointer to corrupted data
Luc Revardel
lrevardel at nvidia.com
Wed Jan 22 12:10:01 UTC 2014
>Number: 185996
>Category: kern
>Synopsis: For IPv6, ipsec_address returns pointer to corrupted data
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Wed Jan 22 12:10:00 UTC 2014
>Closed-Date:
>Last-Modified:
>Originator: Luc Revardel
>Release: 8.4.0
>Organization:
nVidia
>Environment:
Linux 2.6.24-24-generic #1 SMP Fri Jul 24 22:46:06 UTC 2009 i686 GNU/Linux
>Description:
When INET6 is defined, ipsec_address returns a pointer to a local variable if called for an AF_INET6 address. The content of this address is unknown after returning from the function.
This leads to inconsistent display errors such as in this error message:
esp_input_cb: authentication hash mismatch for packet in SA @E«/89a23692
>How-To-Repeat:
Simply call ipsec_address() with a pointer to a properly initialized sockaddr_in6.
Print the content of returned buffer after the call.
struct sockaddr_in6 in6Addr = { /***/};
char *buf;
buf = ipsec_address((union sockaddr_union*) &in6Addr);
printf("IPv6 Addr: %s\n", buf);
>Fix:
Move the logic used in inet_ntoa4 (4 static buffers) into ipsec_address so that it'll apply to both ipv4 & ipv6:
#ifdef INET
/* Return a printable string for the IPv4 address. */
static char *
inet_ntoa4(char *buf, struct in_addr ina)
{
unsigned char *ucp = (unsigned char *) &ina;
sprintf(buf, "%d.%d.%d.%d", ucp[0] & 0xff, ucp[1] & 0xff,
ucp[2] & 0xff, ucp[3] & 0xff);
return (buf);
}
#endif
/* Return a printable string for the address. */
char *
ipsec_address(union sockaddr_union* sa)
{
static char buf[4][INET6_ADDRSTRLEN]; /* ICERA_PORT */
static int i = 3;
i = (i + 1) % 4;
switch (sa->sa.sa_family) {
#ifdef INET
case AF_INET:
return (inet_ntoa4(buf[i], sa->sin.sin_addr));
#endif /* INET */
#ifdef INET6
case AF_INET6:
return (ip6_sprintf(buf[i], &sa->sin6.sin6_addr));
#endif /* INET6 */
default:
return ("(unknown address family)");
}
}
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list