• Xin Long's avatar
    netfilter: check for seqadj ext existence before adding it in nf_nat_setup_info · dc3f9ba4
    Xin Long authored
    commit ab6dd1be upstream.
    
    Commit 4440a2ab ("netfilter: synproxy: Check oom when adding synproxy
    and seqadj ct extensions") wanted to drop the packet when it fails to add
    seqadj ext due to no memory by checking if nfct_seqadj_ext_add returns
    NULL.
    
    But that nfct_seqadj_ext_add returns NULL can also happen when seqadj ext
    already exists in a nf_conn. It will cause that userspace protocol doesn't
    work when both dnat and snat are configured.
    
    Li Shuang found this issue in the case:
    
    Topo:
       ftp client                   router                  ftp server
      10.167.131.2  <-> 10.167.131.254  10.167.141.254 <-> 10.167.141.1
    
    Rules:
      # iptables -t nat -A PREROUTING -i eth1 -p tcp -m tcp --dport 21 -j \
        DNAT --to-destination 10.167.141.1
      # iptables -t nat -A POSTROUTING -o eth2 -p tcp -m tcp --dport 21 -j \
        SNAT --to-source 10.167.141.254
    
    In router, when both dnat and snat are added, nf_nat_setup_info will be
    called twice. The packet can be dropped at the 2nd time for DNAT due to
    seqadj ext is already added at the 1st time for SNAT.
    
    This patch is to fix it by checking for seqadj ext existence before adding
    it, so that the packet will not be dropped if seqadj ext already exists.
    
    Note that as Florian mentioned, as a long term, we should review ext_add()
    behaviour, it's better to return a pointer to the existing ext instead.
    
    Fixes: 4440a2ab ("netfilter: synproxy: Check oom when adding synproxy and seqadj ct extensions")
    Reported-by: 's avatarLi Shuang <shuali@redhat.com>
    Acked-by: 's avatarFlorian Westphal <fw@strlen.de>
    Signed-off-by: 's avatarXin Long <lucien.xin@gmail.com>
    Signed-off-by: 's avatarPablo Neira Ayuso <pablo@netfilter.org>
    Signed-off-by: 's avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    dc3f9ba4
Name
Last commit
Last update
..
6lowpan Loading commit data...
802 Loading commit data...
8021q Loading commit data...
9p Loading commit data...
appletalk Loading commit data...
atm Loading commit data...
ax25 Loading commit data...
batman-adv Loading commit data...
bluetooth Loading commit data...
bridge Loading commit data...
caif Loading commit data...
can Loading commit data...
ceph Loading commit data...
core Loading commit data...
dcb Loading commit data...
dccp Loading commit data...
decnet Loading commit data...
dns_resolver Loading commit data...
dsa Loading commit data...
ethernet Loading commit data...
hsr Loading commit data...
ieee802154 Loading commit data...
ipv4 Loading commit data...
ipv6 Loading commit data...
ipx Loading commit data...
irda Loading commit data...
iucv Loading commit data...
kcm Loading commit data...
key Loading commit data...
l2tp Loading commit data...
l3mdev Loading commit data...
lapb Loading commit data...
llc Loading commit data...
mac80211 Loading commit data...
mac802154 Loading commit data...
mpls Loading commit data...
ncsi Loading commit data...
netfilter Loading commit data...
netlabel Loading commit data...
netlink Loading commit data...
netrom Loading commit data...
nfc Loading commit data...
openvswitch Loading commit data...
packet Loading commit data...
phonet Loading commit data...
qrtr Loading commit data...
rds Loading commit data...
rfkill Loading commit data...
rose Loading commit data...
rxrpc Loading commit data...
sched Loading commit data...
sctp Loading commit data...
strparser Loading commit data...
sunrpc Loading commit data...
switchdev Loading commit data...
tipc Loading commit data...
unix Loading commit data...
vmw_vsock Loading commit data...
wimax Loading commit data...
wireless Loading commit data...
x25 Loading commit data...
xfrm Loading commit data...
Kconfig Loading commit data...
Makefile Loading commit data...
compat.c Loading commit data...
socket.c Loading commit data...
sysctl_net.c Loading commit data...