Skip to contentSkip to conversation

NAT: Fix module refcount dropping too far

PATCH In review Chris Wright 3 participants 23 messages Nov 22, 2005 – Nov 23, 2005 1 message not in the archive

Subsystems (12)
lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

#1 lore raw

PATCH 5/23 VFS: Fix memory leak with file leases

-stable review patch. If anyone has any objections, please let us know.
------------------

The patch
http://linux.bkbits.net:8080/linux-2.6/diffs/fs/[email protected]??nav=index.html
introduced a pretty nasty memory leak in the lease code. When freeing the lease, the code in locks_delete_lock() will correctly clean up the fasync queue, but when we return to fcntl_setlease(), the freed fasync entry will be reinstated.

This patch ensures that we skip the call to fasync_helper() when we're freeing up the lease.

---
 fs/locks.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/locks.c +1 -1
@@ -1418,7 +1418,7 @@ int fcntl_setlease(unsigned int fd, stru
 	lock_kernel();
 
 	error = __setlease(filp, arg, &flp);
-	if (error)
+	if (error || arg == F_UNLCK)
 		goto out_unlock;
 
 	error = fasync_helper(fd, filp, 1, &flp->fl_fasync);

--

#2 lore raw

PATCH 6/23 Generic HDLC WAN drivers - disable netif_carrier_off()

In reply to a message not in the archive

-stable review patch. If anyone has any objections, please let us know.
------------------

As we are currently unable to fix the problem with carrier and protocol state signaling in net core I've to disable netif_carrier_off() calls used by WAN protocol drivers. The attached patch should make them working again.

The remaining netif_carrier_*() calls in hdlc_fr.c are fine as they don't touch the physical device.

---
 drivers/net/wan/hdlc_cisco.c   |    6 ++++++
 drivers/net/wan/hdlc_fr.c      |    4 ++++
 drivers/net/wan/hdlc_generic.c |    6 ++++++
 3 files changed, 16 insertions(+)
drivers/net/wan/hdlc_cisco.c +6 -0
@@ -192,7 +192,9 @@ static int cisco_rx(struct sk_buff *skb)
 					       "uptime %ud%uh%um%us)\n",
 					       dev->name, days, hrs,
 					       min, sec);
+#if 0
 					netif_carrier_on(dev);
+#endif
 					hdlc->state.cisco.up = 1;
 				}
 			}
@@ -225,7 +227,9 @@ static void cisco_timer(unsigned long ar
 		       hdlc->state.cisco.settings.timeout * HZ)) {
 		hdlc->state.cisco.up = 0;
 		printk(KERN_INFO "%s: Link down\n", dev->name);
+#if 0
 		netif_carrier_off(dev);
+#endif
 	}
 
 	cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ,
@@ -261,8 +265,10 @@ static void cisco_stop(struct net_device
 {
 	hdlc_device *hdlc = dev_to_hdlc(dev);
 	del_timer_sync(&hdlc->state.cisco.timer);
+#if 0
 	if (netif_carrier_ok(dev))
 		netif_carrier_off(dev);
+#endif
 	hdlc->state.cisco.up = 0;
 	hdlc->state.cisco.request_sent = 0;
 }
drivers/net/wan/hdlc_fr.c +4 -0
@@ -545,8 +545,10 @@ static void fr_set_link_state(int reliab
 
 	hdlc->state.fr.reliable = reliable;
 	if (reliable) {
+#if 0
 		if (!netif_carrier_ok(dev))
 			netif_carrier_on(dev);
+#endif
 
 		hdlc->state.fr.n391cnt = 0; /* Request full status */
 		hdlc->state.fr.dce_changed = 1;
@@ -560,8 +562,10 @@ static void fr_set_link_state(int reliab
 			}
 		}
 	} else {
+#if 0
 		if (netif_carrier_ok(dev))
 			netif_carrier_off(dev);
+#endif
 
 		while (pvc) {		/* Deactivate all PVCs */
 			pvc_carrier(0, pvc);
drivers/net/wan/hdlc_generic.c +6 -0
@@ -79,11 +79,13 @@ static void __hdlc_set_carrier_on(struct
 	hdlc_device *hdlc = dev_to_hdlc(dev);
 	if (hdlc->proto.start)
 		return hdlc->proto.start(dev);
+#if 0
 #ifdef DEBUG_LINK
 	if (netif_carrier_ok(dev))
 		printk(KERN_ERR "hdlc_set_carrier_on(): already on\n");
 #endif
 	netif_carrier_on(dev);
+#endif
 }
 
 
@@ -94,11 +96,13 @@ static void __hdlc_set_carrier_off(struc
 	if (hdlc->proto.stop)
 		return hdlc->proto.stop(dev);
 
+#if 0
 #ifdef DEBUG_LINK
 	if (!netif_carrier_ok(dev))
 		printk(KERN_ERR "hdlc_set_carrier_off(): already off\n");
 #endif
 	netif_carrier_off(dev);
+#endif
 }
 
 
@@ -294,8 +298,10 @@ int register_hdlc_device(struct net_devi
 	if (result != 0)
 		return -EIO;
 
+#if 0
 	if (netif_carrier_ok(dev))
 		netif_carrier_off(dev); /* no carrier until DCD goes up */
+#endif
 
 	return 0;
 }

--

#3 lore raw

PATCH 7/23 PPTP helper: Fix endianness bug in GRE key / CallID NAT

In reply to a message not in the archive

-stable review patch. If anyone has any objections, please let us know.
------------------

This endianness bug slipped through while changing the 'gre.key' field in the conntrack tuple from 32bit to 16bit.

None of my tests caught the problem, since the linux pptp client always has '0' as call id / gre key. Only windows clients actually trigger the bug.

---
 net/ipv4/netfilter/ip_nat_proto_gre.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
net/ipv4/netfilter/ip_nat_proto_gre.c +2 -2
@@ -139,8 +139,8 @@ gre_manip_pkt(struct sk_buff **pskb,
 			break;
 		case GRE_VERSION_PPTP:
 			DEBUGP("call_id -> 0x%04x\n", 
-				ntohl(tuple->dst.u.gre.key));
-			pgreh->call_id = htons(ntohl(tuple->dst.u.gre.key));
+				ntohs(tuple->dst.u.gre.key));
+			pgreh->call_id = tuple->dst.u.gre.key;
 			break;
 		default:
 			DEBUGP("can't nat unknown GRE version\n");

--

#4 lore raw

PATCH 8/23 NAT: Fix module refcount dropping too far

In reply to a message not in the archive

-stable review patch. If anyone has any objections, please let us know.
------------------

The unknown protocol is used as a fallback when a protocol isn't known. Hence we cannot handle it failing, so don't set ".me". It's OK, since we only grab a reference from within the same module (iptable_nat.ko), so we never take the module refcount from 0 to 1.

Also, remove the "protocol is NULL" test: it's never NULL.

---
 net/ipv4/netfilter/ip_nat_core.c          |    6 ++----
 net/ipv4/netfilter/ip_nat_proto_unknown.c |    2 +-
 2 files changed, 3 insertions(+), 5 deletions(-)
net/ipv4/netfilter/ip_nat_core.c +2 -4
@@ -66,10 +66,8 @@ ip_nat_proto_find_get(u_int8_t protonum)
 	 * removed until we've grabbed the reference */
 	preempt_disable();
 	p = __ip_nat_proto_find(protonum);
-	if (p) {
-		if (!try_module_get(p->me))
-			p = &ip_nat_unknown_protocol;
-	}
+	if (!try_module_get(p->me))
+		p = &ip_nat_unknown_protocol;
 	preempt_enable();
 
 	return p;
net/ipv4/netfilter/ip_nat_proto_unknown.c +1 -1
@@ -62,7 +62,7 @@ unknown_print_range(char *buffer, const 
 
 struct ip_nat_protocol ip_nat_unknown_protocol = {
 	.name			= "unknown",
-	.me			= THIS_MODULE,
+	/* .me isn't set: getting a ref to this cannot fail. */
 	.manip_pkt		= unknown_manip_pkt,
 	.in_range		= unknown_in_range,
 	.unique_tuple		= unknown_unique_tuple,

--

#5 lore raw

PATCH 9/23 nf_queue: Fix Ooops when no queue handler registered

In reply to a message not in the archive

-stable review patch. If anyone has any objections, please let us know.
------------------

With the new nf_queue generalization in 2.6.14, we've introduced a bug that causes an oops as soon as a packet is queued but no queue handler registered. This patch fixes it.

---
 net/netfilter/nf_queue.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/netfilter/nf_queue.c +1 -1
@@ -117,7 +117,7 @@ int nf_queue(struct sk_buff **skb, 
 
 	/* QUEUE == DROP if noone is waiting, to be safe. */
 	read_lock(&queue_handler_lock);
-	if (!queue_handler[pf]->outfn) {
+	if (!queue_handler[pf] || !queue_handler[pf]->outfn) {
 		read_unlock(&queue_handler_lock);
 		kfree_skb(*skb);
 		return 1;

--

#6 lore raw

PATCH 10/23 refcount leak of proto when ctnetlink dumping tuple

In reply to a message not in the archive

-stable review patch. If anyone has any objections, please let us know.
------------------

---
 net/ipv4/netfilter/ip_conntrack_netlink.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
net/ipv4/netfilter/ip_conntrack_netlink.c +6 -3
@@ -58,14 +58,17 @@ ctnetlink_dump_tuples_proto(struct sk_bu
 			    const struct ip_conntrack_tuple *tuple)
 {
 	struct ip_conntrack_protocol *proto;
+	int ret = 0;
 
 	NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum);
 
 	proto = ip_conntrack_proto_find_get(tuple->dst.protonum);
-	if (proto && proto->tuple_to_nfattr)
-		return proto->tuple_to_nfattr(skb, tuple);
+	if (likely(proto && proto->tuple_to_nfattr)) {
+		ret = proto->tuple_to_nfattr(skb, tuple);
+		ip_conntrack_proto_put(proto);
+	}
 
-	return 0;
+	return ret;
 
 nfattr_failure:
 	return -1;

--

#7 lore raw

PATCH 11/23 ctnetlink: check if protoinfo is present

In reply to a message not in the archive

-stable review patch. If anyone has any objections, please let us know.
------------------

This fixes an oops triggered from userspace. If we don't pass information about the private protocol info, the reference to attr will be NULL. This is likely to happen in update messages.

---
 net/ipv4/netfilter/ip_conntrack_proto_tcp.c |    5 +++++
 1 file changed, 5 insertions(+)
net/ipv4/netfilter/ip_conntrack_proto_tcp.c +5 -0
@@ -362,6 +362,11 @@ static int nfattr_to_tcp(struct nfattr *
 	struct nfattr *attr = cda[CTA_PROTOINFO_TCP-1];
 	struct nfattr *tb[CTA_PROTOINFO_TCP_MAX];
 
+	/* updates could not contain anything about the private
+	 * protocol info, in that case skip the parsing */
+	if (!attr)
+		return 0;
+
         if (nfattr_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr) < 0)
                 goto nfattr_failure;
 

--

#8 lore raw

PATCH 12/23 PPTP helper: fix PNS-PAC expectation call id

In reply to a message not in the archive

-stable review patch. If anyone has any objections, please let us know.
------------------

The reply tuple of the PNS->PAC expectation was using the wrong call id.

So we had the following situation:
- PNS behind NAT firewall
- PNS call id requires NATing
- PNS->PAC gre packet arrives first

then the PNS->PAC expectation is matched, and the other expectation is deleted, but the PAC->PNS gre packets do not match the gre conntrack because the call id is wrong.

We also cannot use ip_nat_follow_master().

---
 net/ipv4/netfilter/ip_nat_helper_pptp.c |   28 ++++++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)
net/ipv4/netfilter/ip_nat_helper_pptp.c +26 -2
@@ -73,6 +73,7 @@ static void pptp_nat_expected(struct ip_
 	struct ip_conntrack_tuple t;
 	struct ip_ct_pptp_master *ct_pptp_info;
 	struct ip_nat_pptp *nat_pptp_info;
+	struct ip_nat_range range;
 
 	ct_pptp_info = &master->help.ct_pptp_info;
 	nat_pptp_info = &master->nat.help.nat_pptp_info;
@@ -110,7 +111,30 @@ static void pptp_nat_expected(struct ip_
 		DEBUGP("not found!\n");
 	}
 
-	ip_nat_follow_master(ct, exp);
+	/* This must be a fresh one. */
+	BUG_ON(ct->status & IPS_NAT_DONE_MASK);
+
+	/* Change src to where master sends to */
+	range.flags = IP_NAT_RANGE_MAP_IPS;
+	range.min_ip = range.max_ip
+		= ct->master->tuplehash[!exp->dir].tuple.dst.ip;
+	if (exp->dir == IP_CT_DIR_ORIGINAL) {
+		range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
+		range.min = range.max = exp->saved_proto;
+	}
+	/* hook doesn't matter, but it has to do source manip */
+	ip_nat_setup_info(ct, &range, NF_IP_POST_ROUTING);
+
+	/* For DST manip, map port here to where it's expected. */
+	range.flags = IP_NAT_RANGE_MAP_IPS;
+	range.min_ip = range.max_ip
+		= ct->master->tuplehash[!exp->dir].tuple.src.ip;
+	if (exp->dir == IP_CT_DIR_REPLY) {
+		range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
+		range.min = range.max = exp->saved_proto;
+	}
+	/* hook doesn't matter, but it has to do destination manip */
+	ip_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING);
 }
 
 /* outbound packets == from PNS to PAC */
@@ -213,7 +237,7 @@ pptp_exp_gre(struct ip_conntrack_expect 
 
 	/* alter expectation for PNS->PAC direction */
 	invert_tuplepr(&inv_t, &expect_orig->tuple);
-	expect_orig->saved_proto.gre.key = htons(nat_pptp_info->pac_call_id);
+	expect_orig->saved_proto.gre.key = htons(ct_pptp_info->pns_call_id);
 	expect_orig->tuple.src.u.gre.key = htons(nat_pptp_info->pns_call_id);
 	expect_orig->tuple.dst.u.gre.key = htons(ct_pptp_info->pac_call_id);
 	inv_t.src.ip = reply_t->src.ip;

--

#9 lore raw

PATCH 13/23 ctnetlink: Fix oops when no ICMP ID info in message

In reply to a message not in the archive

-stable review patch. If anyone has any objections, please let us know.
------------------

This patch fixes an userspace triggered oops. If there is no ICMP_ID info the reference to attr will be NULL.

---
 net/ipv4/netfilter/ip_conntrack_proto_icmp.c |   13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)
net/ipv4/netfilter/ip_conntrack_proto_icmp.c +7 -6
@@ -151,13 +151,13 @@ icmp_error_message(struct sk_buff *skb,
 	/* Not enough header? */
 	inside = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_in), &_in);
 	if (inside == NULL)
-		return NF_ACCEPT;
+		return -NF_ACCEPT;
 
 	/* Ignore ICMP's containing fragments (shouldn't happen) */
 	if (inside->ip.frag_off & htons(IP_OFFSET)) {
 		DEBUGP("icmp_error_track: fragment of proto %u\n",
 		       inside->ip.protocol);
-		return NF_ACCEPT;
+		return -NF_ACCEPT;
 	}
 
 	innerproto = ip_conntrack_proto_find_get(inside->ip.protocol);
@@ -166,7 +166,7 @@ icmp_error_message(struct sk_buff *skb,
 	if (!ip_ct_get_tuple(&inside->ip, skb, dataoff, &origtuple, innerproto)) {
 		DEBUGP("icmp_error: ! get_tuple p=%u", inside->ip.protocol);
 		ip_conntrack_proto_put(innerproto);
-		return NF_ACCEPT;
+		return -NF_ACCEPT;
 	}
 
 	/* Ordinarily, we'd expect the inverted tupleproto, but it's
@@ -174,7 +174,7 @@ icmp_error_message(struct sk_buff *skb,
 	if (!ip_ct_invert_tuple(&innertuple, &origtuple, innerproto)) {
 		DEBUGP("icmp_error_track: Can't invert tuple\n");
 		ip_conntrack_proto_put(innerproto);
-		return NF_ACCEPT;
+		return -NF_ACCEPT;
 	}
 	ip_conntrack_proto_put(innerproto);
 
@@ -190,7 +190,7 @@ icmp_error_message(struct sk_buff *skb,
 
 		if (!h) {
 			DEBUGP("icmp_error_track: no match\n");
-			return NF_ACCEPT;
+			return -NF_ACCEPT;
 		}
 		/* Reverse direction from that found */
 		if (DIRECTION(h) != IP_CT_DIR_REPLY)
@@ -296,7 +296,8 @@ static int icmp_nfattr_to_tuple(struct n
 				struct ip_conntrack_tuple *tuple)
 {
 	if (!tb[CTA_PROTO_ICMP_TYPE-1]
-	    || !tb[CTA_PROTO_ICMP_CODE-1])
+	    || !tb[CTA_PROTO_ICMP_CODE-1]
+	    || !tb[CTA_PROTO_ICMP_ID-1])
 		return -1;
 
 	tuple->dst.u.icmp.type = 

--

#10 lore raw

Re: [patch 13/23] [PATCH] [NETFILTER] ctnetlink: Fix oops when no ICMP ID info in message

Quoted 1 line · Chris Wright

-stable review patch. If anyone has any objections, please let us know.

It seems we have two different patches here.

Quoted 5 lines

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

This patch fixes an userspace triggered oops. If there is no ICMP_ID info the reference to attr will be NULL.

Quoted 8 lines

---
net/ipv4/netfilter/ip_conntrack_proto_icmp.c | 13 +++++++------

1 file changed, 7 insertions(+), 6 deletions(-)

First - "stop tracking ICMP(v6) error at early point" by Yasuyuki Kozakai:

Quoted 37 lines
net/ipv4/netfilter/ip_conntrack_proto_icmp.c +4 -4
@@ -151,13 +151,13 @@ icmp_error_message(struct sk_buff *skb,
 	/* Not enough header? */
 	inside = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_in), &_in);
 	if (inside == NULL)
-		return NF_ACCEPT;
+		return -NF_ACCEPT;
 
 	/* Ignore ICMP's containing fragments (shouldn't happen) */
 	if (inside->ip.frag_off & htons(IP_OFFSET)) {
 		DEBUGP("icmp_error_track: fragment of proto %u\n",
 		       inside->ip.protocol);
-		return NF_ACCEPT;
+		return -NF_ACCEPT;
 	}
 
 	innerproto = ip_conntrack_proto_find_get(inside->ip.protocol);
@@ -166,7 +166,7 @@ icmp_error_message(struct sk_buff *skb,
 	if (!ip_ct_get_tuple(&inside->ip, skb, dataoff, &origtuple, innerproto)) {
 		DEBUGP("icmp_error: ! get_tuple p=%u", inside->ip.protocol);
 		ip_conntrack_proto_put(innerproto);
-		return NF_ACCEPT;
+		return -NF_ACCEPT;
 	}
 
 	/* Ordinarily, we'd expect the inverted tupleproto, but it's
@@ -174,7 +174,7 @@ icmp_error_message(struct sk_buff *skb,
 	if (!ip_ct_invert_tuple(&innertuple, &origtuple, innerproto)) {
 		DEBUGP("icmp_error_track: Can't invert tuple\n");
 		ip_conntrack_proto_put(innerproto);
-		return NF_ACCEPT;
+		return -NF_ACCEPT;
 	}
 	ip_conntrack_proto_put(innerproto);
 

net/ipv4/netfilter/ip_conntrack_proto_icmp.c icmp_error_message(struct sk_buff *skb, · line 196

Quoted 8 lines
net/ipv4/netfilter/ip_conntrack_proto_icmp.c +1 -1
@@ -190,7 +190,7 @@ icmp_error_message(struct sk_buff *skb,
 
 		if (!h) {
 			DEBUGP("icmp_error_track: no match\n");
-			return NF_ACCEPT;
+			return -NF_ACCEPT;
 		}
 		/* Reverse direction from that found */
 		if (DIRECTION(h) != IP_CT_DIR_REPLY)

Second - "Fix oops when no ICMP ID info in message":

net/ipv4/netfilter/ip_conntrack_proto_icmp.c static int icmp_nfattr_to_tuple(struct n · line 303

Quoted 11 lines
net/ipv4/netfilter/ip_conntrack_proto_icmp.c +2 -1
@@ -296,7 +296,8 @@ static int icmp_nfattr_to_tuple(struct n
 				struct ip_conntrack_tuple *tuple)
 {
 	if (!tb[CTA_PROTO_ICMP_TYPE-1]
-	    || !tb[CTA_PROTO_ICMP_CODE-1])
+	    || !tb[CTA_PROTO_ICMP_CODE-1]
+	    || !tb[CTA_PROTO_ICMP_ID-1])
 		return -1;
 
 	tuple->dst.u.icmp.type =

Best regards,

Krzysztof Olędzki

#11 lore raw

Re: [patch 13/23] [PATCH] [NETFILTER] ctnetlink: Fix oops when no ICMP ID info in message

Quoted 5 lines · * Krzysztof Oledzki ([email protected]) wrote:
Quoted 1 line · Chris Wright

-stable review patch. If anyone has any objections, please let us know.

It seems we have two different patches here.

Thanks, you are right. Harald, was that intentional?

thanks,
-chris

#12 lore raw

Re: [patch 13/23] [PATCH] [NETFILTER] ctnetlink: Fix oops when no ICMP ID info in message

In reply to Krzysztof Oledzki
Quoted 5 lines · Krzysztof Oledzki
Quoted 1 line · Chris Wright

-stable review patch. If anyone has any objections, please let us know.

It seems we have two different patches here.

yes, it seems like two independent patches slipped into the one patch that was submitted. I detected that error for mainline, but forgot that the same patch was submitted for stable.

So the first part (as pointed out by Krzyzstof) is not a bugfix, but a cosmetic fix.

I therefore request reverting this patch '13', and instead applying the version below, the one that contains only the real fix (as indicated in the changelog)

Sorry once again.

[NETFILTER] ctnetlink: Fix oops when no ICMP ID info in message

This patch fixes an userspace triggered oops. If there is no ICMP_ID info the reference to attr will be NULL.

---
commit 922474105255d7791128688c8e60bb27a8eadf1d
tree b072448bfe0b79058b03ed798a1145ad1a7c6397
parent 723cb15b48e5510094296a9fc240d69a3acae95c
author Krzysztof Piotr Oledzki <[email protected]> Tue, 15 Nov 2005 12:16:43 +0100 committer Harald Welte <[email protected]> Tue, 15 Nov 2005 12:16:43 +0100

 net/ipv4/netfilter/ip_conntrack_proto_icmp.c |   13 +++++++------
 1 files changed, 7 insertions(+), 6 deletions(-)
net/ipv4/netfilter/ip_conntrack_proto_icmp.c +2 -1
@@ -296,7 +296,8 @@ static int icmp_nfattr_to_tuple(struct n
 				struct ip_conntrack_tuple *tuple)
 {
 	if (!tb[CTA_PROTO_ICMP_TYPE-1]
-	    || !tb[CTA_PROTO_ICMP_CODE-1])
+	    || !tb[CTA_PROTO_ICMP_CODE-1]
+	    || !tb[CTA_PROTO_ICMP_ID-1])
 		return -1;
 
 	tuple->dst.u.icmp.type = 
Signature · 5 lines
- Harald Welte <[email protected]>                 http://netfilter.org/
============================================================================
  "Fragmentation is like classful addressing -- an interesting early
   architectural error that shows how much experimentation was going
   on while IP was being designed."                    -- Paul Vixie
#13 lore raw

Re: [patch 13/23] [PATCH] [NETFILTER] ctnetlink: Fix oops when no ICMP ID info in message

Quoted 11 lines · * Harald Welte ([email protected]) wrote:
Quoted 5 lines · Krzysztof Oledzki
Quoted 1 line · Chris Wright

-stable review patch. If anyone has any objections, please let us know.

It seems we have two different patches here.

yes, it seems like two independent patches slipped into the one patch that was submitted. I detected that error for mainline, but forgot that the same patch was submitted for stable.

Quoted 6 lines

So the first part (as pointed out by Krzyzstof) is not a bugfix, but a cosmetic fix.

I therefore request reverting this patch '13', and instead applying the version below, the one that contains only the real fix (as indicated in the changelog)

Thanks Harald, I dropped the old patch and replaced with this one.

thanks,
-chris

#14 lore raw

PATCH 14/23 ip_conntrack TCP: Accept SYN+PUSH like SYN

In reply to a message not in the archive

-stable review patch. If anyone has any objections, please let us know.
------------------

Some devices (e.g. Qlogic iSCSI HBA hardware like QLA4010 up to firmware 3.0.0.4) initiates TCP with SYN and PUSH flags set.

The Linux TCP/IP stack deals fine with that, but the connection tracking code doesn't.

This patch alters TCP connection tracking to accept SYN+PUSH as a valid flag combination.

---
 net/ipv4/netfilter/ip_conntrack_proto_tcp.c |    1 +
 1 file changed, 1 insertion(+)
net/ipv4/netfilter/ip_conntrack_proto_tcp.c +1 -0
@@ -818,6 +818,7 @@ static u8 tcp_valid_flags[(TH_FIN|TH_SYN
 {
 	[TH_SYN]			= 1,
 	[TH_SYN|TH_ACK]			= 1,
+	[TH_SYN|TH_PUSH]		= 1,
 	[TH_SYN|TH_ACK|TH_PUSH]		= 1,
 	[TH_RST]			= 1,
 	[TH_RST|TH_ACK]			= 1,

--

#15 lore raw

PATCH 15/23 ip_conntrack: fix ftp/irc/tftp helpers on ports >= 32768

In reply to a message not in the archive

-stable review patch. If anyone has any objections, please let us know.
------------------

Since we've converted the ftp/irc/tftp helpers to use the new module_parm_array() some time ago, we ware accidentially using signed data types - thus preventing those modules from being used on ports >= 32768.

This patch fixes it by using 'ushort' module parameters.

Thanks to Jan Nijs for reporting this bug.

---
 net/ipv4/netfilter/ip_conntrack_ftp.c  |    4 ++--
 net/ipv4/netfilter/ip_conntrack_irc.c  |    4 ++--
 net/ipv4/netfilter/ip_conntrack_tftp.c |    4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)
net/ipv4/netfilter/ip_conntrack_ftp.c +2 -2
@@ -29,9 +29,9 @@ static char *ftp_buffer;
 static DEFINE_SPINLOCK(ip_ftp_lock);
 
 #define MAX_PORTS 8
-static short ports[MAX_PORTS];
+static unsigned short ports[MAX_PORTS];
 static int ports_c;
-module_param_array(ports, short, &ports_c, 0400);
+module_param_array(ports, ushort, &ports_c, 0400);
 
 static int loose;
 module_param(loose, int, 0600);
net/ipv4/netfilter/ip_conntrack_irc.c +2 -2
@@ -34,7 +34,7 @@
 #include <linux/moduleparam.h>
 
 #define MAX_PORTS 8
-static short ports[MAX_PORTS];
+static unsigned short ports[MAX_PORTS];
 static int ports_c;
 static int max_dcc_channels = 8;
 static unsigned int dcc_timeout = 300;
@@ -52,7 +52,7 @@ EXPORT_SYMBOL_GPL(ip_nat_irc_hook);
 MODULE_AUTHOR("Harald Welte <[email protected]>");
 MODULE_DESCRIPTION("IRC (DCC) connection tracking helper");
 MODULE_LICENSE("GPL");
-module_param_array(ports, short, &ports_c, 0400);
+module_param_array(ports, ushort, &ports_c, 0400);
 MODULE_PARM_DESC(ports, "port numbers of IRC servers");
 module_param(max_dcc_channels, int, 0400);
 MODULE_PARM_DESC(max_dcc_channels, "max number of expected DCC channels per IRC session");
net/ipv4/netfilter/ip_conntrack_tftp.c +2 -2
@@ -26,9 +26,9 @@ MODULE_DESCRIPTION("tftp connection trac
 MODULE_LICENSE("GPL");
 
 #define MAX_PORTS 8
-static short ports[MAX_PORTS];
+static unsigned short ports[MAX_PORTS];
 static int ports_c;
-module_param_array(ports, short, &ports_c, 0400);
+module_param_array(ports, ushort, &ports_c, 0400);
 MODULE_PARM_DESC(ports, "port numbers of tftp servers");
 
 #if 0

--

#16 lore raw

PATCH 16/23 : Fix memory management error during setting up new advapi sockopts.

In reply to a message not in the archive

-stable review patch. If anyone has any objections, please let us know.
------------------

---
 net/ipv6/exthdrs.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
net/ipv6/exthdrs.c +2 -1
@@ -628,6 +628,7 @@ ipv6_renew_options(struct sock *sk, stru
 	if (!tot_len)
 		return NULL;
 
+	tot_len += sizeof(*opt2);
 	opt2 = sock_kmalloc(sk, tot_len, GFP_ATOMIC);
 	if (!opt2)
 		return ERR_PTR(-ENOBUFS);
@@ -668,7 +669,7 @@ ipv6_renew_options(struct sock *sk, stru
 
 	return opt2;
 out:
-	sock_kfree_s(sk, p, tot_len);
+	sock_kfree_s(sk, opt2, opt2->tot_len);
 	return ERR_PTR(err);
 }
 

--

#17 lore raw

PATCH 17/23 : Fix calculation of AH length during filling ancillary data.

In reply to a message not in the archive

-stable review patch. If anyone has any objections, please let us know.
------------------

---
 net/ipv6/datagram.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv6/datagram.c +1 -1
@@ -437,7 +437,7 @@ int datagram_recv_ctl(struct sock *sk, s
 				break;
 			case IPPROTO_AH:
 				nexthdr = ptr[0];
-				len = (ptr[1] + 1) << 2;
+				len = (ptr[1] + 2) << 2;
 				break;
 			default:
 				nexthdr = ptr[0];

--

#18 lore raw

PATCH 18/23 : Fix sending extension headers before and including routing header.

In reply to a message not in the archive

-stable review patch. If anyone has any objections, please let us know.
------------------

Based on suggestion from Masahide Nakamura <[email protected]>.

---
 include/net/ipv6.h       |    2 ++
 net/ipv6/exthdrs.c       |   19 +++++++++++++++++++
 net/ipv6/ip6_flowlabel.c |   16 ++++++----------
 net/ipv6/raw.c           |    4 +++-
 net/ipv6/udp.c           |    4 +++-
 5 files changed, 33 insertions(+), 12 deletions(-)
include/net/ipv6.h +2 -0
@@ -237,6 +237,8 @@ extern struct ipv6_txoptions *	ipv6_rene
 						   int newtype,
 						   struct ipv6_opt_hdr __user *newopt,
 						   int newoptlen);
+struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space,
+					  struct ipv6_txoptions *opt);
 
 extern int ip6_frag_nqueues;
 extern atomic_t ip6_frag_mem;
net/ipv6/exthdrs.c +19 -0
@@ -673,3 +673,22 @@ out:
 	return ERR_PTR(err);
 }
 
+struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space,
+					  struct ipv6_txoptions *opt)
+{
+	/*
+	 * ignore the dest before srcrt unless srcrt is being included.
+	 * --yoshfuji
+	 */
+	if (opt && opt->dst0opt && !opt->srcrt) {
+		if (opt_space != opt) {
+			memcpy(opt_space, opt, sizeof(*opt_space));
+			opt = opt_space;
+		}
+		opt->opt_nflen -= ipv6_optlen(opt->dst0opt);
+		opt->dst0opt = NULL;
+	}
+
+	return opt;
+}
+
net/ipv6/ip6_flowlabel.c +6 -10
@@ -225,20 +225,16 @@ struct ipv6_txoptions *fl6_merge_options
 					 struct ip6_flowlabel * fl,
 					 struct ipv6_txoptions * fopt)
 {
-	struct ipv6_txoptions * fl_opt = fl ? fl->opt : NULL;
-
-	if (fopt == NULL || fopt->opt_flen == 0) {
-		if (!fl_opt || !fl_opt->dst0opt || fl_opt->srcrt)
-			return fl_opt;
-	}
-
+	struct ipv6_txoptions * fl_opt = fl->opt;
+
+	if (fopt == NULL || fopt->opt_flen == 0)
+		return fl_opt;
+
 	if (fl_opt != NULL) {
 		opt_space->hopopt = fl_opt->hopopt;
-		opt_space->dst0opt = fl_opt->srcrt ? fl_opt->dst0opt : NULL;
+		opt_space->dst0opt = fl_opt->dst0opt;
 		opt_space->srcrt = fl_opt->srcrt;
 		opt_space->opt_nflen = fl_opt->opt_nflen;
-		if (fl_opt->dst0opt && !fl_opt->srcrt)
-			opt_space->opt_nflen -= ipv6_optlen(fl_opt->dst0opt);
 	} else {
 		if (fopt->opt_nflen == 0)
 			return fopt;
net/ipv6/raw.c +3 -1
@@ -756,7 +756,9 @@ static int rawv6_sendmsg(struct kiocb *i
 	}
 	if (opt == NULL)
 		opt = np->opt;
-	opt = fl6_merge_options(&opt_space, flowlabel, opt);
+	if (flowlabel)
+		opt = fl6_merge_options(&opt_space, flowlabel, opt);
+	opt = ipv6_fixup_options(&opt_space, opt);
 
 	fl.proto = proto;
 	rawv6_probe_proto_opt(&fl, msg);
net/ipv6/udp.c +3 -1
@@ -778,7 +778,9 @@ do_udp_sendmsg:
 	}
 	if (opt == NULL)
 		opt = np->opt;
-	opt = fl6_merge_options(&opt_space, flowlabel, opt);
+	if (flowlabel)
+		opt = fl6_merge_options(&opt_space, flowlabel, opt);
+	opt = ipv6_fixup_options(&opt_space, opt);
 
 	fl->proto = IPPROTO_UDP;
 	ipv6_addr_copy(&fl->fl6_dst, daddr);

--

#19 lore raw

PATCH 19/23 x86_64/i386: Compute correct MTRR mask on early Noconas

In reply to a message not in the archive

-stable review patch. If anyone has any objections, please let us know.
------------------

Force correct address space size for MTRR on some 64bit Intel Xeons

They report 40bit, but only have 36bits of physical address space. This caused problems with setting up the correct masks for MTRR, resulting in incorrect MTRRs.

CPUID workaround for steppings 0F33h(supporting x86) and 0F34h(supporting x86 and EM64T). Detail info can be found at:
http://download.intel.com/design/Xeon/specupdt/30240216.pdf
http://download.intel.com/design/Pentium4/specupdt/30235221.pdf

---
 arch/i386/kernel/cpu/mtrr/main.c |    8 ++++++++
 arch/x86_64/kernel/setup.c       |    5 +++++
 2 files changed, 13 insertions(+)
arch/i386/kernel/cpu/mtrr/main.c +8 -0
@@ -626,6 +626,14 @@ void __init mtrr_bp_init(void)
 		if (cpuid_eax(0x80000000) >= 0x80000008) {
 			u32 phys_addr;
 			phys_addr = cpuid_eax(0x80000008) & 0xff;
+			/* CPUID workaround for Intel 0F33/0F34 CPU */
+			if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
+			    boot_cpu_data.x86 == 0xF &&
+			    boot_cpu_data.x86_model == 0x3 &&
+			    (boot_cpu_data.x86_mask == 0x3 ||
+			     boot_cpu_data.x86_mask == 0x4))
+				phys_addr = 36;
+
 			size_or_mask = ~((1 << (phys_addr - PAGE_SHIFT)) - 1);
 			size_and_mask = ~size_or_mask & 0xfff00000;
 		} else if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR &&
arch/x86_64/kernel/setup.c +5 -0
@@ -993,6 +993,11 @@ static void __cpuinit init_intel(struct 
 		unsigned eax = cpuid_eax(0x80000008);
 		c->x86_virt_bits = (eax >> 8) & 0xff;
 		c->x86_phys_bits = eax & 0xff;
+		/* CPUID workaround for Intel 0F34 CPU */
+		if (c->x86_vendor == X86_VENDOR_INTEL &&
+		    c->x86 == 0xF && c->x86_model == 0x3 &&
+		    c->x86_mask == 0x4)
+			c->x86_phys_bits = 36;
 	}
 
 	if (c->x86 == 15)

--

#20 lore raw

PATCH 20/23 drivers/isdn/hardware/eicon/os_4bri.c: correct the xdiLoadFile() signature

In reply to a message not in the archive

-stable review patch. If anyone has any objections, please let us know.
------------------

It's not good if caller and callee disagree regarding the type of the arguments.

In this case, this could cause problems on 64bit architectures.

---
 drivers/isdn/hardware/eicon/os_4bri.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/isdn/hardware/eicon/os_4bri.c +2 -1
@@ -16,6 +16,7 @@
 #include "diva_pci.h"
 #include "mi_pc.h"
 #include "dsrv4bri.h"
+#include "helpers.h"
 
 static void *diva_xdiLoadFileFile = NULL;
 static dword diva_xdiLoadFileLength = 0;
@@ -815,7 +816,7 @@ diva_4bri_cmd_card_proc(struct _diva_os_
 	return (ret);
 }
 
-void *xdiLoadFile(char *FileName, unsigned long *FileLength,
+void *xdiLoadFile(char *FileName, dword *FileLength,
 		  unsigned long lim)
 {
 	void *ret = diva_xdiLoadFileFile;

--

#21 lore raw

PATCH 21/23 hwmon: Fix missing boundary check when setting W83627THF in0 limits

In reply to a message not in the archive

-stable review patch. If anyone has any objections, please let us know.
------------------

Add SENSORS_LIMIT in store VCore limit functions. This fixes a potential u8 overflow on out-of-range user input.

---
 drivers/hwmon/w83627hf.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/hwmon/w83627hf.c +6 -2
@@ -454,7 +454,9 @@ static ssize_t store_regs_in_min0(struct
 		(w83627thf == data->type || w83637hf == data->type))
 
 		/* use VRM9 calculation */
-		data->in_min[0] = (u8)(((val * 100) - 70000 + 244) / 488);
+		data->in_min[0] =
+			SENSORS_LIMIT(((val * 100) - 70000 + 244) / 488, 0,
+					255);
 	else
 		/* use VRM8 (standard) calculation */
 		data->in_min[0] = IN_TO_REG(val);
@@ -479,7 +481,9 @@ static ssize_t store_regs_in_max0(struct
 		(w83627thf == data->type || w83637hf == data->type))
 		
 		/* use VRM9 calculation */
-		data->in_max[0] = (u8)(((val * 100) - 70000 + 244) / 488);
+		data->in_max[0] =
+			SENSORS_LIMIT(((val * 100) - 70000 + 244) / 488, 0,
+					255);
 	else
 		/* use VRM8 (standard) calculation */
 		data->in_max[0] = IN_TO_REG(val);

--

#22 lore raw

PATCH 22/23 hwmon: Fix lm78 VID conversion

In reply to a message not in the archive

-stable review patch. If anyone has any objections, please let us know.
------------------

Fix the lm78 VID reading, which I accidentally broke while making this driver use the common vid_from_reg function rather than reimplementing its own in 2.6.14-rc1.

I'm not proud of it, trust me.

---
 drivers/hwmon/lm78.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwmon/lm78.c +1 -1
@@ -451,7 +451,7 @@ static DEVICE_ATTR(fan3_div, S_IRUGO, sh
 static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct lm78_data *data = lm78_update_device(dev);
-	return sprintf(buf, "%d\n", vid_from_reg(82, data->vid));
+	return sprintf(buf, "%d\n", vid_from_reg(data->vid, 82));
 }
 static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
 

--

#23 lore raw

PATCH 23/23 hwmon: Fix missing it87 fan div init

In reply to a message not in the archive

-stable review patch. If anyone has any objections, please let us know.
------------------

Fix a bug where setting the low fan speed limits will not work if no data was ever read through the sysfs interface and the fan clock dividers have not been explicitely set yet either. The reason is that data->fan_div[nr] may currently be used before it is initialized from the chip register values. The fix is to explicitely initialize data->fan_div[nr] before using it.

Bug reported, and fix tested, by Nicolas Mailhot.

---
 drivers/hwmon/it87.c |    7 +++++++
 1 file changed, 7 insertions(+)
drivers/hwmon/it87.c +7 -0
@@ -522,8 +522,15 @@ static ssize_t set_fan_min(struct device
 	struct i2c_client *client = to_i2c_client(dev);
 	struct it87_data *data = i2c_get_clientdata(client);
 	int val = simple_strtol(buf, NULL, 10);
+	u8 reg = it87_read_value(client, IT87_REG_FAN_DIV);
 
 	down(&data->update_lock);
+	switch (nr) {
+	case 0: data->fan_div[nr] = reg & 0x07; break;
+	case 1: data->fan_div[nr] = (reg >> 3) & 0x07; break;
+	case 2: data->fan_div[nr] = (reg & 0x40) ? 3 : 1; break;
+	}
+
 	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
 	it87_write_value(client, IT87_REG_FAN_MIN(nr), data->fan_min[nr]);
 	up(&data->update_lock);

--