netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] netfilter fixes for 3.11-rc4
@ 2013-08-10 16:58 Pablo Neira Ayuso
  2013-08-10 16:58 ` [PATCH 1/4] netfilter: xt_TCPMSS: fix handling of malformed TCP header and options Pablo Neira Ayuso
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Pablo Neira Ayuso @ 2013-08-10 16:58 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

Hi David,

The following patchset contains four netfilter fixes, they are:

* Fix possible invalid access and mangling of the TCPMSS option in
  xt_TCPMSS. This was spotted by Julian Anastasov.

* Fix possible off by one access and mangling of the TCP packet in
  xt_TCPOPTSTRIP, also spotted by Julian Anastasov.

* Fix possible information leak due to missing initialization of one
  padding field of several structures that are included in nfqueue and
  nflog netlink messages, from Dan Carpenter.

* Fix TCP window tracking with Fast Open, from Yuchung Cheng.

You can pull these changes from:

  git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git master

Thanks!

----------------------------------------------------------------

The following changes since commit a661b43fd047ef501da43a19975415f861c7c3db:

  mlx5: fix error return code in mlx5_alloc_uuars() (2013-07-30 19:33:45 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git master

for you to fetch changes up to 356d7d88e088687b6578ca64601b0a2c9d145296:

  netfilter: nf_conntrack: fix tcp_in_window for Fast Open (2013-08-10 18:36:22 +0200)

----------------------------------------------------------------
Dan Carpenter (1):
      netfilter: nfnetlink_{log,queue}: fix information leaks in netlink message

Pablo Neira Ayuso (2):
      netfilter: xt_TCPMSS: fix handling of malformed TCP header and options
      netfilter: xt_TCPOPTSTRIP: fix possible off by one access

Yuchung Cheng (1):
      netfilter: nf_conntrack: fix tcp_in_window for Fast Open

 net/netfilter/nf_conntrack_proto_tcp.c |   12 ++++++++----
 net/netfilter/nfnetlink_log.c          |    6 +++++-
 net/netfilter/nfnetlink_queue_core.c   |    5 ++++-
 net/netfilter/xt_TCPMSS.c              |   28 ++++++++++++++++------------
 net/netfilter/xt_TCPOPTSTRIP.c         |   10 ++++++----
 5 files changed, 39 insertions(+), 22 deletions(-)

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/4] netfilter: xt_TCPMSS: fix handling of malformed TCP header and options
  2013-08-10 16:58 [PATCH 0/4] netfilter fixes for 3.11-rc4 Pablo Neira Ayuso
@ 2013-08-10 16:58 ` Pablo Neira Ayuso
  2013-08-10 16:58 ` [PATCH 2/4] netfilter: xt_TCPOPTSTRIP: fix possible off by one access Pablo Neira Ayuso
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Pablo Neira Ayuso @ 2013-08-10 16:58 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

Make sure the packet has enough room for the TCP header and
that it is not malformed.

While at it, store tcph->doff*4 in a variable, as it is used
several times.

This patch also fixes a possible off by one in case of malformed
TCP options.

Reported-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/xt_TCPMSS.c |   28 ++++++++++++++++------------
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c
index 7011c71..6113cc7 100644
--- a/net/netfilter/xt_TCPMSS.c
+++ b/net/netfilter/xt_TCPMSS.c
@@ -52,7 +52,8 @@ tcpmss_mangle_packet(struct sk_buff *skb,
 {
 	const struct xt_tcpmss_info *info = par->targinfo;
 	struct tcphdr *tcph;
-	unsigned int tcplen, i;
+	int len, tcp_hdrlen;
+	unsigned int i;
 	__be16 oldval;
 	u16 newmss;
 	u8 *opt;
@@ -64,11 +65,14 @@ tcpmss_mangle_packet(struct sk_buff *skb,
 	if (!skb_make_writable(skb, skb->len))
 		return -1;
 
-	tcplen = skb->len - tcphoff;
+	len = skb->len - tcphoff;
+	if (len < (int)sizeof(struct tcphdr))
+		return -1;
+
 	tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff);
+	tcp_hdrlen = tcph->doff * 4;
 
-	/* Header cannot be larger than the packet */
-	if (tcplen < tcph->doff*4)
+	if (len < tcp_hdrlen)
 		return -1;
 
 	if (info->mss == XT_TCPMSS_CLAMP_PMTU) {
@@ -87,9 +91,8 @@ tcpmss_mangle_packet(struct sk_buff *skb,
 		newmss = info->mss;
 
 	opt = (u_int8_t *)tcph;
-	for (i = sizeof(struct tcphdr); i < tcph->doff*4; i += optlen(opt, i)) {
-		if (opt[i] == TCPOPT_MSS && tcph->doff*4 - i >= TCPOLEN_MSS &&
-		    opt[i+1] == TCPOLEN_MSS) {
+	for (i = sizeof(struct tcphdr); i <= tcp_hdrlen - TCPOLEN_MSS; i += optlen(opt, i)) {
+		if (opt[i] == TCPOPT_MSS && opt[i+1] == TCPOLEN_MSS) {
 			u_int16_t oldmss;
 
 			oldmss = (opt[i+2] << 8) | opt[i+3];
@@ -112,9 +115,10 @@ tcpmss_mangle_packet(struct sk_buff *skb,
 	}
 
 	/* There is data after the header so the option can't be added
-	   without moving it, and doing so may make the SYN packet
-	   itself too large. Accept the packet unmodified instead. */
-	if (tcplen > tcph->doff*4)
+	 * without moving it, and doing so may make the SYN packet
+	 * itself too large. Accept the packet unmodified instead.
+	 */
+	if (len > tcp_hdrlen)
 		return 0;
 
 	/*
@@ -143,10 +147,10 @@ tcpmss_mangle_packet(struct sk_buff *skb,
 		newmss = min(newmss, (u16)1220);
 
 	opt = (u_int8_t *)tcph + sizeof(struct tcphdr);
-	memmove(opt + TCPOLEN_MSS, opt, tcplen - sizeof(struct tcphdr));
+	memmove(opt + TCPOLEN_MSS, opt, len - sizeof(struct tcphdr));
 
 	inet_proto_csum_replace2(&tcph->check, skb,
-				 htons(tcplen), htons(tcplen + TCPOLEN_MSS), 1);
+				 htons(len), htons(len + TCPOLEN_MSS), 1);
 	opt[0] = TCPOPT_MSS;
 	opt[1] = TCPOLEN_MSS;
 	opt[2] = (newmss & 0xff00) >> 8;
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/4] netfilter: xt_TCPOPTSTRIP: fix possible off by one access
  2013-08-10 16:58 [PATCH 0/4] netfilter fixes for 3.11-rc4 Pablo Neira Ayuso
  2013-08-10 16:58 ` [PATCH 1/4] netfilter: xt_TCPMSS: fix handling of malformed TCP header and options Pablo Neira Ayuso
@ 2013-08-10 16:58 ` Pablo Neira Ayuso
  2013-08-10 16:58 ` [PATCH 3/4] netfilter: nfnetlink_{log,queue}: fix information leaks in netlink message Pablo Neira Ayuso
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Pablo Neira Ayuso @ 2013-08-10 16:58 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

Fix a possible off by one access since optlen()
touches opt[offset+1] unsafely when i == tcp_hdrlen(skb) - 1.

This patch replaces tcp_hdrlen() by the local variable tcp_hdrlen
that stores the TCP header length, to save some cycles.

Reported-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/xt_TCPOPTSTRIP.c |   10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/net/netfilter/xt_TCPOPTSTRIP.c b/net/netfilter/xt_TCPOPTSTRIP.c
index b68fa19..625fa1d 100644
--- a/net/netfilter/xt_TCPOPTSTRIP.c
+++ b/net/netfilter/xt_TCPOPTSTRIP.c
@@ -38,7 +38,7 @@ tcpoptstrip_mangle_packet(struct sk_buff *skb,
 	struct tcphdr *tcph;
 	u_int16_t n, o;
 	u_int8_t *opt;
-	int len;
+	int len, tcp_hdrlen;
 
 	/* This is a fragment, no TCP header is available */
 	if (par->fragoff != 0)
@@ -52,7 +52,9 @@ tcpoptstrip_mangle_packet(struct sk_buff *skb,
 		return NF_DROP;
 
 	tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff);
-	if (tcph->doff * 4 > len)
+	tcp_hdrlen = tcph->doff * 4;
+
+	if (len < tcp_hdrlen)
 		return NF_DROP;
 
 	opt  = (u_int8_t *)tcph;
@@ -61,10 +63,10 @@ tcpoptstrip_mangle_packet(struct sk_buff *skb,
 	 * Walk through all TCP options - if we find some option to remove,
 	 * set all octets to %TCPOPT_NOP and adjust checksum.
 	 */
-	for (i = sizeof(struct tcphdr); i < tcp_hdrlen(skb); i += optl) {
+	for (i = sizeof(struct tcphdr); i < tcp_hdrlen - 1; i += optl) {
 		optl = optlen(opt, i);
 
-		if (i + optl > tcp_hdrlen(skb))
+		if (i + optl > tcp_hdrlen)
 			break;
 
 		if (!tcpoptstrip_test_bit(info->strip_bmap, opt[i]))
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/4] netfilter: nfnetlink_{log,queue}: fix information leaks in netlink message
  2013-08-10 16:58 [PATCH 0/4] netfilter fixes for 3.11-rc4 Pablo Neira Ayuso
  2013-08-10 16:58 ` [PATCH 1/4] netfilter: xt_TCPMSS: fix handling of malformed TCP header and options Pablo Neira Ayuso
  2013-08-10 16:58 ` [PATCH 2/4] netfilter: xt_TCPOPTSTRIP: fix possible off by one access Pablo Neira Ayuso
@ 2013-08-10 16:58 ` Pablo Neira Ayuso
  2013-08-10 16:58 ` [PATCH 4/4] netfilter: nf_conntrack: fix tcp_in_window for Fast Open Pablo Neira Ayuso
  2013-08-10 20:44 ` [PATCH 0/4] netfilter fixes for 3.11-rc4 David Miller
  4 siblings, 0 replies; 6+ messages in thread
From: Pablo Neira Ayuso @ 2013-08-10 16:58 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

From: Dan Carpenter <dan.carpenter@oracle.com>

These structs have a "_pad" member.  Also the "phw" structs have an 8
byte "hw_addr[]" array but sometimes only the first 6 bytes are
initialized.

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/nfnetlink_log.c        |    6 +++++-
 net/netfilter/nfnetlink_queue_core.c |    5 ++++-
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 962e979..d92cc31 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -419,6 +419,7 @@ __build_packet_message(struct nfnl_log_net *log,
 	nfmsg->version = NFNETLINK_V0;
 	nfmsg->res_id = htons(inst->group_num);
 
+	memset(&pmsg, 0, sizeof(pmsg));
 	pmsg.hw_protocol	= skb->protocol;
 	pmsg.hook		= hooknum;
 
@@ -498,7 +499,10 @@ __build_packet_message(struct nfnl_log_net *log,
 	if (indev && skb->dev &&
 	    skb->mac_header != skb->network_header) {
 		struct nfulnl_msg_packet_hw phw;
-		int len = dev_parse_header(skb, phw.hw_addr);
+		int len;
+
+		memset(&phw, 0, sizeof(phw));
+		len = dev_parse_header(skb, phw.hw_addr);
 		if (len > 0) {
 			phw.hw_addrlen = htons(len);
 			if (nla_put(inst->skb, NFULA_HWADDR, sizeof(phw), &phw))
diff --git a/net/netfilter/nfnetlink_queue_core.c b/net/netfilter/nfnetlink_queue_core.c
index 971ea14..8a703c3 100644
--- a/net/netfilter/nfnetlink_queue_core.c
+++ b/net/netfilter/nfnetlink_queue_core.c
@@ -463,7 +463,10 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
 	if (indev && entskb->dev &&
 	    entskb->mac_header != entskb->network_header) {
 		struct nfqnl_msg_packet_hw phw;
-		int len = dev_parse_header(entskb, phw.hw_addr);
+		int len;
+
+		memset(&phw, 0, sizeof(phw));
+		len = dev_parse_header(entskb, phw.hw_addr);
 		if (len) {
 			phw.hw_addrlen = htons(len);
 			if (nla_put(skb, NFQA_HWADDR, sizeof(phw), &phw))
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/4] netfilter: nf_conntrack: fix tcp_in_window for Fast Open
  2013-08-10 16:58 [PATCH 0/4] netfilter fixes for 3.11-rc4 Pablo Neira Ayuso
                   ` (2 preceding siblings ...)
  2013-08-10 16:58 ` [PATCH 3/4] netfilter: nfnetlink_{log,queue}: fix information leaks in netlink message Pablo Neira Ayuso
@ 2013-08-10 16:58 ` Pablo Neira Ayuso
  2013-08-10 20:44 ` [PATCH 0/4] netfilter fixes for 3.11-rc4 David Miller
  4 siblings, 0 replies; 6+ messages in thread
From: Pablo Neira Ayuso @ 2013-08-10 16:58 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

From: Yuchung Cheng <ycheng@google.com>

Currently the conntrack checks if the ending sequence of a packet
falls within the observed receive window. However it does so even
if it has not observe any packet from the remote yet and uses an
uninitialized receive window (td_maxwin).

If a connection uses Fast Open to send a SYN-data packet which is
dropped afterward in the network. The subsequent SYNs retransmits
will all fail this check and be discarded, leading to a connection
timeout. This is because the SYN retransmit does not contain data
payload so

end == initial sequence number (isn) + 1
sender->td_end == isn + syn_data_len
receiver->td_maxwin == 0

The fix is to only apply this check after td_maxwin is initialized.

Reported-by: Michael Chan <mcfchan@stanford.edu>
Signed-off-by: Yuchung Cheng <ycheng@google.com>
Acked-by: Eric Dumazet <edumazet@google.com>
Acked-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/nf_conntrack_proto_tcp.c |   12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 7dcc376..2f80107 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -526,7 +526,7 @@ static bool tcp_in_window(const struct nf_conn *ct,
 	const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
 	__u32 seq, ack, sack, end, win, swin;
 	s16 receiver_offset;
-	bool res;
+	bool res, in_recv_win;
 
 	/*
 	 * Get the required data from the packet.
@@ -649,14 +649,18 @@ static bool tcp_in_window(const struct nf_conn *ct,
 		 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
 		 receiver->td_scale);
 
+	/* Is the ending sequence in the receive window (if available)? */
+	in_recv_win = !receiver->td_maxwin ||
+		      after(end, sender->td_end - receiver->td_maxwin - 1);
+
 	pr_debug("tcp_in_window: I=%i II=%i III=%i IV=%i\n",
 		 before(seq, sender->td_maxend + 1),
-		 after(end, sender->td_end - receiver->td_maxwin - 1),
+		 (in_recv_win ? 1 : 0),
 		 before(sack, receiver->td_end + 1),
 		 after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1));
 
 	if (before(seq, sender->td_maxend + 1) &&
-	    after(end, sender->td_end - receiver->td_maxwin - 1) &&
+	    in_recv_win &&
 	    before(sack, receiver->td_end + 1) &&
 	    after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1)) {
 		/*
@@ -725,7 +729,7 @@ static bool tcp_in_window(const struct nf_conn *ct,
 			nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL,
 			"nf_ct_tcp: %s ",
 			before(seq, sender->td_maxend + 1) ?
-			after(end, sender->td_end - receiver->td_maxwin - 1) ?
+			in_recv_win ?
 			before(sack, receiver->td_end + 1) ?
 			after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1) ? "BUG"
 			: "ACK is under the lower bound (possible overly delayed ACK)"
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/4] netfilter fixes for 3.11-rc4
  2013-08-10 16:58 [PATCH 0/4] netfilter fixes for 3.11-rc4 Pablo Neira Ayuso
                   ` (3 preceding siblings ...)
  2013-08-10 16:58 ` [PATCH 4/4] netfilter: nf_conntrack: fix tcp_in_window for Fast Open Pablo Neira Ayuso
@ 2013-08-10 20:44 ` David Miller
  4 siblings, 0 replies; 6+ messages in thread
From: David Miller @ 2013-08-10 20:44 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel, netdev

From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Sat, 10 Aug 2013 18:58:49 +0200

> The following patchset contains four netfilter fixes, they are:
> 
> * Fix possible invalid access and mangling of the TCPMSS option in
>   xt_TCPMSS. This was spotted by Julian Anastasov.
> 
> * Fix possible off by one access and mangling of the TCP packet in
>   xt_TCPOPTSTRIP, also spotted by Julian Anastasov.
> 
> * Fix possible information leak due to missing initialization of one
>   padding field of several structures that are included in nfqueue and
>   nflog netlink messages, from Dan Carpenter.
> 
> * Fix TCP window tracking with Fast Open, from Yuchung Cheng.
> 
> You can pull these changes from:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git master

Pulled, thanks Pablo!

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2013-08-10 20:44 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-10 16:58 [PATCH 0/4] netfilter fixes for 3.11-rc4 Pablo Neira Ayuso
2013-08-10 16:58 ` [PATCH 1/4] netfilter: xt_TCPMSS: fix handling of malformed TCP header and options Pablo Neira Ayuso
2013-08-10 16:58 ` [PATCH 2/4] netfilter: xt_TCPOPTSTRIP: fix possible off by one access Pablo Neira Ayuso
2013-08-10 16:58 ` [PATCH 3/4] netfilter: nfnetlink_{log,queue}: fix information leaks in netlink message Pablo Neira Ayuso
2013-08-10 16:58 ` [PATCH 4/4] netfilter: nf_conntrack: fix tcp_in_window for Fast Open Pablo Neira Ayuso
2013-08-10 20:44 ` [PATCH 0/4] netfilter fixes for 3.11-rc4 David Miller

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).