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

Commit c2a1910b authored by Jorge Boncompte's avatar Jorge Boncompte Committed by David S. Miller
Browse files

[NETFILTER]: nf_nat_proto_gre: do not modify/corrupt GREv0 packets through NAT



While porting some changes of the 2.6.21-rc7 pptp/proto_gre conntrack
and nat modules to a 2.4.32 kernel I noticed that the gre_key function
returns a wrong pointer to the GRE key of a version 0 packet thus
corrupting the packet payload.

The intended behaviour for GREv0 packets is to act like
nf_conntrack_proto_generic/nf_nat_proto_unknown so I have ripped the
offending functions (not used anymore) and modified the
nf_nat_proto_gre modules to not touch version 0 (non PPTP) packets.

Signed-off-by: default avatarJorge Boncompte <jorge@dti2.net>
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 32785007
Loading
Loading
Loading
Loading
+0 −18
Original line number Original line Diff line number Diff line
@@ -87,24 +87,6 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
/* delete keymap entries */
/* delete keymap entries */
void nf_ct_gre_keymap_destroy(struct nf_conn *ct);
void nf_ct_gre_keymap_destroy(struct nf_conn *ct);


/* get pointer to gre key, if present */
static inline __be32 *gre_key(struct gre_hdr *greh)
{
	if (!greh->key)
		return NULL;
	if (greh->csum || greh->routing)
		return (__be32 *)(greh+sizeof(*greh)+4);
	return (__be32 *)(greh+sizeof(*greh));
}

/* get pointer ot gre csum, if present */
static inline __sum16 *gre_csum(struct gre_hdr *greh)
{
	if (!greh->csum)
		return NULL;
	return (__sum16 *)(greh+sizeof(*greh));
}

extern void nf_ct_gre_keymap_flush(void);
extern void nf_ct_gre_keymap_flush(void);
extern void nf_nat_need_gre(void);
extern void nf_nat_need_gre(void);


+8 −12
Original line number Original line Diff line number Diff line
@@ -72,6 +72,11 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple,
	__be16 *keyptr;
	__be16 *keyptr;
	unsigned int min, i, range_size;
	unsigned int min, i, range_size;


	/* If there is no master conntrack we are not PPTP,
	   do not change tuples */
	if (!conntrack->master)
		return 0;

	if (maniptype == IP_NAT_MANIP_SRC)
	if (maniptype == IP_NAT_MANIP_SRC)
		keyptr = &tuple->src.u.gre.key;
		keyptr = &tuple->src.u.gre.key;
	else
	else
@@ -122,18 +127,9 @@ gre_manip_pkt(struct sk_buff **pskb, unsigned int iphdroff,
	if (maniptype != IP_NAT_MANIP_DST)
	if (maniptype != IP_NAT_MANIP_DST)
		return 1;
		return 1;
	switch (greh->version) {
	switch (greh->version) {
	case 0:
	case GRE_VERSION_1701:
		if (!greh->key) {
		/* We do not currently NAT any GREv0 packets.
			DEBUGP("can't nat GRE w/o key\n");
		 * Try to behave like "nf_nat_proto_unknown" */
			break;
		}
		if (greh->csum) {
			/* FIXME: Never tested this code... */
			nf_proto_csum_replace4(gre_csum(greh), *pskb,
					       *(gre_key(greh)),
					       tuple->dst.u.gre.key, 0);
		}
		*(gre_key(greh)) = tuple->dst.u.gre.key;
		break;
		break;
	case GRE_VERSION_PPTP:
	case GRE_VERSION_PPTP:
		DEBUGP("call_id -> 0x%04x\n", ntohs(tuple->dst.u.gre.key));
		DEBUGP("call_id -> 0x%04x\n", ntohs(tuple->dst.u.gre.key));