Bug 185996 - [ip6] For IPv6, ipsec_address returns pointer to corrupted data
Summary: [ip6] For IPv6, ipsec_address returns pointer to corrupted data
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: Unspecified
Hardware: Any Any
: Normal Affects Only Me
Assignee: Andrey V. Elsukov
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-01-22 12:10 UTC by Luc Revardel
Modified: 2019-01-21 09:36 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Luc Revardel 2014-01-22 12:10:00 UTC
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

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)");
	}
}
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);
Comment 1 Mark Linimon freebsd_committer freebsd_triage 2014-04-20 04:20:24 UTC
Responsible Changed
From-To: freebsd-bugs->freebsd-net

Over to maintainer(s).
Comment 2 commit-hook freebsd_committer freebsd_triage 2015-04-18 16:59:07 UTC
A commit references this bug:

Author: ae
Date: Sat Apr 18 16:58:36 UTC 2015
New revision: 281695
URL: https://svnweb.freebsd.org/changeset/base/281695

Log:
  Change ipsec_address() and ipsec_logsastr() functions to take two
  additional arguments - buffer and size of this buffer.

  ipsec_address() is used to convert sockaddr structure to presentation
  format. The IPv6 part of this function returns pointer to the on-stack
  buffer and at the moment when it will be used by caller, it becames
  invalid. IPv4 version uses 4 static buffers and returns pointer to
  new buffer each time when it called. But anyway it is still possible
  to get corrupted data when several threads will use this function.

  ipsec_logsastr() is used to format string about SA entry. It also
  uses static buffer and has the same problem with concurrent threads.

  To fix these problems add the buffer pointer and size of this
  buffer to arguments. Now each caller will pass buffer and its size
  to these functions. Also convert all places where these functions
  are used (except disabled code).

  And now ipsec_address() uses inet_ntop() function from libkern.

  PR:		185996
  Differential Revision:	https://reviews.freebsd.org/D2321
  Reviewed by:	gnn
  Sponsored by:	Yandex LLC

Changes:
  head/sys/netipsec/ipsec.c
  head/sys/netipsec/ipsec.h
  head/sys/netipsec/ipsec_input.c
  head/sys/netipsec/ipsec_output.c
  head/sys/netipsec/xform_ah.c
  head/sys/netipsec/xform_esp.c
  head/sys/netipsec/xform_ipcomp.c
Comment 3 Eitan Adler freebsd_committer freebsd_triage 2018-05-28 19:45:22 UTC
batch change:

For bugs that match the following
-  Status Is In progress 
AND
- Untouched since 2018-01-01.
AND
- Affects Base System OR Documentation

DO:

Reset to open status.


Note:
I did a quick pass but if you are getting this email it might be worthwhile to double check to see if this bug ought to be closed.
Comment 4 Oleksandr Tymoshenko freebsd_committer freebsd_triage 2019-01-21 09:36:35 UTC
There is a commit referencing this PR, but it's still not closed and has been inactive for some time. Closing the PR as fixed but feel free to re-open it if the issue hasn't been completely resolved.

Thanks