]>
Commit | Line | Data |
---|---|---|
7c95fd11 GKH |
1 | From ab6dd1beac7be3c17f8bf3d38bdf29ecb7293f1e Mon Sep 17 00:00:00 2001 |
2 | From: Xin Long <lucien.xin@gmail.com> | |
3 | Date: Thu, 10 Aug 2017 10:22:24 +0800 | |
4 | Subject: netfilter: check for seqadj ext existence before adding it in nf_nat_setup_info | |
5 | ||
6 | From: Xin Long <lucien.xin@gmail.com> | |
7 | ||
8 | commit ab6dd1beac7be3c17f8bf3d38bdf29ecb7293f1e upstream. | |
9 | ||
10 | Commit 4440a2ab3b9f ("netfilter: synproxy: Check oom when adding synproxy | |
11 | and seqadj ct extensions") wanted to drop the packet when it fails to add | |
12 | seqadj ext due to no memory by checking if nfct_seqadj_ext_add returns | |
13 | NULL. | |
14 | ||
15 | But that nfct_seqadj_ext_add returns NULL can also happen when seqadj ext | |
16 | already exists in a nf_conn. It will cause that userspace protocol doesn't | |
17 | work when both dnat and snat are configured. | |
18 | ||
19 | Li Shuang found this issue in the case: | |
20 | ||
21 | Topo: | |
22 | ftp client router ftp server | |
23 | 10.167.131.2 <-> 10.167.131.254 10.167.141.254 <-> 10.167.141.1 | |
24 | ||
25 | Rules: | |
26 | # iptables -t nat -A PREROUTING -i eth1 -p tcp -m tcp --dport 21 -j \ | |
27 | DNAT --to-destination 10.167.141.1 | |
28 | # iptables -t nat -A POSTROUTING -o eth2 -p tcp -m tcp --dport 21 -j \ | |
29 | SNAT --to-source 10.167.141.254 | |
30 | ||
31 | In router, when both dnat and snat are added, nf_nat_setup_info will be | |
32 | called twice. The packet can be dropped at the 2nd time for DNAT due to | |
33 | seqadj ext is already added at the 1st time for SNAT. | |
34 | ||
35 | This patch is to fix it by checking for seqadj ext existence before adding | |
36 | it, so that the packet will not be dropped if seqadj ext already exists. | |
37 | ||
38 | Note that as Florian mentioned, as a long term, we should review ext_add() | |
39 | behaviour, it's better to return a pointer to the existing ext instead. | |
40 | ||
41 | Fixes: 4440a2ab3b9f ("netfilter: synproxy: Check oom when adding synproxy and seqadj ct extensions") | |
42 | Reported-by: Li Shuang <shuali@redhat.com> | |
43 | Acked-by: Florian Westphal <fw@strlen.de> | |
44 | Signed-off-by: Xin Long <lucien.xin@gmail.com> | |
45 | Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> | |
46 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
47 | ||
48 | --- | |
49 | net/netfilter/nf_nat_core.c | 2 +- | |
50 | 1 file changed, 1 insertion(+), 1 deletion(-) | |
51 | ||
52 | --- a/net/netfilter/nf_nat_core.c | |
53 | +++ b/net/netfilter/nf_nat_core.c | |
54 | @@ -421,7 +421,7 @@ nf_nat_setup_info(struct nf_conn *ct, | |
55 | else | |
56 | ct->status |= IPS_DST_NAT; | |
57 | ||
58 | - if (nfct_help(ct)) | |
59 | + if (nfct_help(ct) && !nfct_seqadj(ct)) | |
60 | if (!nfct_seqadj_ext_add(ct)) | |
61 | return NF_DROP; | |
62 | } |