[PATCH 4/4] tcp: make challenge acks less predictable

Stefan Bader stefan.bader at canonical.com
Fri Aug 12 14:02:15 UTC 2016


On 12.08.2016 15:58, Tim Gardner wrote:
> On 08/12/2016 07:30 AM, Tim Gardner wrote:
>> From: Eric Dumazet <edumazet at google.com>
>>
>> Yue Cao claims that current host rate limiting of challenge ACKS
>> (RFC 5961) could leak enough information to allow a patient attacker
>> to hijack TCP sessions. He will soon provide details in an academic
>> paper.
>>
>> This patch increases the default limit from 100 to 1000, and adds
>> some randomization so that the attacker can no longer hijack
>> sessions without spending a considerable amount of probes.
>>
>> Based on initial analysis and patch from Linus.
>>
>> Note that we also have per socket rate limiting, so it is tempting
>> to remove the host limit in the future.
>>
>> v2: randomize the count of challenge acks per second, not the period.
>>
>> Fixes: 282f23c6ee34 ("tcp: implement RFC 5961 3.2")
>> Reported-by: Yue Cao <ycao009 at ucr.edu>
>> Signed-off-by: Eric Dumazet <edumazet at google.com>
>> Suggested-by: Linus Torvalds <torvalds at linux-foundation.org>
>> Cc: Yuchung Cheng <ycheng at google.com>
>> Cc: Neal Cardwell <ncardwell at google.com>
>> Acked-by: Neal Cardwell <ncardwell at google.com>
>> Acked-by: Yuchung Cheng <ycheng at google.com>
>> Signed-off-by: David S. Miller <davem at davemloft.net>
>>
>> CVE-2016-5696
>>
>> (backported from commit 75ff39ccc1bd5d3c455b6822ab09e533c551f758 upstream)
>> Signed-off-by: Stefan Bader <stefan.bader at canonical.com>
>> Signed-off-by: Tim Gardner <tim.gardner at canonical.com>
>> ---
>>  net/ipv4/tcp_input.c | 16 ++++++++++++----
>>  1 file changed, 12 insertions(+), 4 deletions(-)
>>
>> diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
>> index 2cc1313..1bf94fa 100644
>> --- a/net/ipv4/tcp_input.c
>> +++ b/net/ipv4/tcp_input.c
>> @@ -86,7 +86,7 @@ int sysctl_tcp_adv_win_scale __read_mostly = 1;
>>  EXPORT_SYMBOL(sysctl_tcp_adv_win_scale);
>>  
>>  /* rfc5961 challenge ack rate limiting */
>> -int sysctl_tcp_challenge_ack_limit = 100;
>> +int sysctl_tcp_challenge_ack_limit = 1000;
>>  
>>  int sysctl_tcp_stdurg __read_mostly;
>>  int sysctl_tcp_rfc1337 __read_mostly;
>> @@ -3288,17 +3288,25 @@ static void tcp_send_challenge_ack(struct sock *sk)
>>  	/* unprotected vars, we dont care of overwrites */
>>  	static u32 challenge_timestamp;
>>  	static unsigned int challenge_count;
>> -	u32 now = jiffies / HZ;
>> +	u32 count, now = jiffies / HZ;
>>  
>> +	/* Check host-wide RFC 5961 rate limit. */
>>  	if (now != challenge_timestamp) {
>> +		u32 half = (sysctl_tcp_challenge_ack_limit + 1) >> 1;
>> +
>>  		challenge_timestamp = now;
>> -		challenge_count = 0;
>> +		*((volatile unsigned int *) &challenge_count) =
>> +		WRITE_ONCE(challenge_count, half +
>> +			   prandom_u32_max(sysctl_tcp_challenge_ack_limit));
> 
> This seems kind of bogus. ^^

Yes, I had pulled back that function, too. But note that in the updated version
I replaced that with its expanded form...
> 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: OpenPGP digital signature
URL: <https://lists.ubuntu.com/archives/kernel-team/attachments/20160812/9ad377b5/attachment.sig>


More information about the kernel-team mailing list