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