Skip to content

Commit 23416e2

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, they are: 1) When using IPVS in direct-routing mode, normal traffic from the LVS host to a back-end server is sometimes incorrectly NATed on the way back into the LVS host. Patch to fix this from Julian Anastasov. 2) Calm down clang compilation warning in ctnetlink due to type mismatch, from Matthias Kaehlcke. 3) Do not re-setup NAT for conntracks that are already confirmed, this is fixing a problem that was introduced in the previous nf-next batch. Patch from Liping Zhang. 4) Do not allow conntrack helper removal from userspace cthelper infrastructure if already in used. This comes with an initial patch to introduce nf_conntrack_helper_put() that is required by this fix. From Liping Zhang. 5) Zero the pad when copying data to userspace, otherwise iptables fails to remove rules. This is a follow up on the patchset that sorts out the internal match/target structure pointer leak to userspace. Patch from the same author, Willem de Bruijn. This also comes with a build failure when CONFIG_COMPAT is not on, coming in the last patch of this series. 6) SYNPROXY crashes with conntrack entries that are created via ctnetlink, more specifically via conntrackd state sync. Patch from Eric Leblond. 7) RCU safe iteration on set element dumping in nf_tables, from Liping Zhang. 8) Missing sanitization of immediate date for the bitwise and cmp expressions in nf_tables. 9) Refcounting logic for chain and objects from set elements does not integrate into the nf_tables 2-phase commit protocol. 10) Missing sanitization of target verdict in ebtables arpreply target, from Gao Feng. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 8b4822d + 751a9c7 commit 23416e2

File tree

21 files changed

+249
-79
lines changed

21 files changed

+249
-79
lines changed

include/linux/netfilter/x_tables.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ int xt_match_to_user(const struct xt_entry_match *m,
294294
int xt_target_to_user(const struct xt_entry_target *t,
295295
struct xt_entry_target __user *u);
296296
int xt_data_to_user(void __user *dst, const void *src,
297-
int usersize, int size);
297+
int usersize, int size, int aligned_size);
298298

299299
void *xt_copy_counters_from_user(const void __user *user, unsigned int len,
300300
struct xt_counters_info *info, bool compat);

include/linux/netfilter_bridge/ebtables.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,4 +125,9 @@ extern unsigned int ebt_do_table(struct sk_buff *skb,
125125
/* True if the target is not a standard target */
126126
#define INVALID_TARGET (info->target < -NUM_STANDARD_TARGETS || info->target >= 0)
127127

128+
static inline bool ebt_invalid_target(int target)
129+
{
130+
return (target < -NUM_STANDARD_TARGETS || target >= 0);
131+
}
132+
128133
#endif

include/net/netfilter/nf_conntrack_helper.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#ifndef _NF_CONNTRACK_HELPER_H
1111
#define _NF_CONNTRACK_HELPER_H
12+
#include <linux/refcount.h>
1213
#include <net/netfilter/nf_conntrack.h>
1314
#include <net/netfilter/nf_conntrack_extend.h>
1415
#include <net/netfilter/nf_conntrack_expect.h>
@@ -26,6 +27,7 @@ struct nf_conntrack_helper {
2627
struct hlist_node hnode; /* Internal use. */
2728

2829
char name[NF_CT_HELPER_NAME_LEN]; /* name of the module */
30+
refcount_t refcnt;
2931
struct module *me; /* pointer to self */
3032
const struct nf_conntrack_expect_policy *expect_policy;
3133

@@ -79,6 +81,8 @@ struct nf_conntrack_helper *__nf_conntrack_helper_find(const char *name,
7981
struct nf_conntrack_helper *nf_conntrack_helper_try_module_get(const char *name,
8082
u16 l3num,
8183
u8 protonum);
84+
void nf_conntrack_helper_put(struct nf_conntrack_helper *helper);
85+
8286
void nf_ct_helper_init(struct nf_conntrack_helper *helper,
8387
u16 l3num, u16 protonum, const char *name,
8488
u16 default_port, u16 spec_port, u32 id,

include/net/netfilter/nf_tables.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ struct nft_data_desc {
176176
int nft_data_init(const struct nft_ctx *ctx,
177177
struct nft_data *data, unsigned int size,
178178
struct nft_data_desc *desc, const struct nlattr *nla);
179-
void nft_data_uninit(const struct nft_data *data, enum nft_data_types type);
179+
void nft_data_release(const struct nft_data *data, enum nft_data_types type);
180180
int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data,
181181
enum nft_data_types type, unsigned int len);
182182

net/bridge/netfilter/ebt_arpreply.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ static int ebt_arpreply_tg_check(const struct xt_tgchk_param *par)
6868
if (e->ethproto != htons(ETH_P_ARP) ||
6969
e->invflags & EBT_IPROTO)
7070
return -EINVAL;
71+
if (ebt_invalid_target(info->target))
72+
return -EINVAL;
73+
7174
return 0;
7275
}
7376

net/bridge/netfilter/ebtables.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,7 +1373,8 @@ static inline int ebt_obj_to_user(char __user *um, const char *_name,
13731373
strlcpy(name, _name, sizeof(name));
13741374
if (copy_to_user(um, name, EBT_FUNCTION_MAXNAMELEN) ||
13751375
put_user(datasize, (int __user *)(um + EBT_FUNCTION_MAXNAMELEN)) ||
1376-
xt_data_to_user(um + entrysize, data, usersize, datasize))
1376+
xt_data_to_user(um + entrysize, data, usersize, datasize,
1377+
XT_ALIGN(datasize)))
13771378
return -EFAULT;
13781379

13791380
return 0;
@@ -1658,7 +1659,8 @@ static int compat_match_to_user(struct ebt_entry_match *m, void __user **dstptr,
16581659
if (match->compat_to_user(cm->data, m->data))
16591660
return -EFAULT;
16601661
} else {
1661-
if (xt_data_to_user(cm->data, m->data, match->usersize, msize))
1662+
if (xt_data_to_user(cm->data, m->data, match->usersize, msize,
1663+
COMPAT_XT_ALIGN(msize)))
16621664
return -EFAULT;
16631665
}
16641666

@@ -1687,7 +1689,8 @@ static int compat_target_to_user(struct ebt_entry_target *t,
16871689
if (target->compat_to_user(cm->data, t->data))
16881690
return -EFAULT;
16891691
} else {
1690-
if (xt_data_to_user(cm->data, t->data, target->usersize, tsize))
1692+
if (xt_data_to_user(cm->data, t->data, target->usersize, tsize,
1693+
COMPAT_XT_ALIGN(tsize)))
16911694
return -EFAULT;
16921695
}
16931696

net/netfilter/ipvs/ip_vs_core.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -849,10 +849,8 @@ static int handle_response_icmp(int af, struct sk_buff *skb,
849849
{
850850
unsigned int verdict = NF_DROP;
851851

852-
if (IP_VS_FWD_METHOD(cp) != 0) {
853-
pr_err("shouldn't reach here, because the box is on the "
854-
"half connection in the tun/dr module.\n");
855-
}
852+
if (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ)
853+
goto ignore_cp;
856854

857855
/* Ensure the checksum is correct */
858856
if (!skb_csum_unnecessary(skb) && ip_vs_checksum_complete(skb, ihl)) {
@@ -886,6 +884,8 @@ static int handle_response_icmp(int af, struct sk_buff *skb,
886884
ip_vs_notrack(skb);
887885
else
888886
ip_vs_update_conntrack(skb, cp, 0);
887+
888+
ignore_cp:
889889
verdict = NF_ACCEPT;
890890

891891
out:
@@ -1385,8 +1385,11 @@ ip_vs_out(struct netns_ipvs *ipvs, unsigned int hooknum, struct sk_buff *skb, in
13851385
*/
13861386
cp = pp->conn_out_get(ipvs, af, skb, &iph);
13871387

1388-
if (likely(cp))
1388+
if (likely(cp)) {
1389+
if (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ)
1390+
goto ignore_cp;
13891391
return handle_response(af, skb, pd, cp, &iph, hooknum);
1392+
}
13901393

13911394
/* Check for real-server-started requests */
13921395
if (atomic_read(&ipvs->conn_out_counter)) {
@@ -1444,9 +1447,15 @@ ip_vs_out(struct netns_ipvs *ipvs, unsigned int hooknum, struct sk_buff *skb, in
14441447
}
14451448
}
14461449
}
1450+
1451+
out:
14471452
IP_VS_DBG_PKT(12, af, pp, skb, iph.off,
14481453
"ip_vs_out: packet continues traversal as normal");
14491454
return NF_ACCEPT;
1455+
1456+
ignore_cp:
1457+
__ip_vs_conn_put(cp);
1458+
goto out;
14501459
}
14511460

14521461
/*

net/netfilter/nf_conntrack_helper.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,13 +174,24 @@ nf_conntrack_helper_try_module_get(const char *name, u16 l3num, u8 protonum)
174174
#endif
175175
if (h != NULL && !try_module_get(h->me))
176176
h = NULL;
177+
if (h != NULL && !refcount_inc_not_zero(&h->refcnt)) {
178+
module_put(h->me);
179+
h = NULL;
180+
}
177181

178182
rcu_read_unlock();
179183

180184
return h;
181185
}
182186
EXPORT_SYMBOL_GPL(nf_conntrack_helper_try_module_get);
183187

188+
void nf_conntrack_helper_put(struct nf_conntrack_helper *helper)
189+
{
190+
refcount_dec(&helper->refcnt);
191+
module_put(helper->me);
192+
}
193+
EXPORT_SYMBOL_GPL(nf_conntrack_helper_put);
194+
184195
struct nf_conn_help *
185196
nf_ct_helper_ext_add(struct nf_conn *ct,
186197
struct nf_conntrack_helper *helper, gfp_t gfp)
@@ -417,6 +428,7 @@ int nf_conntrack_helper_register(struct nf_conntrack_helper *me)
417428
}
418429
}
419430
}
431+
refcount_set(&me->refcnt, 1);
420432
hlist_add_head_rcu(&me->hnode, &nf_ct_helper_hash[h]);
421433
nf_ct_helper_count++;
422434
out:

net/netfilter/nf_conntrack_netlink.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
#include <net/netfilter/nf_conntrack_zones.h>
4646
#include <net/netfilter/nf_conntrack_timestamp.h>
4747
#include <net/netfilter/nf_conntrack_labels.h>
48+
#include <net/netfilter/nf_conntrack_seqadj.h>
49+
#include <net/netfilter/nf_conntrack_synproxy.h>
4850
#ifdef CONFIG_NF_NAT_NEEDED
4951
#include <net/netfilter/nf_nat_core.h>
5052
#include <net/netfilter/nf_nat_l4proto.h>
@@ -1007,9 +1009,8 @@ static const struct nla_policy tuple_nla_policy[CTA_TUPLE_MAX+1] = {
10071009

10081010
static int
10091011
ctnetlink_parse_tuple(const struct nlattr * const cda[],
1010-
struct nf_conntrack_tuple *tuple,
1011-
enum ctattr_type type, u_int8_t l3num,
1012-
struct nf_conntrack_zone *zone)
1012+
struct nf_conntrack_tuple *tuple, u32 type,
1013+
u_int8_t l3num, struct nf_conntrack_zone *zone)
10131014
{
10141015
struct nlattr *tb[CTA_TUPLE_MAX+1];
10151016
int err;
@@ -1828,6 +1829,8 @@ ctnetlink_create_conntrack(struct net *net,
18281829
nf_ct_tstamp_ext_add(ct, GFP_ATOMIC);
18291830
nf_ct_ecache_ext_add(ct, 0, 0, GFP_ATOMIC);
18301831
nf_ct_labels_ext_add(ct);
1832+
nfct_seqadj_ext_add(ct);
1833+
nfct_synproxy_ext_add(ct);
18311834

18321835
/* we must add conntrack extensions before confirmation. */
18331836
ct->status |= IPS_CONFIRMED;
@@ -2447,7 +2450,7 @@ static struct nfnl_ct_hook ctnetlink_glue_hook = {
24472450

24482451
static int ctnetlink_exp_dump_tuple(struct sk_buff *skb,
24492452
const struct nf_conntrack_tuple *tuple,
2450-
enum ctattr_expect type)
2453+
u32 type)
24512454
{
24522455
struct nlattr *nest_parms;
24532456

net/netfilter/nf_nat_core.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,10 @@ nf_nat_setup_info(struct nf_conn *ct,
409409
{
410410
struct nf_conntrack_tuple curr_tuple, new_tuple;
411411

412+
/* Can't setup nat info for confirmed ct. */
413+
if (nf_ct_is_confirmed(ct))
414+
return NF_ACCEPT;
415+
412416
NF_CT_ASSERT(maniptype == NF_NAT_MANIP_SRC ||
413417
maniptype == NF_NAT_MANIP_DST);
414418
BUG_ON(nf_nat_initialized(ct, maniptype));

0 commit comments

Comments
 (0)