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: Patrick McHardy <kaber@trash.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
Родитель
0658cdc8f3
Коммит
2d89c68ac7
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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 {
|
||||||
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,
|
||||||
|
|
||||||
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,
|
||||||
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 @@ err_stat:
|
||||||
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
#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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
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;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче