Commit 2d89c68a authored by Patrick McHardy's avatar Patrick McHardy Committed by Pablo Neira Ayuso

netfilter: nf_nat: change sequence number adjustments to 32 bits

Using 16 bits is too small, when many adjustments happen the offsets might
overflow and break the connection.
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 0658cdc8
...@@ -330,7 +330,7 @@ extern struct nfq_ct_hook __rcu *nfq_ct_hook; ...@@ -330,7 +330,7 @@ extern struct nfq_ct_hook __rcu *nfq_ct_hook;
struct nfq_ct_nat_hook { struct nfq_ct_nat_hook {
void (*seq_adjust)(struct sk_buff *skb, struct nf_conn *ct, void (*seq_adjust)(struct sk_buff *skb, struct nf_conn *ct,
u32 ctinfo, int off); u32 ctinfo, s32 off);
}; };
extern struct nfq_ct_nat_hook __rcu *nfq_ct_nat_hook; extern struct nfq_ct_nat_hook __rcu *nfq_ct_nat_hook;
#else #else
......
...@@ -234,7 +234,7 @@ static inline bool nf_ct_kill(struct nf_conn *ct) ...@@ -234,7 +234,7 @@ static inline bool nf_ct_kill(struct nf_conn *ct)
} }
/* These are for NAT. Icky. */ /* These are for NAT. Icky. */
extern s16 (*nf_ct_nat_offset)(const struct nf_conn *ct, extern s32 (*nf_ct_nat_offset)(const struct nf_conn *ct,
enum ip_conntrack_dir dir, enum ip_conntrack_dir dir,
u32 seq); u32 seq);
......
...@@ -19,7 +19,7 @@ struct nf_nat_seq { ...@@ -19,7 +19,7 @@ struct nf_nat_seq {
u_int32_t correction_pos; u_int32_t correction_pos;
/* sequence number offset before and after last modification */ /* sequence number offset before and after last modification */
int16_t offset_before, offset_after; int32_t offset_before, offset_after;
}; };
#include <linux/list.h> #include <linux/list.h>
......
...@@ -41,7 +41,7 @@ extern int nf_nat_mangle_udp_packet(struct sk_buff *skb, ...@@ -41,7 +41,7 @@ extern int nf_nat_mangle_udp_packet(struct sk_buff *skb,
extern void nf_nat_set_seq_adjust(struct nf_conn *ct, extern void nf_nat_set_seq_adjust(struct nf_conn *ct,
enum ip_conntrack_info ctinfo, enum ip_conntrack_info ctinfo,
__be32 seq, s16 off); __be32 seq, s32 off);
extern int nf_nat_seq_adjust(struct sk_buff *skb, extern int nf_nat_seq_adjust(struct sk_buff *skb,
struct nf_conn *ct, struct nf_conn *ct,
enum ip_conntrack_info ctinfo, enum ip_conntrack_info ctinfo,
...@@ -56,11 +56,11 @@ extern int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb, ...@@ -56,11 +56,11 @@ extern int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb,
extern void nf_nat_follow_master(struct nf_conn *ct, extern void nf_nat_follow_master(struct nf_conn *ct,
struct nf_conntrack_expect *this); struct nf_conntrack_expect *this);
extern s16 nf_nat_get_offset(const struct nf_conn *ct, extern s32 nf_nat_get_offset(const struct nf_conn *ct,
enum ip_conntrack_dir dir, enum ip_conntrack_dir dir,
u32 seq); u32 seq);
extern void nf_nat_tcp_seq_adjust(struct sk_buff *skb, struct nf_conn *ct, extern void nf_nat_tcp_seq_adjust(struct sk_buff *skb, struct nf_conn *ct,
u32 dir, int off); u32 dir, s32 off);
#endif #endif
...@@ -1695,7 +1695,7 @@ int nf_conntrack_init_net(struct net *net) ...@@ -1695,7 +1695,7 @@ int nf_conntrack_init_net(struct net *net)
return ret; return ret;
} }
s16 (*nf_ct_nat_offset)(const struct nf_conn *ct, s32 (*nf_ct_nat_offset)(const struct nf_conn *ct,
enum ip_conntrack_dir dir, enum ip_conntrack_dir dir,
u32 seq); u32 seq);
EXPORT_SYMBOL_GPL(nf_ct_nat_offset); EXPORT_SYMBOL_GPL(nf_ct_nat_offset);
...@@ -496,7 +496,7 @@ static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff, ...@@ -496,7 +496,7 @@ static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff,
} }
#ifdef CONFIG_NF_NAT_NEEDED #ifdef CONFIG_NF_NAT_NEEDED
static inline s16 nat_offset(const struct nf_conn *ct, static inline s32 nat_offset(const struct nf_conn *ct,
enum ip_conntrack_dir dir, enum ip_conntrack_dir dir,
u32 seq) u32 seq)
{ {
...@@ -525,7 +525,7 @@ static bool tcp_in_window(const struct nf_conn *ct, ...@@ -525,7 +525,7 @@ static bool tcp_in_window(const struct nf_conn *ct,
struct ip_ct_tcp_state *receiver = &state->seen[!dir]; struct ip_ct_tcp_state *receiver = &state->seen[!dir];
const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple; const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
__u32 seq, ack, sack, end, win, swin; __u32 seq, ack, sack, end, win, swin;
s16 receiver_offset; s32 receiver_offset;
bool res; bool res;
/* /*
......
...@@ -68,13 +68,13 @@ adjust_tcp_sequence(u32 seq, ...@@ -68,13 +68,13 @@ adjust_tcp_sequence(u32 seq,
} }
/* Get the offset value, for conntrack */ /* Get the offset value, for conntrack */
s16 nf_nat_get_offset(const struct nf_conn *ct, s32 nf_nat_get_offset(const struct nf_conn *ct,
enum ip_conntrack_dir dir, enum ip_conntrack_dir dir,
u32 seq) u32 seq)
{ {
struct nf_conn_nat *nat = nfct_nat(ct); struct nf_conn_nat *nat = nfct_nat(ct);
struct nf_nat_seq *this_way; struct nf_nat_seq *this_way;
s16 offset; s32 offset;
if (!nat) if (!nat)
return 0; return 0;
...@@ -143,7 +143,7 @@ static int enlarge_skb(struct sk_buff *skb, unsigned int extra) ...@@ -143,7 +143,7 @@ static int enlarge_skb(struct sk_buff *skb, unsigned int extra)
} }
void nf_nat_set_seq_adjust(struct nf_conn *ct, enum ip_conntrack_info ctinfo, void nf_nat_set_seq_adjust(struct nf_conn *ct, enum ip_conntrack_info ctinfo,
__be32 seq, s16 off) __be32 seq, s32 off)
{ {
if (!off) if (!off)
return; return;
...@@ -370,7 +370,7 @@ nf_nat_seq_adjust(struct sk_buff *skb, ...@@ -370,7 +370,7 @@ nf_nat_seq_adjust(struct sk_buff *skb,
struct tcphdr *tcph; struct tcphdr *tcph;
int dir; int dir;
__be32 newseq, newack; __be32 newseq, newack;
s16 seqoff, ackoff; s32 seqoff, ackoff;
struct nf_conn_nat *nat = nfct_nat(ct); struct nf_conn_nat *nat = nfct_nat(ct);
struct nf_nat_seq *this_way, *other_way; struct nf_nat_seq *this_way, *other_way;
int res; int res;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment