Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next

Conflicts:
net/netfilter/nf_log.c

The conflict in nf_log.c is that in 'net' we added CONFIG_PROC_FS
protection around foo_proc_entry() calls to fix a build failure,
whereas in Pablo's tree a guard if() test around a call is
remove_proc_entry() was removed. Trivially resolved.

Pablo Neira Ayuso says:

====================
The following patchset contains the first batch of
Netfilter/IPVS updates for your net-next tree, they are:

* Three patches with improvements and code refactorization
for nfnetlink_queue, from Florian Westphal.

* FTP helper now parses replies without brackets, as RFC1123
recommends, from Jeff Mahoney.

* Rise a warning to tell everyone about ULOG deprecation,
NFLOG has been already in the kernel tree for long time
and supersedes the old logging over netlink stub, from
myself.

* Don't panic if we fail to load netfilter core framework,
just bail out instead, from myself.

* Add cond_resched_rcu, used by IPVS to allow rescheduling
while walking over big hashtables, from Simon Horman.

* Change type of IPVS sysctl_sync_qlen_max sysctl to avoid
possible overflow, from Zhang Yanfei.

* Use strlcpy instead of strncpy to skip zeroing of already
initialized area to write the extension names in ebtables,
from Chen Gang.

* Use already existing per-cpu notrack object from xt_CT,
from Eric Dumazet.

* Save explicit socket lookup in xt_socket now that we have
early demux, also from Eric Dumazet.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+155 -84
+1 -1
include/linux/netfilter.h
··· 35 35 result->all[3] = a1->all[3] & mask->all[3]; 36 36 } 37 37 38 - extern void netfilter_init(void); 38 + extern int netfilter_init(void); 39 39 40 40 /* Largest hook number + 1 */ 41 41 #define NF_MAX_HOOKS 8
+9
include/linux/sched.h
··· 2444 2444 __cond_resched_softirq(); \ 2445 2445 }) 2446 2446 2447 + static inline void cond_resched_rcu(void) 2448 + { 2449 + #if defined(CONFIG_DEBUG_ATOMIC_SLEEP) || !defined(CONFIG_PREEMPT_RCU) 2450 + rcu_read_unlock(); 2451 + cond_resched(); 2452 + rcu_read_lock(); 2453 + #endif 2454 + } 2455 + 2447 2456 /* 2448 2457 * Does a critical section need to be broken due to another 2449 2458 * task waiting?: (technically does not depend on CONFIG_PREEMPT,
+4 -4
include/net/ip_vs.h
··· 905 905 struct ipvs_master_sync_state { 906 906 struct list_head sync_queue; 907 907 struct ip_vs_sync_buff *sync_buff; 908 - int sync_queue_len; 908 + unsigned long sync_queue_len; 909 909 unsigned int sync_queue_delay; 910 910 struct task_struct *master_thread; 911 911 struct delayed_work master_wakeup_work; ··· 998 998 int sysctl_snat_reroute; 999 999 int sysctl_sync_ver; 1000 1000 int sysctl_sync_ports; 1001 - int sysctl_sync_qlen_max; 1001 + unsigned long sysctl_sync_qlen_max; 1002 1002 int sysctl_sync_sock_size; 1003 1003 int sysctl_cache_bypass; 1004 1004 int sysctl_expire_nodest_conn; ··· 1085 1085 return ACCESS_ONCE(ipvs->sysctl_sync_ports); 1086 1086 } 1087 1087 1088 - static inline int sysctl_sync_qlen_max(struct netns_ipvs *ipvs) 1088 + static inline unsigned long sysctl_sync_qlen_max(struct netns_ipvs *ipvs) 1089 1089 { 1090 1090 return ipvs->sysctl_sync_qlen_max; 1091 1091 } ··· 1138 1138 return 1; 1139 1139 } 1140 1140 1141 - static inline int sysctl_sync_qlen_max(struct netns_ipvs *ipvs) 1141 + static inline unsigned long sysctl_sync_qlen_max(struct netns_ipvs *ipvs) 1142 1142 { 1143 1143 return IPVS_SYNC_QLEN_MAX; 1144 1144 }
+6
include/net/netns/x_tables.h
··· 15 15 struct ebt_table *frame_filter; 16 16 struct ebt_table *frame_nat; 17 17 #endif 18 + #if IS_ENABLED(CONFIG_IP_NF_TARGET_ULOG) 19 + bool ulog_warn_deprecated; 20 + #endif 21 + #if IS_ENABLED(CONFIG_BRIDGE_EBT_ULOG) 22 + bool ebt_ulog_warn_deprecated; 23 + #endif 18 24 }; 19 25 #endif
+6
net/bridge/netfilter/ebt_ulog.c
··· 271 271 { 272 272 struct ebt_ulog_info *uloginfo = par->targinfo; 273 273 274 + if (!par->net->xt.ebt_ulog_warn_deprecated) { 275 + pr_info("ebt_ulog is deprecated and it will be removed soon, " 276 + "use ebt_nflog instead\n"); 277 + par->net->xt.ebt_ulog_warn_deprecated = true; 278 + } 279 + 274 280 if (uloginfo->nlgroup > 31) 275 281 return -EINVAL; 276 282
+3 -3
net/bridge/netfilter/ebtables.c
··· 1339 1339 1340 1340 /* ebtables expects 32 bytes long names but xt_match names are 29 bytes 1341 1341 long. Copy 29 bytes and fill remaining bytes with zeroes. */ 1342 - strncpy(name, m->u.match->name, sizeof(name)); 1342 + strlcpy(name, m->u.match->name, sizeof(name)); 1343 1343 if (copy_to_user(hlp, name, EBT_FUNCTION_MAXNAMELEN)) 1344 1344 return -EFAULT; 1345 1345 return 0; ··· 1351 1351 char __user *hlp = ubase + ((char *)w - base); 1352 1352 char name[EBT_FUNCTION_MAXNAMELEN] = {}; 1353 1353 1354 - strncpy(name, w->u.watcher->name, sizeof(name)); 1354 + strlcpy(name, w->u.watcher->name, sizeof(name)); 1355 1355 if (copy_to_user(hlp , name, EBT_FUNCTION_MAXNAMELEN)) 1356 1356 return -EFAULT; 1357 1357 return 0; ··· 1377 1377 ret = EBT_WATCHER_ITERATE(e, ebt_make_watchername, base, ubase); 1378 1378 if (ret != 0) 1379 1379 return ret; 1380 - strncpy(name, t->u.target->name, sizeof(name)); 1380 + strlcpy(name, t->u.target->name, sizeof(name)); 1381 1381 if (copy_to_user(hlp, name, EBT_FUNCTION_MAXNAMELEN)) 1382 1382 return -EFAULT; 1383 1383 return 0;
+1 -1
net/ipv4/netfilter/Kconfig
··· 111 111 To compile it as a module, choose M here. If unsure, say N. 112 112 113 113 config IP_NF_TARGET_ULOG 114 - tristate "ULOG target support" 114 + tristate "ULOG target support (obsolete)" 115 115 default m if NETFILTER_ADVANCED=n 116 116 ---help--- 117 117
+6
net/ipv4/netfilter/ipt_ULOG.c
··· 330 330 { 331 331 const struct ipt_ulog_info *loginfo = par->targinfo; 332 332 333 + if (!par->net->xt.ulog_warn_deprecated) { 334 + pr_info("ULOG is deprecated and it will be removed soon, " 335 + "use NFLOG instead\n"); 336 + par->net->xt.ulog_warn_deprecated = true; 337 + } 338 + 333 339 if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') { 334 340 pr_debug("prefix not null-terminated\n"); 335 341 return -EINVAL;
+15 -6
net/netfilter/core.c
··· 304 304 .exit = netfilter_net_exit, 305 305 }; 306 306 307 - void __init netfilter_init(void) 307 + int __init netfilter_init(void) 308 308 { 309 - int i, h; 309 + int i, h, ret; 310 + 310 311 for (i = 0; i < ARRAY_SIZE(nf_hooks); i++) { 311 312 for (h = 0; h < NF_MAX_HOOKS; h++) 312 313 INIT_LIST_HEAD(&nf_hooks[i][h]); 313 314 } 314 315 315 - if (register_pernet_subsys(&netfilter_net_ops) < 0) 316 - panic("cannot create netfilter proc entry"); 316 + ret = register_pernet_subsys(&netfilter_net_ops); 317 + if (ret < 0) 318 + goto err; 317 319 318 - if (netfilter_log_init() < 0) 319 - panic("cannot initialize nf_log"); 320 + ret = netfilter_log_init(); 321 + if (ret < 0) 322 + goto err_pernet; 323 + 324 + return 0; 325 + err_pernet: 326 + unregister_pernet_subsys(&netfilter_net_ops); 327 + err: 328 + return ret; 320 329 }
+8 -15
net/netfilter/ipvs/ip_vs_conn.c
··· 975 975 return cp; 976 976 } 977 977 } 978 - rcu_read_unlock(); 979 - rcu_read_lock(); 978 + cond_resched_rcu(); 980 979 } 981 980 982 981 return NULL; ··· 1014 1015 iter->l = &ip_vs_conn_tab[idx]; 1015 1016 return cp; 1016 1017 } 1017 - rcu_read_unlock(); 1018 - rcu_read_lock(); 1018 + cond_resched_rcu(); 1019 1019 } 1020 1020 iter->l = NULL; 1021 1021 return NULL; ··· 1204 1206 int idx; 1205 1207 struct ip_vs_conn *cp, *cp_c; 1206 1208 1209 + rcu_read_lock(); 1207 1210 /* 1208 1211 * Randomly scan 1/32 of the whole table every second 1209 1212 */ 1210 1213 for (idx = 0; idx < (ip_vs_conn_tab_size>>5); idx++) { 1211 1214 unsigned int hash = net_random() & ip_vs_conn_tab_mask; 1212 - 1213 - /* 1214 - * Lock is actually needed in this loop. 1215 - */ 1216 - rcu_read_lock(); 1217 1215 1218 1216 hlist_for_each_entry_rcu(cp, &ip_vs_conn_tab[hash], c_list) { 1219 1217 if (cp->flags & IP_VS_CONN_F_TEMPLATE) ··· 1246 1252 __ip_vs_conn_put(cp); 1247 1253 } 1248 1254 } 1249 - rcu_read_unlock(); 1255 + cond_resched_rcu(); 1250 1256 } 1257 + rcu_read_unlock(); 1251 1258 } 1252 1259 1253 1260 ··· 1262 1267 struct netns_ipvs *ipvs = net_ipvs(net); 1263 1268 1264 1269 flush_again: 1270 + rcu_read_lock(); 1265 1271 for (idx = 0; idx < ip_vs_conn_tab_size; idx++) { 1266 - /* 1267 - * Lock is actually needed in this loop. 1268 - */ 1269 - rcu_read_lock(); 1270 1272 1271 1273 hlist_for_each_entry_rcu(cp, &ip_vs_conn_tab[idx], c_list) { 1272 1274 if (!ip_vs_conn_net_eq(cp, net)) ··· 1278 1286 __ip_vs_conn_put(cp); 1279 1287 } 1280 1288 } 1281 - rcu_read_unlock(); 1289 + cond_resched_rcu(); 1282 1290 } 1291 + rcu_read_unlock(); 1283 1292 1284 1293 /* the counter may be not NULL, because maybe some conn entries 1285 1294 are run by slow timer handler or unhashed but still referred */
+2 -2
net/netfilter/ipvs/ip_vs_ctl.c
··· 1716 1716 }, 1717 1717 { 1718 1718 .procname = "sync_qlen_max", 1719 - .maxlen = sizeof(int), 1719 + .maxlen = sizeof(unsigned long), 1720 1720 .mode = 0644, 1721 - .proc_handler = proc_dointvec, 1721 + .proc_handler = proc_doulongvec_minmax, 1722 1722 }, 1723 1723 { 1724 1724 .procname = "sync_sock_size",
+54 -19
net/netfilter/nf_conntrack_ftp.c
··· 55 55 struct nf_conntrack_expect *exp); 56 56 EXPORT_SYMBOL_GPL(nf_nat_ftp_hook); 57 57 58 - static int try_rfc959(const char *, size_t, struct nf_conntrack_man *, char); 59 - static int try_eprt(const char *, size_t, struct nf_conntrack_man *, char); 58 + static int try_rfc959(const char *, size_t, struct nf_conntrack_man *, 59 + char, unsigned int *); 60 + static int try_rfc1123(const char *, size_t, struct nf_conntrack_man *, 61 + char, unsigned int *); 62 + static int try_eprt(const char *, size_t, struct nf_conntrack_man *, 63 + char, unsigned int *); 60 64 static int try_epsv_response(const char *, size_t, struct nf_conntrack_man *, 61 - char); 65 + char, unsigned int *); 62 66 63 67 static struct ftp_search { 64 68 const char *pattern; ··· 70 66 char skip; 71 67 char term; 72 68 enum nf_ct_ftp_type ftptype; 73 - int (*getnum)(const char *, size_t, struct nf_conntrack_man *, char); 69 + int (*getnum)(const char *, size_t, struct nf_conntrack_man *, char, unsigned int *); 74 70 } search[IP_CT_DIR_MAX][2] = { 75 71 [IP_CT_DIR_ORIGINAL] = { 76 72 { ··· 94 90 { 95 91 .pattern = "227 ", 96 92 .plen = sizeof("227 ") - 1, 97 - .skip = '(', 98 - .term = ')', 99 93 .ftptype = NF_CT_FTP_PASV, 100 - .getnum = try_rfc959, 94 + .getnum = try_rfc1123, 101 95 }, 102 96 { 103 97 .pattern = "229 ", ··· 134 132 i++; 135 133 else { 136 134 /* Unexpected character; true if it's the 137 - terminator and we're finished. */ 138 - if (*data == term && i == array_size - 1) 135 + terminator (or we don't care about one) 136 + and we're finished. */ 137 + if ((*data == term || !term) && i == array_size - 1) 139 138 return len; 140 139 141 140 pr_debug("Char %u (got %u nums) `%u' unexpected\n", ··· 151 148 152 149 /* Returns 0, or length of numbers: 192,168,1,1,5,6 */ 153 150 static int try_rfc959(const char *data, size_t dlen, 154 - struct nf_conntrack_man *cmd, char term) 151 + struct nf_conntrack_man *cmd, char term, 152 + unsigned int *offset) 155 153 { 156 154 int length; 157 155 u_int32_t array[6]; ··· 165 161 (array[2] << 8) | array[3]); 166 162 cmd->u.tcp.port = htons((array[4] << 8) | array[5]); 167 163 return length; 164 + } 165 + 166 + /* 167 + * From RFC 1123: 168 + * The format of the 227 reply to a PASV command is not 169 + * well standardized. In particular, an FTP client cannot 170 + * assume that the parentheses shown on page 40 of RFC-959 171 + * will be present (and in fact, Figure 3 on page 43 omits 172 + * them). Therefore, a User-FTP program that interprets 173 + * the PASV reply must scan the reply for the first digit 174 + * of the host and port numbers. 175 + */ 176 + static int try_rfc1123(const char *data, size_t dlen, 177 + struct nf_conntrack_man *cmd, char term, 178 + unsigned int *offset) 179 + { 180 + int i; 181 + for (i = 0; i < dlen; i++) 182 + if (isdigit(data[i])) 183 + break; 184 + 185 + if (i == dlen) 186 + return 0; 187 + 188 + *offset += i; 189 + 190 + return try_rfc959(data + i, dlen - i, cmd, 0, offset); 168 191 } 169 192 170 193 /* Grab port: number up to delimiter */ ··· 222 191 223 192 /* Returns 0, or length of numbers: |1|132.235.1.2|6275| or |2|3ffe::1|6275| */ 224 193 static int try_eprt(const char *data, size_t dlen, struct nf_conntrack_man *cmd, 225 - char term) 194 + char term, unsigned int *offset) 226 195 { 227 196 char delim; 228 197 int length; ··· 270 239 271 240 /* Returns 0, or length of numbers: |||6446| */ 272 241 static int try_epsv_response(const char *data, size_t dlen, 273 - struct nf_conntrack_man *cmd, char term) 242 + struct nf_conntrack_man *cmd, char term, 243 + unsigned int *offset) 274 244 { 275 245 char delim; 276 246 ··· 293 261 unsigned int *numlen, 294 262 struct nf_conntrack_man *cmd, 295 263 int (*getnum)(const char *, size_t, 296 - struct nf_conntrack_man *, char)) 264 + struct nf_conntrack_man *, char, 265 + unsigned int *)) 297 266 { 298 - size_t i; 267 + size_t i = plen; 299 268 300 269 pr_debug("find_pattern `%s': dlen = %Zu\n", pattern, dlen); 301 270 if (dlen == 0) ··· 326 293 pr_debug("Pattern matches!\n"); 327 294 /* Now we've found the constant string, try to skip 328 295 to the 'skip' character */ 329 - for (i = plen; data[i] != skip; i++) 330 - if (i == dlen - 1) return -1; 296 + if (skip) { 297 + for (i = plen; data[i] != skip; i++) 298 + if (i == dlen - 1) return -1; 331 299 332 - /* Skip over the last character */ 333 - i++; 300 + /* Skip over the last character */ 301 + i++; 302 + } 334 303 335 304 pr_debug("Skipped up to `%c'!\n", skip); 336 305 337 306 *numoff = i; 338 - *numlen = getnum(data + i, dlen - i, cmd, term); 307 + *numlen = getnum(data + i, dlen - i, cmd, term, numoff); 339 308 if (!*numlen) 340 309 return -1; 341 310
+1 -3
net/netfilter/nf_log.c
··· 369 369 370 370 out_sysctl: 371 371 #ifdef CONFIG_PROC_FS 372 - /* For init_net: errors will trigger panic, don't unroll on error. */ 373 - if (!net_eq(net, &init_net)) 374 - remove_proc_entry("nf_log", net->nf.proc_netfilter); 372 + remove_proc_entry("nf_log", net->nf.proc_netfilter); 375 373 #endif 376 374 return ret; 377 375 }
+6 -4
net/netfilter/xt_CT.c
··· 26 26 if (skb->nfct != NULL) 27 27 return XT_CONTINUE; 28 28 29 + /* special case the untracked ct : we want the percpu object */ 30 + if (!ct) 31 + ct = nf_ct_untracked_get(); 29 32 atomic_inc(&ct->ct_general.use); 30 33 skb->nfct = &ct->ct_general; 31 34 skb->nfctinfo = IP_CT_NEW; ··· 189 186 int ret = -EOPNOTSUPP; 190 187 191 188 if (info->flags & XT_CT_NOTRACK) { 192 - ct = nf_ct_untracked_get(); 193 - atomic_inc(&ct->ct_general.use); 189 + ct = NULL; 194 190 goto out; 195 191 } 196 192 ··· 313 311 struct nf_conn *ct = info->ct; 314 312 struct nf_conn_help *help; 315 313 316 - if (!nf_ct_is_untracked(ct)) { 314 + if (ct && !nf_ct_is_untracked(ct)) { 317 315 help = nfct_help(ct); 318 316 if (help) 319 317 module_put(help->helper->me); ··· 321 319 nf_ct_l3proto_module_put(par->family); 322 320 323 321 xt_ct_destroy_timeout(ct); 322 + nf_ct_put(info->ct); 324 323 } 325 - nf_ct_put(info->ct); 326 324 } 327 325 328 326 static void xt_ct_tg_destroy_v0(const struct xt_tgdtor_param *par)
+16 -10
net/netfilter/xt_socket.c
··· 107 107 { 108 108 const struct iphdr *iph = ip_hdr(skb); 109 109 struct udphdr _hdr, *hp = NULL; 110 - struct sock *sk; 110 + struct sock *sk = skb->sk; 111 111 __be32 uninitialized_var(daddr), uninitialized_var(saddr); 112 112 __be16 uninitialized_var(dport), uninitialized_var(sport); 113 113 u8 uninitialized_var(protocol); ··· 155 155 } 156 156 #endif 157 157 158 - sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), protocol, 159 - saddr, daddr, sport, dport, par->in, NFT_LOOKUP_ANY); 160 - if (sk != NULL) { 158 + if (!sk) 159 + sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), protocol, 160 + saddr, daddr, sport, dport, 161 + par->in, NFT_LOOKUP_ANY); 162 + if (sk) { 161 163 bool wildcard; 162 164 bool transparent = true; 163 165 ··· 175 173 (sk->sk_state == TCP_TIME_WAIT && 176 174 inet_twsk(sk)->tw_transparent)); 177 175 178 - xt_socket_put_sk(sk); 176 + if (sk != skb->sk) 177 + xt_socket_put_sk(sk); 179 178 180 179 if (wildcard || !transparent) 181 180 sk = NULL; ··· 263 260 { 264 261 struct ipv6hdr *iph = ipv6_hdr(skb); 265 262 struct udphdr _hdr, *hp = NULL; 266 - struct sock *sk; 263 + struct sock *sk = skb->sk; 267 264 struct in6_addr *daddr = NULL, *saddr = NULL; 268 265 __be16 uninitialized_var(dport), uninitialized_var(sport); 269 266 int thoff = 0, uninitialized_var(tproto); ··· 294 291 return false; 295 292 } 296 293 297 - sk = nf_tproxy_get_sock_v6(dev_net(skb->dev), tproto, 298 - saddr, daddr, sport, dport, par->in, NFT_LOOKUP_ANY); 299 - if (sk != NULL) { 294 + if (!sk) 295 + sk = nf_tproxy_get_sock_v6(dev_net(skb->dev), tproto, 296 + saddr, daddr, sport, dport, 297 + par->in, NFT_LOOKUP_ANY); 298 + if (sk) { 300 299 bool wildcard; 301 300 bool transparent = true; 302 301 ··· 314 309 (sk->sk_state == TCP_TIME_WAIT && 315 310 inet_twsk(sk)->tw_transparent)); 316 311 317 - xt_socket_put_sk(sk); 312 + if (sk != skb->sk) 313 + xt_socket_put_sk(sk); 318 314 319 315 if (wildcard || !transparent) 320 316 sk = NULL;
+3 -1
net/socket.c
··· 2641 2641 */ 2642 2642 2643 2643 #ifdef CONFIG_NETFILTER 2644 - netfilter_init(); 2644 + err = netfilter_init(); 2645 + if (err) 2646 + goto out; 2645 2647 #endif 2646 2648 2647 2649 #ifdef CONFIG_NETWORK_PHY_TIMESTAMPING