Re: git: 9b569353e0b0 - main - tcp: initialize V_ts_offset_secret for all vnets

From: Mark Johnston <markj_at_freebsd.org>
Date: Mon, 12 Aug 2024 15:20:23 UTC
On Sat, Aug 10, 2024 at 12:07:35PM +0200, tuexen@freebsd.org wrote:
> > On 10. Aug 2024, at 02:20, Zhenlei Huang <zlei@FreeBSD.org> wrote:
> > 
> > 
> > 
> >> On Aug 9, 2024, at 10:15 PM, Michael Tuexen <tuexen@FreeBSD.org> wrote:
> >> 
> >> The branch main has been updated by tuexen:
> >> 
> >> URL: https://cgit.FreeBSD.org/src/commit/?id=9b569353e0b073a513cf10debbe634c2ceb29fdf
> >> 
> >> commit 9b569353e0b073a513cf10debbe634c2ceb29fdf
> >> Author:     Michael Tuexen <tuexen@FreeBSD.org>
> >> AuthorDate: 2024-08-09 14:12:22 +0000
> >> Commit:     Michael Tuexen <tuexen@FreeBSD.org>
> >> CommitDate: 2024-08-09 14:12:22 +0000
> >> 
> >>  tcp: initialize V_ts_offset_secret for all vnets
> >> 
> >>  Initialize V_ts_offset_secret for each vnet, not only for the
> >>  default vnet, since it is vnet specific.
> >> 
> >>  Reviewed by:            Peter Lei
> >>  MFC after:              3 days
> >>  Sponsored by:           Netflix, Inc.
> >>  Differential Revision:  https://reviews.freebsd.org/D46246
> >> ---
> >> sys/netinet/tcp_subr.c | 2 +-
> >> 1 file changed, 1 insertion(+), 1 deletion(-)
> >> 
> >> diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
> >> index 9e95a87b3596..9b5f2651fb35 100644
> >> --- a/sys/netinet/tcp_subr.c
> >> +++ b/sys/netinet/tcp_subr.c
> >> @@ -1465,6 +1465,7 @@ tcp_vnet_init(void *arg __unused)
> >> VNET_PCPUSTAT_ALLOC(tcpstat, M_WAITOK);
> >> 
> >> V_tcp_msl = TCPTV_MSL;
> >> + arc4rand(&V_ts_offset_secret, sizeof(V_ts_offset_secret), 0);
> > 
> > Emm, does it have any (potential) security problems if not initialized ? If yes then does it deserve an SA ?
> I don't know, if it deserves a SA. I plan to MFC it after 3 days and would
> like to get it included in 13.4 (I sent a notice announcing this to re@
> yesterday).
> 
> The consequence of the bug is that the offset for the TCP timestamp is
> predictable for all vnets not being the default vnet (vnet0).
> 
> So an attacker could setup TCP connections to multiple TCP endpoints
> and try to figure out
> * if they belong to the same host.
> * what the ticks value of the host is.
> 
> However, this requires
> (a) the attacker knows that the TCP endpoints are on a FreeBSD host.
> (b) that at least two TCP endpoints are not in vnet0.
> (c) the attacker knows the way the offset is computed.
> 
> (c) is a consequence of (a).
> 
> I also CC'ed the security team, so they are aware of it and can chime in.

I don't really see why two endpoints are needed to figure out the uptime
of the host.  The timestamp we use is a hash of the connection 4-tuple
and the secret, which is all zeroes for a VNET jail affected by this bug.

One could precompute the hash outputs for some range of time values,
connect twice to the same endpoint, and check to see whether the
timestamps correspond to two of the precomputed values in a way that
roughly matches the time delta between the connections.  Assuming a),
one can then infer 1) whether the endpoint is in a VNET jail, and 2) the
uptime of the host.

This assumes that the VNET isn't behind a NAT service, since otherwise
the 4-tuple will be different, but even then the search space might be
small enough to succeed.