* [PATCH] Fix accepting invalid RST segments
@ 2009-05-25 10:35 Jozsef Kadlecsik
2009-05-25 15:24 ` Patrick McHardy
0 siblings, 1 reply; 2+ messages in thread
From: Jozsef Kadlecsik @ 2009-05-25 10:35 UTC (permalink / raw)
To: Patrick McHardy, netfilter-devel
Hi Patrick,
Robert L Mathews discovered that some clients send evil TCP RST segments,
which are accepted by netfilter conntrack but discarded by the
destination. Thus the conntrack entry is destroyed but the destination
retransmits data until timeout.
The same technique, i.e. sending properly crafted RST segments, can easily
be used to bypass connlimit/connbytes based restrictions (the sample
script written by Robert can be found in the netfilter mailing list
archives).
The patch below adds a new flag and new field to struct ip_ct_tcp_state so
that checking RST segments can be made more strict and thus TCP conntrack
can catch the invalid ones: the RST segment is accepted only if its
sequence number higher than or equal to the highest ack we seen from the
other direction. (The last_ack field cannot be reused because it is used
to catch resent packets.)
Please send the patch for kernel inclusion.
Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
diff --git a/include/linux/netfilter/nf_conntrack_tcp.h b/include/linux/netfilter/nf_conntrack_tcp.h
index 3066789..b2f384d 100644
--- a/include/linux/netfilter/nf_conntrack_tcp.h
+++ b/include/linux/netfilter/nf_conntrack_tcp.h
@@ -35,6 +35,9 @@ enum tcp_conntrack {
/* Has unacknowledged data */
#define IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED 0x10
+/* The field td_maxack has been set */
+#define IP_CT_TCP_FLAG_MAXACK_SET 0x20
+
struct nf_ct_tcp_flags {
__u8 flags;
__u8 mask;
@@ -46,6 +49,7 @@ struct ip_ct_tcp_state {
u_int32_t td_end; /* max of seq + len */
u_int32_t td_maxend; /* max of ack + max(win, 1) */
u_int32_t td_maxwin; /* max(win) */
+ u_int32_t td_maxack; /* max of ack */
u_int8_t td_scale; /* window scale factor */
u_int8_t flags; /* per direction options */
};
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index b5ccf2b..97a6e93 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -634,6 +634,14 @@ static bool tcp_in_window(const struct nf_conn *ct,
sender->td_end = end;
sender->flags |= IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED;
}
+ if (tcph->ack) {
+ if (!(sender->flags & IP_CT_TCP_FLAG_MAXACK_SET)) {
+ sender->td_maxack = ack;
+ sender->flags |= IP_CT_TCP_FLAG_MAXACK_SET;
+ } else if (after(ack, sender->td_maxack))
+ sender->td_maxack = ack;
+ }
+
/*
* Update receiver data.
*/
@@ -919,6 +927,16 @@ static int tcp_packet(struct nf_conn *ct,
return -NF_ACCEPT;
case TCP_CONNTRACK_CLOSE:
if (index == TCP_RST_SET
+ && (ct->proto.tcp.seen[!dir].flags & IP_CT_TCP_FLAG_MAXACK_SET)
+ && before(ntohl(th->seq), ct->proto.tcp.seen[!dir].td_maxack)) {
+ /* Invalid RST */
+ write_unlock_bh(&tcp_lock);
+ if (LOG_INVALID(net, IPPROTO_TCP))
+ nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
+ "nf_ct_tcp: invalid RST ");
+ return -NF_ACCEPT;
+ }
+ if (index == TCP_RST_SET
&& ((test_bit(IPS_SEEN_REPLY_BIT, &ct->status)
&& ct->proto.tcp.last_index == TCP_SYN_SET)
|| (!test_bit(IPS_ASSURED_BIT, &ct->status)
Best regards,
Jozsef
-
E-mail : kadlec@blackhole.kfki.hu, kadlec@mail.kfki.hu
PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt
Address : KFKI Research Institute for Particle and Nuclear Physics
H-1525 Budapest 114, POB. 49, Hungary
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] Fix accepting invalid RST segments
2009-05-25 10:35 [PATCH] Fix accepting invalid RST segments Jozsef Kadlecsik
@ 2009-05-25 15:24 ` Patrick McHardy
0 siblings, 0 replies; 2+ messages in thread
From: Patrick McHardy @ 2009-05-25 15:24 UTC (permalink / raw)
To: Jozsef Kadlecsik; +Cc: netfilter-devel
Jozsef Kadlecsik wrote:
> Hi Patrick,
>
> Robert L Mathews discovered that some clients send evil TCP RST segments,
> which are accepted by netfilter conntrack but discarded by the
> destination. Thus the conntrack entry is destroyed but the destination
> retransmits data until timeout.
>
> The same technique, i.e. sending properly crafted RST segments, can easily
> be used to bypass connlimit/connbytes based restrictions (the sample
> script written by Robert can be found in the netfilter mailing list
> archives).
>
> The patch below adds a new flag and new field to struct ip_ct_tcp_state so
> that checking RST segments can be made more strict and thus TCP conntrack
> can catch the invalid ones: the RST segment is accepted only if its
> sequence number higher than or equal to the highest ack we seen from the
> other direction. (The last_ack field cannot be reused because it is used
> to catch resent packets.)
Applied, thanks.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2009-05-25 15:24 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-05-25 10:35 [PATCH] Fix accepting invalid RST segments Jozsef Kadlecsik
2009-05-25 15:24 ` Patrick McHardy
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).