Skip to content

Commit

Permalink
netfilter: nf_nat: change sequence number adjustments to 32 bits
Browse files Browse the repository at this point in the history
Using 16 bits is too small, when many adjustments happen the offsets might
overflow and break the connection.

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  • Loading branch information
Patrick McHardy authored and Pablo Neira Ayuso committed Jul 31, 2013
1 parent 0658cdc commit 2d89c68
Show file tree
Hide file tree
Showing 7 changed files with 13 additions and 13 deletions.
2 changes: 1 addition & 1 deletion include/linux/netfilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ extern struct nfq_ct_hook __rcu *nfq_ct_hook;

struct nfq_ct_nat_hook {
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;
#else
Expand Down
2 changes: 1 addition & 1 deletion include/net/netfilter/nf_conntrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ static inline bool nf_ct_kill(struct nf_conn *ct)
}

/* 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,
u32 seq);

Expand Down
2 changes: 1 addition & 1 deletion include/net/netfilter/nf_nat.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ struct nf_nat_seq {
u_int32_t correction_pos;

/* sequence number offset before and after last modification */
int16_t offset_before, offset_after;
int32_t offset_before, offset_after;
};

#include <linux/list.h>
Expand Down
6 changes: 3 additions & 3 deletions include/net/netfilter/nf_nat_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
enum ip_conntrack_info ctinfo,
__be32 seq, s16 off);
__be32 seq, s32 off);
extern int nf_nat_seq_adjust(struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
Expand All @@ -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,
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,
u32 seq);

extern void nf_nat_tcp_seq_adjust(struct sk_buff *skb, struct nf_conn *ct,
u32 dir, int off);
u32 dir, s32 off);

#endif
2 changes: 1 addition & 1 deletion net/netfilter/nf_conntrack_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1695,7 +1695,7 @@ int nf_conntrack_init_net(struct net *net)
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,
u32 seq);
EXPORT_SYMBOL_GPL(nf_ct_nat_offset);
4 changes: 2 additions & 2 deletions net/netfilter/nf_conntrack_proto_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff,
}

#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,
u32 seq)
{
Expand Down Expand Up @@ -525,7 +525,7 @@ static bool tcp_in_window(const struct nf_conn *ct,
struct ip_ct_tcp_state *receiver = &state->seen[!dir];
const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
__u32 seq, ack, sack, end, win, swin;
s16 receiver_offset;
s32 receiver_offset;
bool res;

/*
Expand Down
8 changes: 4 additions & 4 deletions net/netfilter/nf_nat_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@ adjust_tcp_sequence(u32 seq,
}

/* 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,
u32 seq)
{
struct nf_conn_nat *nat = nfct_nat(ct);
struct nf_nat_seq *this_way;
s16 offset;
s32 offset;

if (!nat)
return 0;
Expand Down Expand Up @@ -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,
__be32 seq, s16 off)
__be32 seq, s32 off)
{
if (!off)
return;
Expand Down Expand Up @@ -370,7 +370,7 @@ nf_nat_seq_adjust(struct sk_buff *skb,
struct tcphdr *tcph;
int dir;
__be32 newseq, newack;
s16 seqoff, ackoff;
s32 seqoff, ackoff;
struct nf_conn_nat *nat = nfct_nat(ct);
struct nf_nat_seq *this_way, *other_way;
int res;
Expand Down

0 comments on commit 2d89c68

Please sign in to comment.