Commit fb2eb1c1 authored by Florian Westphal's avatar Florian Westphal Committed by Pablo Neira Ayuso
Browse files

netfilter: tcpmss, optstrip: prefer skb_ensure_writable



This also changes optstrip to only make the tcp header writeable
rather than the entire packet.

Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 8e03707f
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -89,7 +89,7 @@ tcpmss_mangle_packet(struct sk_buff *skb,
	if (par->fragoff != 0)
	if (par->fragoff != 0)
		return 0;
		return 0;


	if (!skb_make_writable(skb, skb->len))
	if (skb_ensure_writable(skb, skb->len))
		return -1;
		return -1;


	len = skb->len - tcphoff;
	len = skb->len - tcphoff;
+13 −15
Original line number Original line Diff line number Diff line
@@ -31,33 +31,33 @@ static inline unsigned int optlen(const u_int8_t *opt, unsigned int offset)
static unsigned int
static unsigned int
tcpoptstrip_mangle_packet(struct sk_buff *skb,
tcpoptstrip_mangle_packet(struct sk_buff *skb,
			  const struct xt_action_param *par,
			  const struct xt_action_param *par,
			  unsigned int tcphoff, unsigned int minlen)
			  unsigned int tcphoff)
{
{
	const struct xt_tcpoptstrip_target_info *info = par->targinfo;
	const struct xt_tcpoptstrip_target_info *info = par->targinfo;
	struct tcphdr *tcph, _th;
	unsigned int optl, i, j;
	unsigned int optl, i, j;
	struct tcphdr *tcph;
	u_int16_t n, o;
	u_int16_t n, o;
	u_int8_t *opt;
	u_int8_t *opt;
	int len, tcp_hdrlen;
	int tcp_hdrlen;


	/* This is a fragment, no TCP header is available */
	/* This is a fragment, no TCP header is available */
	if (par->fragoff != 0)
	if (par->fragoff != 0)
		return XT_CONTINUE;
		return XT_CONTINUE;


	if (!skb_make_writable(skb, skb->len))
	tcph = skb_header_pointer(skb, tcphoff, sizeof(_th), &_th);
	if (!tcph)
		return NF_DROP;
		return NF_DROP;


	len = skb->len - tcphoff;
	if (len < (int)sizeof(struct tcphdr))
		return NF_DROP;

	tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff);
	tcp_hdrlen = tcph->doff * 4;
	tcp_hdrlen = tcph->doff * 4;
	if (tcp_hdrlen < sizeof(struct tcphdr))
		return NF_DROP;


	if (len < tcp_hdrlen)
	if (skb_ensure_writable(skb, tcphoff + tcp_hdrlen))
		return NF_DROP;
		return NF_DROP;


	opt  = (u_int8_t *)tcph;
	/* must reload tcph, might have been moved */
	tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff);
	opt  = (u8 *)tcph;


	/*
	/*
	 * Walk through all TCP options - if we find some option to remove,
	 * Walk through all TCP options - if we find some option to remove,
@@ -91,8 +91,7 @@ tcpoptstrip_mangle_packet(struct sk_buff *skb,
static unsigned int
static unsigned int
tcpoptstrip_tg4(struct sk_buff *skb, const struct xt_action_param *par)
tcpoptstrip_tg4(struct sk_buff *skb, const struct xt_action_param *par)
{
{
	return tcpoptstrip_mangle_packet(skb, par, ip_hdrlen(skb),
	return tcpoptstrip_mangle_packet(skb, par, ip_hdrlen(skb));
	       sizeof(struct iphdr) + sizeof(struct tcphdr));
}
}


#if IS_ENABLED(CONFIG_IP6_NF_MANGLE)
#if IS_ENABLED(CONFIG_IP6_NF_MANGLE)
@@ -109,8 +108,7 @@ tcpoptstrip_tg6(struct sk_buff *skb, const struct xt_action_param *par)
	if (tcphoff < 0)
	if (tcphoff < 0)
		return NF_DROP;
		return NF_DROP;


	return tcpoptstrip_mangle_packet(skb, par, tcphoff,
	return tcpoptstrip_mangle_packet(skb, par, tcphoff);
	       sizeof(*ipv6h) + sizeof(struct tcphdr));
}
}
#endif
#endif