Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2bad35b7 authored by Jorge Boncompte [DTI2]'s avatar Jorge Boncompte [DTI2] Committed by David S. Miller
Browse files

netns: oops in ip[6]_frag_reasm incrementing stats



dev can be NULL in ip[6]_frag_reasm for skb's coming from RAW sockets.

Quagga's OSPFD sends fragmented packets on a RAW socket, when netfilter
conntrack reassembles them on the OUTPUT path you hit this code path.

You can test it with something like "hping2 -0 -d 2000 -f AA.BB.CC.DD"

With help from Jarek Poplawski.

Signed-off-by: default avatarJorge Boncompte [DTI2] <jorge@dti2.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e4a389a9
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -463,6 +463,7 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
			 struct net_device *dev)
{
	struct net *net = container_of(qp->q.net, struct net, ipv4.frags);
	struct iphdr *iph;
	struct sk_buff *fp, *head = qp->q.fragments;
	int len;
@@ -548,7 +549,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
	iph = ip_hdr(head);
	iph->frag_off = 0;
	iph->tot_len = htons(len);
	IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_REASMOKS);
	IP_INC_STATS_BH(net, IPSTATS_MIB_REASMOKS);
	qp->q.fragments = NULL;
	return 0;

+3 −4
Original line number Diff line number Diff line
@@ -452,6 +452,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
			  struct net_device *dev)
{
	struct net *net = container_of(fq->q.net, struct net, ipv6.frags);
	struct sk_buff *fp, *head = fq->q.fragments;
	int    payload_len;
	unsigned int nhoff;
@@ -551,8 +552,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
					  head->csum);

	rcu_read_lock();
	IP6_INC_STATS_BH(dev_net(dev),
			 __in6_dev_get(dev), IPSTATS_MIB_REASMOKS);
	IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMOKS);
	rcu_read_unlock();
	fq->q.fragments = NULL;
	return 1;
@@ -566,8 +566,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
		printk(KERN_DEBUG "ip6_frag_reasm: no memory for reassembly\n");
out_fail:
	rcu_read_lock();
	IP6_INC_STATS_BH(dev_net(dev),
			 __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS);
	IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS);
	rcu_read_unlock();
	return -1;
}