[NETFILTER]: nf_conntrack_ftp: fix newline sequence number calculation
authorPatrick McHardy <kaber@trash.net>
Thu, 24 May 2007 23:41:50 +0000 (16:41 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 24 May 2007 23:41:50 +0000 (16:41 -0700)
When the packet size is changed by the FTP NAT helper, the connection
tracking helper adjusts the sequence number of the newline character
by the size difference. This is wrong because NAT sequence number
adjustment happens after helpers are called, so the unadjusted number
is compared to the already adjusted one.

Based on report by YU, Haitao <yuhaitao@tsinghua.org.cn>

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/netfilter/nf_conntrack_ftp.h
net/ipv4/netfilter/nf_nat_ftp.c
net/netfilter/nf_conntrack_ftp.c

index 81453ea7e4c2c063e351ce6ff6f63fa01e601a2d..b7c360ffd0d037db5fedef34b45ca921132fe82e 100644 (file)
@@ -37,8 +37,7 @@ extern unsigned int (*nf_nat_ftp_hook)(struct sk_buff **pskb,
                                       enum nf_ct_ftp_type type,
                                       unsigned int matchoff,
                                       unsigned int matchlen,
-                                      struct nf_conntrack_expect *exp,
-                                      u32 *seq);
+                                      struct nf_conntrack_expect *exp);
 #endif /* __KERNEL__ */
 
 #endif /* _NF_CONNTRACK_FTP_H */
index 751b598017555e9e2a1faefbec43cc67be3fae6f..e6bc8e5a72f13796a36c3fa1af3b5d12619fb1b2 100644 (file)
@@ -40,8 +40,7 @@ mangle_rfc959_packet(struct sk_buff **pskb,
                     unsigned int matchoff,
                     unsigned int matchlen,
                     struct nf_conn *ct,
-                    enum ip_conntrack_info ctinfo,
-                    u32 *seq)
+                    enum ip_conntrack_info ctinfo)
 {
        char buffer[sizeof("nnn,nnn,nnn,nnn,nnn,nnn")];
 
@@ -50,7 +49,6 @@ mangle_rfc959_packet(struct sk_buff **pskb,
 
        DEBUGP("calling nf_nat_mangle_tcp_packet\n");
 
-       *seq += strlen(buffer) - matchlen;
        return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff,
                                        matchlen, buffer, strlen(buffer));
 }
@@ -63,8 +61,7 @@ mangle_eprt_packet(struct sk_buff **pskb,
                   unsigned int matchoff,
                   unsigned int matchlen,
                   struct nf_conn *ct,
-                  enum ip_conntrack_info ctinfo,
-                  u32 *seq)
+                  enum ip_conntrack_info ctinfo)
 {
        char buffer[sizeof("|1|255.255.255.255|65535|")];
 
@@ -72,7 +69,6 @@ mangle_eprt_packet(struct sk_buff **pskb,
 
        DEBUGP("calling nf_nat_mangle_tcp_packet\n");
 
-       *seq += strlen(buffer) - matchlen;
        return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff,
                                        matchlen, buffer, strlen(buffer));
 }
@@ -85,8 +81,7 @@ mangle_epsv_packet(struct sk_buff **pskb,
                   unsigned int matchoff,
                   unsigned int matchlen,
                   struct nf_conn *ct,
-                  enum ip_conntrack_info ctinfo,
-                  u32 *seq)
+                  enum ip_conntrack_info ctinfo)
 {
        char buffer[sizeof("|||65535|")];
 
@@ -94,14 +89,13 @@ mangle_epsv_packet(struct sk_buff **pskb,
 
        DEBUGP("calling nf_nat_mangle_tcp_packet\n");
 
-       *seq += strlen(buffer) - matchlen;
        return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff,
                                        matchlen, buffer, strlen(buffer));
 }
 
 static int (*mangle[])(struct sk_buff **, __be32, u_int16_t,
                       unsigned int, unsigned int, struct nf_conn *,
-                      enum ip_conntrack_info, u32 *seq)
+                      enum ip_conntrack_info)
 = {
        [NF_CT_FTP_PORT] = mangle_rfc959_packet,
        [NF_CT_FTP_PASV] = mangle_rfc959_packet,
@@ -116,8 +110,7 @@ static unsigned int nf_nat_ftp(struct sk_buff **pskb,
                               enum nf_ct_ftp_type type,
                               unsigned int matchoff,
                               unsigned int matchlen,
-                              struct nf_conntrack_expect *exp,
-                              u32 *seq)
+                              struct nf_conntrack_expect *exp)
 {
        __be32 newip;
        u_int16_t port;
@@ -145,8 +138,7 @@ static unsigned int nf_nat_ftp(struct sk_buff **pskb,
        if (port == 0)
                return NF_DROP;
 
-       if (!mangle[type](pskb, newip, port, matchoff, matchlen, ct, ctinfo,
-                         seq)) {
+       if (!mangle[type](pskb, newip, port, matchoff, matchlen, ct, ctinfo)) {
                nf_conntrack_unexpect_related(exp);
                return NF_DROP;
        }
index 4bb669c7780f1e46b9284ffbab7ad5fec6f1f189..82db2aa53bfce5acecac166f4d10e493dc2fe478 100644 (file)
@@ -48,8 +48,7 @@ unsigned int (*nf_nat_ftp_hook)(struct sk_buff **pskb,
                                enum nf_ct_ftp_type type,
                                unsigned int matchoff,
                                unsigned int matchlen,
-                               struct nf_conntrack_expect *exp,
-                               u32 *seq);
+                               struct nf_conntrack_expect *exp);
 EXPORT_SYMBOL_GPL(nf_nat_ftp_hook);
 
 #if 0
@@ -521,7 +520,7 @@ static int help(struct sk_buff **pskb,
        nf_nat_ftp = rcu_dereference(nf_nat_ftp_hook);
        if (nf_nat_ftp && ct->status & IPS_NAT_MASK)
                ret = nf_nat_ftp(pskb, ctinfo, search[dir][i].ftptype,
-                                matchoff, matchlen, exp, &seq);
+                                matchoff, matchlen, exp);
        else {
                /* Can't expect this?  Best to drop packet now. */
                if (nf_conntrack_expect_related(exp) != 0)