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

Commit 4c5de695 authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller
Browse files

[NETFILTER]: PPTP conntrack: fix another GRE keymap leak



When the master PPTP connection times out while still having unfullfilled
expectations (and a GRE keymap entry) associated with it, the keymap entry
is not destroyed.

Add a destroy callback to struct ip_conntrack_helper and use it to destroy
PPTP siblings when the master is destroyed.

Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent fd5e3bef
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -25,6 +25,8 @@ struct ip_conntrack_helper
		    struct ip_conntrack *ct,
		    struct ip_conntrack *ct,
		    enum ip_conntrack_info conntrackinfo);
		    enum ip_conntrack_info conntrackinfo);


	void (*destroy)(struct ip_conntrack *ct);

	int (*to_nfattr)(struct sk_buff *skb, const struct ip_conntrack *ct);
	int (*to_nfattr)(struct sk_buff *skb, const struct ip_conntrack *ct);
};
};


+5 −0
Original line number Original line Diff line number Diff line
@@ -307,6 +307,7 @@ destroy_conntrack(struct nf_conntrack *nfct)
{
{
	struct ip_conntrack *ct = (struct ip_conntrack *)nfct;
	struct ip_conntrack *ct = (struct ip_conntrack *)nfct;
	struct ip_conntrack_protocol *proto;
	struct ip_conntrack_protocol *proto;
	struct ip_conntrack_helper *helper;


	DEBUGP("destroy_conntrack(%p)\n", ct);
	DEBUGP("destroy_conntrack(%p)\n", ct);
	IP_NF_ASSERT(atomic_read(&nfct->use) == 0);
	IP_NF_ASSERT(atomic_read(&nfct->use) == 0);
@@ -315,6 +316,10 @@ destroy_conntrack(struct nf_conntrack *nfct)
	ip_conntrack_event(IPCT_DESTROY, ct);
	ip_conntrack_event(IPCT_DESTROY, ct);
	set_bit(IPS_DYING_BIT, &ct->status);
	set_bit(IPS_DYING_BIT, &ct->status);


	helper = ct->helper;
	if (helper && helper->destroy)
		helper->destroy(ct);

	/* To make sure we don't get any weird locking issues here:
	/* To make sure we don't get any weird locking issues here:
	 * destroy_conntrack() MUST NOT be called with a write lock
	 * destroy_conntrack() MUST NOT be called with a write lock
	 * to ip_conntrack_lock!!! -HW */
	 * to ip_conntrack_lock!!! -HW */
+2 −10
Original line number Original line Diff line number Diff line
@@ -553,15 +553,6 @@ conntrack_pptp_help(struct sk_buff **pskb,
	nexthdr_off += tcph->doff * 4;
	nexthdr_off += tcph->doff * 4;
 	datalen = tcplen - tcph->doff * 4;
 	datalen = tcplen - tcph->doff * 4;


	if (tcph->fin || tcph->rst) {
		DEBUGP("RST/FIN received, timeouting GRE\n");
		/* can't do this after real newnat */
		info->cstate = PPTP_CALL_NONE;

		/* untrack this call id, unexpect GRE packets */
		pptp_destroy_siblings(ct);
	}

	pptph = skb_header_pointer(*pskb, nexthdr_off, sizeof(_pptph), &_pptph);
	pptph = skb_header_pointer(*pskb, nexthdr_off, sizeof(_pptph), &_pptph);
	if (!pptph) {
	if (!pptph) {
		DEBUGP("no full PPTP header, can't track\n");
		DEBUGP("no full PPTP header, can't track\n");
@@ -640,7 +631,8 @@ static struct ip_conntrack_helper pptp = {
			   .protonum = 0xff
			   .protonum = 0xff
		 	 }
		 	 }
		},
		},
	.help = conntrack_pptp_help
	.help = conntrack_pptp_help,
	.destroy = pptp_destroy_siblings,
};
};


extern void ip_ct_proto_gre_fini(void);
extern void ip_ct_proto_gre_fini(void);