Skip to content

Commit

Permalink
tcp: should drop incoming frames without ACK flag set
Browse files Browse the repository at this point in the history
In commit 96e0bf4 (tcp: Discard segments that ack data not yet
sent) John Dykstra enforced a check against ack sequences.

In commit 354e4aa (tcp: RFC 5961 5.2 Blind Data Injection Attack
Mitigation) I added more safety tests.

But we missed fact that these tests are not performed if ACK bit is
not set.

RFC 793 3.9 mandates TCP should drop a frame without ACK flag set.

" fifth check the ACK field,
      if the ACK bit is off drop the segment and return"

Not doing so permits an attacker to only guess an acceptable sequence
number, evading stronger checks.

Many thanks to Zhiyun Qian for bringing this issue to our attention.

See :
http://web.eecs.umich.edu/~zhiyunq/pub/ccs12_TCP_sequence_number_inference.pdf

Reported-by: Zhiyun Qian <[email protected]>
Signed-off-by: Eric Dumazet <[email protected]>
Cc: Nandita Dukkipati <[email protected]>
Cc: Neal Cardwell <[email protected]>
Cc: John Dykstra <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Eric Dumazet authored and davem330 committed Dec 26, 2012
1 parent 3d0dcfb commit c3ae62a
Showing 1 changed file with 10 additions and 4 deletions.
14 changes: 10 additions & 4 deletions net/ipv4/tcp_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -5543,6 +5543,9 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
if (len < (th->doff << 2) || tcp_checksum_complete_user(sk, skb))
goto csum_error;

if (!th->ack)
goto discard;

/*
* Standard slow path.
*/
Expand All @@ -5551,7 +5554,7 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
return 0;

step5:
if (th->ack && tcp_ack(sk, skb, FLAG_SLOWPATH) < 0)
if (tcp_ack(sk, skb, FLAG_SLOWPATH) < 0)
goto discard;

/* ts_recent update must be made after we are sure that the packet
Expand Down Expand Up @@ -5984,11 +5987,15 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
if (tcp_check_req(sk, skb, req, NULL, true) == NULL)
goto discard;
}

if (!th->ack)
goto discard;

if (!tcp_validate_incoming(sk, skb, th, 0))
return 0;

/* step 5: check the ACK field */
if (th->ack) {
if (true) {
int acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH) > 0;

switch (sk->sk_state) {
Expand Down Expand Up @@ -6138,8 +6145,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
}
break;
}
} else
goto discard;
}

/* ts_recent update must be made after we are sure that the packet
* is in window.
Expand Down

0 comments on commit c3ae62a

Please sign in to comment.