Skip to content

Commit a08ce73

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
Pablo Neira Ayuso says: ==================== Netfilter/IPVS fixes for net The following patchset contains Netfilter/IPVS fixes for your net tree: 1) Reject non-null terminated helper names from xt_CT, from Gao Feng. 2) Fix KASAN splat due to out-of-bound access from commit phase, from Alexey Kodanev. 3) Missing conntrack hook registration on IPVS FTP helper, from Julian Anastasov. 4) Incorrect skbuff allocation size in bridge nft_reject, from Taehee Yoo. 5) Fix inverted check on packet xmit to non-local addresses, also from Julian. 6) Fix ebtables alignment compat problems, from Alin Nastac. 7) Hook mask checks are not correct in xt_set, from Serhey Popovych. 8) Fix timeout listing of element in ipsets, from Jozsef. 9) Cap maximum timeout value in ipset, also from Jozsef. 10) Don't allow family option for hash:mac sets, from Florent Fourcot. 11) Restrict ebtables to work with NFPROTO_BRIDGE targets only, this Florian. 12) Another bug reported by KASAN in the rbtree set backend, from Taehee Yoo. 13) Missing __IPS_MAX_BIT update doesn't include IPS_OFFLOAD_BIT. From Gao Feng. 14) Missing initialization of match/target in ebtables, from Florian Westphal. 15) Remove useless nft_dup.h file in include path, from C. Labbe. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 349b71d + d8e87fc commit a08ce73

File tree

15 files changed

+99
-36
lines changed

15 files changed

+99
-36
lines changed

include/linux/netfilter/ipset/ip_set_timeout.h

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
/* Set is defined with timeout support: timeout value may be 0 */
2424
#define IPSET_NO_TIMEOUT UINT_MAX
2525

26+
/* Max timeout value, see msecs_to_jiffies() in jiffies.h */
27+
#define IPSET_MAX_TIMEOUT (UINT_MAX >> 1)/MSEC_PER_SEC
28+
2629
#define ip_set_adt_opt_timeout(opt, set) \
2730
((opt)->ext.timeout != IPSET_NO_TIMEOUT ? (opt)->ext.timeout : (set)->timeout)
2831

@@ -32,11 +35,10 @@ ip_set_timeout_uget(struct nlattr *tb)
3235
unsigned int timeout = ip_set_get_h32(tb);
3336

3437
/* Normalize to fit into jiffies */
35-
if (timeout > UINT_MAX/MSEC_PER_SEC)
36-
timeout = UINT_MAX/MSEC_PER_SEC;
38+
if (timeout > IPSET_MAX_TIMEOUT)
39+
timeout = IPSET_MAX_TIMEOUT;
3740

38-
/* Userspace supplied TIMEOUT parameter: adjust crazy size */
39-
return timeout == IPSET_NO_TIMEOUT ? IPSET_NO_TIMEOUT - 1 : timeout;
41+
return timeout;
4042
}
4143

4244
static inline bool
@@ -65,8 +67,14 @@ ip_set_timeout_set(unsigned long *timeout, u32 value)
6567
static inline u32
6668
ip_set_timeout_get(const unsigned long *timeout)
6769
{
68-
return *timeout == IPSET_ELEM_PERMANENT ? 0 :
69-
jiffies_to_msecs(*timeout - jiffies)/MSEC_PER_SEC;
70+
u32 t;
71+
72+
if (*timeout == IPSET_ELEM_PERMANENT)
73+
return 0;
74+
75+
t = jiffies_to_msecs(*timeout - jiffies)/MSEC_PER_SEC;
76+
/* Zero value in userspace means no timeout */
77+
return t == 0 ? 1 : t;
7078
}
7179

7280
#endif /* __KERNEL__ */

include/net/ip_vs.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,7 @@ struct ip_vs_service {
631631

632632
/* alternate persistence engine */
633633
struct ip_vs_pe __rcu *pe;
634+
int conntrack_afmask;
634635

635636
struct rcu_head rcu_head;
636637
};
@@ -1611,6 +1612,35 @@ static inline bool ip_vs_conn_uses_conntrack(struct ip_vs_conn *cp,
16111612
return false;
16121613
}
16131614

1615+
static inline int ip_vs_register_conntrack(struct ip_vs_service *svc)
1616+
{
1617+
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
1618+
int afmask = (svc->af == AF_INET6) ? 2 : 1;
1619+
int ret = 0;
1620+
1621+
if (!(svc->conntrack_afmask & afmask)) {
1622+
ret = nf_ct_netns_get(svc->ipvs->net, svc->af);
1623+
if (ret >= 0)
1624+
svc->conntrack_afmask |= afmask;
1625+
}
1626+
return ret;
1627+
#else
1628+
return 0;
1629+
#endif
1630+
}
1631+
1632+
static inline void ip_vs_unregister_conntrack(struct ip_vs_service *svc)
1633+
{
1634+
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
1635+
int afmask = (svc->af == AF_INET6) ? 2 : 1;
1636+
1637+
if (svc->conntrack_afmask & afmask) {
1638+
nf_ct_netns_put(svc->ipvs->net, svc->af);
1639+
svc->conntrack_afmask &= ~afmask;
1640+
}
1641+
#endif
1642+
}
1643+
16141644
static inline int
16151645
ip_vs_dest_conn_overhead(struct ip_vs_dest *dest)
16161646
{

include/net/netfilter/nft_dup.h

Lines changed: 0 additions & 10 deletions
This file was deleted.

include/uapi/linux/netfilter/nf_conntrack_common.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ enum ip_conntrack_status {
112112
IPS_EXPECTED | IPS_CONFIRMED | IPS_DYING |
113113
IPS_SEQ_ADJUST | IPS_TEMPLATE | IPS_OFFLOAD),
114114

115-
__IPS_MAX_BIT = 14,
115+
__IPS_MAX_BIT = 15,
116116
};
117117

118118
/* Connection tracking event types */

net/bridge/netfilter/ebtables.c

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,12 @@ ebt_check_watcher(struct ebt_entry_watcher *w, struct xt_tgchk_param *par,
411411
watcher = xt_request_find_target(NFPROTO_BRIDGE, w->u.name, 0);
412412
if (IS_ERR(watcher))
413413
return PTR_ERR(watcher);
414+
415+
if (watcher->family != NFPROTO_BRIDGE) {
416+
module_put(watcher->me);
417+
return -ENOENT;
418+
}
419+
414420
w->u.watcher = watcher;
415421

416422
par->target = watcher;
@@ -709,6 +715,8 @@ ebt_check_entry(struct ebt_entry *e, struct net *net,
709715
}
710716
i = 0;
711717

718+
memset(&mtpar, 0, sizeof(mtpar));
719+
memset(&tgpar, 0, sizeof(tgpar));
712720
mtpar.net = tgpar.net = net;
713721
mtpar.table = tgpar.table = name;
714722
mtpar.entryinfo = tgpar.entryinfo = e;
@@ -730,6 +738,13 @@ ebt_check_entry(struct ebt_entry *e, struct net *net,
730738
goto cleanup_watchers;
731739
}
732740

741+
/* Reject UNSPEC, xtables verdicts/return values are incompatible */
742+
if (target->family != NFPROTO_BRIDGE) {
743+
module_put(target->me);
744+
ret = -ENOENT;
745+
goto cleanup_watchers;
746+
}
747+
733748
t->u.target = target;
734749
if (t->u.target == &ebt_standard_target) {
735750
if (gap < sizeof(struct ebt_standard_target)) {
@@ -1605,16 +1620,16 @@ struct compat_ebt_entry_mwt {
16051620
compat_uptr_t ptr;
16061621
} u;
16071622
compat_uint_t match_size;
1608-
compat_uint_t data[0];
1623+
compat_uint_t data[0] __attribute__ ((aligned (__alignof__(struct compat_ebt_replace))));
16091624
};
16101625

16111626
/* account for possible padding between match_size and ->data */
16121627
static int ebt_compat_entry_padsize(void)
16131628
{
1614-
BUILD_BUG_ON(XT_ALIGN(sizeof(struct ebt_entry_match)) <
1615-
COMPAT_XT_ALIGN(sizeof(struct compat_ebt_entry_mwt)));
1616-
return (int) XT_ALIGN(sizeof(struct ebt_entry_match)) -
1617-
COMPAT_XT_ALIGN(sizeof(struct compat_ebt_entry_mwt));
1629+
BUILD_BUG_ON(sizeof(struct ebt_entry_match) <
1630+
sizeof(struct compat_ebt_entry_mwt));
1631+
return (int) sizeof(struct ebt_entry_match) -
1632+
sizeof(struct compat_ebt_entry_mwt);
16181633
}
16191634

16201635
static int ebt_compat_match_offset(const struct xt_match *match,

net/bridge/netfilter/nft_reject_bridge.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ static void nft_reject_br_send_v6_unreach(struct net *net,
261261
if (!reject6_br_csum_ok(oldskb, hook))
262262
return;
263263

264-
nskb = alloc_skb(sizeof(struct iphdr) + sizeof(struct icmp6hdr) +
264+
nskb = alloc_skb(sizeof(struct ipv6hdr) + sizeof(struct icmp6hdr) +
265265
LL_MAX_HEADER + len, GFP_ATOMIC);
266266
if (!nskb)
267267
return;

net/ipv4/netfilter/ip_tables.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,7 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name,
531531
return -ENOMEM;
532532

533533
j = 0;
534+
memset(&mtpar, 0, sizeof(mtpar));
534535
mtpar.net = net;
535536
mtpar.table = name;
536537
mtpar.entryinfo = &e->ip;

net/ipv6/netfilter/ip6_tables.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,7 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name,
550550
return -ENOMEM;
551551

552552
j = 0;
553+
memset(&mtpar, 0, sizeof(mtpar));
553554
mtpar.net = net;
554555
mtpar.table = name;
555556
mtpar.entryinfo = &e->ipv6;

net/netfilter/ipset/ip_set_hash_gen.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1234,7 +1234,10 @@ IPSET_TOKEN(HTYPE, _create)(struct net *net, struct ip_set *set,
12341234
pr_debug("Create set %s with family %s\n",
12351235
set->name, set->family == NFPROTO_IPV4 ? "inet" : "inet6");
12361236

1237-
#ifndef IP_SET_PROTO_UNDEF
1237+
#ifdef IP_SET_PROTO_UNDEF
1238+
if (set->family != NFPROTO_UNSPEC)
1239+
return -IPSET_ERR_INVALID_FAMILY;
1240+
#else
12381241
if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6))
12391242
return -IPSET_ERR_INVALID_FAMILY;
12401243
#endif

net/netfilter/ipvs/ip_vs_ctl.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,9 @@ __ip_vs_update_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest,
839839
* For now only for NAT!
840840
*/
841841
ip_vs_rs_hash(ipvs, dest);
842+
/* FTP-NAT requires conntrack for mangling */
843+
if (svc->port == FTPPORT)
844+
ip_vs_register_conntrack(svc);
842845
}
843846
atomic_set(&dest->conn_flags, conn_flags);
844847

@@ -1462,6 +1465,7 @@ static void __ip_vs_del_service(struct ip_vs_service *svc, bool cleanup)
14621465
*/
14631466
static void ip_vs_unlink_service(struct ip_vs_service *svc, bool cleanup)
14641467
{
1468+
ip_vs_unregister_conntrack(svc);
14651469
/* Hold svc to avoid double release from dest_trash */
14661470
atomic_inc(&svc->refcnt);
14671471
/*

0 commit comments

Comments
 (0)