aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2012-09-03 09:28:30 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2012-09-03 09:34:51 -0400
commitace1fe1231bdfffd60b5e703aa5b7283fbf98dbd (patch)
tree06c7492a8f3cc65f916768616ca24c6bc7171761 /net/netfilter
parentce9f3f31efb88841e4df98794b13dbac8c4901da (diff)
parenta2dc375e12334b3d8f787a48b2fb6172ccfb80ae (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
This merges (3f509c6 netfilter: nf_nat_sip: fix incorrect handling of EBUSY for RTCP expectation) to Patrick McHardy's IPv6 NAT changes.
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/ipvs/ip_vs_ctl.c4
-rw-r--r--net/netfilter/nf_conntrack_core.c16
-rw-r--r--net/netfilter/nf_conntrack_netlink.c3
-rw-r--r--net/netfilter/nf_nat_sip.c5
-rw-r--r--net/netfilter/nfnetlink_log.c20
-rw-r--r--net/netfilter/xt_LOG.c16
-rw-r--r--net/netfilter/xt_owner.c30
-rw-r--r--net/netfilter/xt_recent.c13
8 files changed, 79 insertions, 28 deletions
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 3c601378d27e..767cc12da0fe 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -1171,8 +1171,10 @@ ip_vs_add_service(struct net *net, struct ip_vs_service_user_kern *u,
1171 goto out_err; 1171 goto out_err;
1172 } 1172 }
1173 svc->stats.cpustats = alloc_percpu(struct ip_vs_cpu_stats); 1173 svc->stats.cpustats = alloc_percpu(struct ip_vs_cpu_stats);
1174 if (!svc->stats.cpustats) 1174 if (!svc->stats.cpustats) {
1175 ret = -ENOMEM;
1175 goto out_err; 1176 goto out_err;
1177 }
1176 1178
1177 /* I'm the first user of the service */ 1179 /* I'm the first user of the service */
1178 atomic_set(&svc->usecnt, 0); 1180 atomic_set(&svc->usecnt, 0);
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index c9bb994ae9ba..dcb27910ab3c 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -255,12 +255,15 @@ static void death_by_event(unsigned long ul_conntrack)
255{ 255{
256 struct nf_conn *ct = (void *)ul_conntrack; 256 struct nf_conn *ct = (void *)ul_conntrack;
257 struct net *net = nf_ct_net(ct); 257 struct net *net = nf_ct_net(ct);
258 struct nf_conntrack_ecache *ecache = nf_ct_ecache_find(ct);
259
260 BUG_ON(ecache == NULL);
258 261
259 if (nf_conntrack_event(IPCT_DESTROY, ct) < 0) { 262 if (nf_conntrack_event(IPCT_DESTROY, ct) < 0) {
260 /* bad luck, let's retry again */ 263 /* bad luck, let's retry again */
261 ct->timeout.expires = jiffies + 264 ecache->timeout.expires = jiffies +
262 (random32() % net->ct.sysctl_events_retry_timeout); 265 (random32() % net->ct.sysctl_events_retry_timeout);
263 add_timer(&ct->timeout); 266 add_timer(&ecache->timeout);
264 return; 267 return;
265 } 268 }
266 /* we've got the event delivered, now it's dying */ 269 /* we've got the event delivered, now it's dying */
@@ -274,6 +277,9 @@ static void death_by_event(unsigned long ul_conntrack)
274void nf_ct_insert_dying_list(struct nf_conn *ct) 277void nf_ct_insert_dying_list(struct nf_conn *ct)
275{ 278{
276 struct net *net = nf_ct_net(ct); 279 struct net *net = nf_ct_net(ct);
280 struct nf_conntrack_ecache *ecache = nf_ct_ecache_find(ct);
281
282 BUG_ON(ecache == NULL);
277 283
278 /* add this conntrack to the dying list */ 284 /* add this conntrack to the dying list */
279 spin_lock_bh(&nf_conntrack_lock); 285 spin_lock_bh(&nf_conntrack_lock);
@@ -281,10 +287,10 @@ void nf_ct_insert_dying_list(struct nf_conn *ct)
281 &net->ct.dying); 287 &net->ct.dying);
282 spin_unlock_bh(&nf_conntrack_lock); 288 spin_unlock_bh(&nf_conntrack_lock);
283 /* set a new timer to retry event delivery */ 289 /* set a new timer to retry event delivery */
284 setup_timer(&ct->timeout, death_by_event, (unsigned long)ct); 290 setup_timer(&ecache->timeout, death_by_event, (unsigned long)ct);
285 ct->timeout.expires = jiffies + 291 ecache->timeout.expires = jiffies +
286 (random32() % net->ct.sysctl_events_retry_timeout); 292 (random32() % net->ct.sysctl_events_retry_timeout);
287 add_timer(&ct->timeout); 293 add_timer(&ecache->timeout);
288} 294}
289EXPORT_SYMBOL_GPL(nf_ct_insert_dying_list); 295EXPORT_SYMBOL_GPL(nf_ct_insert_dying_list);
290 296
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 966f5133a384..a205bd6ce294 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -2813,7 +2813,8 @@ static int __init ctnetlink_init(void)
2813 goto err_unreg_subsys; 2813 goto err_unreg_subsys;
2814 } 2814 }
2815 2815
2816 if (register_pernet_subsys(&ctnetlink_net_ops)) { 2816 ret = register_pernet_subsys(&ctnetlink_net_ops);
2817 if (ret < 0) {
2817 pr_err("ctnetlink_init: cannot register pernet operations\n"); 2818 pr_err("ctnetlink_init: cannot register pernet operations\n");
2818 goto err_unreg_exp_subsys; 2819 goto err_unreg_exp_subsys;
2819 } 2820 }
diff --git a/net/netfilter/nf_nat_sip.c b/net/netfilter/nf_nat_sip.c
index f4db3a7bd285..16303c752213 100644
--- a/net/netfilter/nf_nat_sip.c
+++ b/net/netfilter/nf_nat_sip.c
@@ -542,7 +542,10 @@ static unsigned int nf_nat_sdp_media(struct sk_buff *skb, unsigned int protoff,
542 ret = nf_ct_expect_related(rtcp_exp); 542 ret = nf_ct_expect_related(rtcp_exp);
543 if (ret == 0) 543 if (ret == 0)
544 break; 544 break;
545 else if (ret != -EBUSY) { 545 else if (ret == -EBUSY) {
546 nf_ct_unexpect_related(rtp_exp);
547 continue;
548 } else if (ret < 0) {
546 nf_ct_unexpect_related(rtp_exp); 549 nf_ct_unexpect_related(rtp_exp);
547 port = 0; 550 port = 0;
548 break; 551 break;
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 169ab59ed9d4..be194b144297 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -55,6 +55,7 @@ struct nfulnl_instance {
55 unsigned int qlen; /* number of nlmsgs in skb */ 55 unsigned int qlen; /* number of nlmsgs in skb */
56 struct sk_buff *skb; /* pre-allocatd skb */ 56 struct sk_buff *skb; /* pre-allocatd skb */
57 struct timer_list timer; 57 struct timer_list timer;
58 struct user_namespace *peer_user_ns; /* User namespace of the peer process */
58 int peer_pid; /* PID of the peer process */ 59 int peer_pid; /* PID of the peer process */
59 60
60 /* configurable parameters */ 61 /* configurable parameters */
@@ -132,7 +133,7 @@ instance_put(struct nfulnl_instance *inst)
132static void nfulnl_timer(unsigned long data); 133static void nfulnl_timer(unsigned long data);
133 134
134static struct nfulnl_instance * 135static struct nfulnl_instance *
135instance_create(u_int16_t group_num, int pid) 136instance_create(u_int16_t group_num, int pid, struct user_namespace *user_ns)
136{ 137{
137 struct nfulnl_instance *inst; 138 struct nfulnl_instance *inst;
138 int err; 139 int err;
@@ -162,6 +163,7 @@ instance_create(u_int16_t group_num, int pid)
162 163
163 setup_timer(&inst->timer, nfulnl_timer, (unsigned long)inst); 164 setup_timer(&inst->timer, nfulnl_timer, (unsigned long)inst);
164 165
166 inst->peer_user_ns = user_ns;
165 inst->peer_pid = pid; 167 inst->peer_pid = pid;
166 inst->group_num = group_num; 168 inst->group_num = group_num;
167 169
@@ -480,7 +482,7 @@ __build_packet_message(struct nfulnl_instance *inst,
480 } 482 }
481 483
482 if (indev && skb_mac_header_was_set(skb)) { 484 if (indev && skb_mac_header_was_set(skb)) {
483 if (nla_put_be32(inst->skb, NFULA_HWTYPE, htons(skb->dev->type)) || 485 if (nla_put_be16(inst->skb, NFULA_HWTYPE, htons(skb->dev->type)) ||
484 nla_put_be16(inst->skb, NFULA_HWLEN, 486 nla_put_be16(inst->skb, NFULA_HWLEN,
485 htons(skb->dev->hard_header_len)) || 487 htons(skb->dev->hard_header_len)) ||
486 nla_put(inst->skb, NFULA_HWHEADER, skb->dev->hard_header_len, 488 nla_put(inst->skb, NFULA_HWHEADER, skb->dev->hard_header_len,
@@ -503,8 +505,11 @@ __build_packet_message(struct nfulnl_instance *inst,
503 read_lock_bh(&skb->sk->sk_callback_lock); 505 read_lock_bh(&skb->sk->sk_callback_lock);
504 if (skb->sk->sk_socket && skb->sk->sk_socket->file) { 506 if (skb->sk->sk_socket && skb->sk->sk_socket->file) {
505 struct file *file = skb->sk->sk_socket->file; 507 struct file *file = skb->sk->sk_socket->file;
506 __be32 uid = htonl(file->f_cred->fsuid); 508 __be32 uid = htonl(from_kuid_munged(inst->peer_user_ns,
507 __be32 gid = htonl(file->f_cred->fsgid); 509 file->f_cred->fsuid));
510 __be32 gid = htonl(from_kgid_munged(inst->peer_user_ns,
511 file->f_cred->fsgid));
512 /* need to unlock here since NLA_PUT may goto */
508 read_unlock_bh(&skb->sk->sk_callback_lock); 513 read_unlock_bh(&skb->sk->sk_callback_lock);
509 if (nla_put_be32(inst->skb, NFULA_UID, uid) || 514 if (nla_put_be32(inst->skb, NFULA_UID, uid) ||
510 nla_put_be32(inst->skb, NFULA_GID, gid)) 515 nla_put_be32(inst->skb, NFULA_GID, gid))
@@ -783,7 +788,8 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
783 } 788 }
784 789
785 inst = instance_create(group_num, 790 inst = instance_create(group_num,
786 NETLINK_CB(skb).pid); 791 NETLINK_CB(skb).pid,
792 sk_user_ns(NETLINK_CB(skb).ssk));
787 if (IS_ERR(inst)) { 793 if (IS_ERR(inst)) {
788 ret = PTR_ERR(inst); 794 ret = PTR_ERR(inst);
789 goto out; 795 goto out;
@@ -996,8 +1002,10 @@ static int __init nfnetlink_log_init(void)
996 1002
997#ifdef CONFIG_PROC_FS 1003#ifdef CONFIG_PROC_FS
998 if (!proc_create("nfnetlink_log", 0440, 1004 if (!proc_create("nfnetlink_log", 0440,
999 proc_net_netfilter, &nful_file_ops)) 1005 proc_net_netfilter, &nful_file_ops)) {
1006 status = -ENOMEM;
1000 goto cleanup_logger; 1007 goto cleanup_logger;
1008 }
1001#endif 1009#endif
1002 return status; 1010 return status;
1003 1011
diff --git a/net/netfilter/xt_LOG.c b/net/netfilter/xt_LOG.c
index ff5f75fddb15..02a2bf49dcbd 100644
--- a/net/netfilter/xt_LOG.c
+++ b/net/netfilter/xt_LOG.c
@@ -363,10 +363,12 @@ static void dump_ipv4_packet(struct sbuff *m,
363 /* Max length: 15 "UID=4294967295 " */ 363 /* Max length: 15 "UID=4294967295 " */
364 if ((logflags & XT_LOG_UID) && !iphoff && skb->sk) { 364 if ((logflags & XT_LOG_UID) && !iphoff && skb->sk) {
365 read_lock_bh(&skb->sk->sk_callback_lock); 365 read_lock_bh(&skb->sk->sk_callback_lock);
366 if (skb->sk->sk_socket && skb->sk->sk_socket->file) 366 if (skb->sk->sk_socket && skb->sk->sk_socket->file) {
367 const struct cred *cred = skb->sk->sk_socket->file->f_cred;
367 sb_add(m, "UID=%u GID=%u ", 368 sb_add(m, "UID=%u GID=%u ",
368 skb->sk->sk_socket->file->f_cred->fsuid, 369 from_kuid_munged(&init_user_ns, cred->fsuid),
369 skb->sk->sk_socket->file->f_cred->fsgid); 370 from_kgid_munged(&init_user_ns, cred->fsgid));
371 }
370 read_unlock_bh(&skb->sk->sk_callback_lock); 372 read_unlock_bh(&skb->sk->sk_callback_lock);
371 } 373 }
372 374
@@ -719,10 +721,12 @@ static void dump_ipv6_packet(struct sbuff *m,
719 /* Max length: 15 "UID=4294967295 " */ 721 /* Max length: 15 "UID=4294967295 " */
720 if ((logflags & XT_LOG_UID) && recurse && skb->sk) { 722 if ((logflags & XT_LOG_UID) && recurse && skb->sk) {
721 read_lock_bh(&skb->sk->sk_callback_lock); 723 read_lock_bh(&skb->sk->sk_callback_lock);
722 if (skb->sk->sk_socket && skb->sk->sk_socket->file) 724 if (skb->sk->sk_socket && skb->sk->sk_socket->file) {
725 const struct cred *cred = skb->sk->sk_socket->file->f_cred;
723 sb_add(m, "UID=%u GID=%u ", 726 sb_add(m, "UID=%u GID=%u ",
724 skb->sk->sk_socket->file->f_cred->fsuid, 727 from_kuid_munged(&init_user_ns, cred->fsuid),
725 skb->sk->sk_socket->file->f_cred->fsgid); 728 from_kgid_munged(&init_user_ns, cred->fsgid));
729 }
726 read_unlock_bh(&skb->sk->sk_callback_lock); 730 read_unlock_bh(&skb->sk->sk_callback_lock);
727 } 731 }
728 732
diff --git a/net/netfilter/xt_owner.c b/net/netfilter/xt_owner.c
index 772d7389b337..ca2e577ed8ac 100644
--- a/net/netfilter/xt_owner.c
+++ b/net/netfilter/xt_owner.c
@@ -17,6 +17,17 @@
17#include <linux/netfilter/x_tables.h> 17#include <linux/netfilter/x_tables.h>
18#include <linux/netfilter/xt_owner.h> 18#include <linux/netfilter/xt_owner.h>
19 19
20static int owner_check(const struct xt_mtchk_param *par)
21{
22 struct xt_owner_match_info *info = par->matchinfo;
23
24 /* For now only allow adding matches from the initial user namespace */
25 if ((info->match & (XT_OWNER_UID|XT_OWNER_GID)) &&
26 (current_user_ns() != &init_user_ns))
27 return -EINVAL;
28 return 0;
29}
30
20static bool 31static bool
21owner_mt(const struct sk_buff *skb, struct xt_action_param *par) 32owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
22{ 33{
@@ -37,17 +48,23 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
37 return ((info->match ^ info->invert) & 48 return ((info->match ^ info->invert) &
38 (XT_OWNER_UID | XT_OWNER_GID)) == 0; 49 (XT_OWNER_UID | XT_OWNER_GID)) == 0;
39 50
40 if (info->match & XT_OWNER_UID) 51 if (info->match & XT_OWNER_UID) {
41 if ((filp->f_cred->fsuid >= info->uid_min && 52 kuid_t uid_min = make_kuid(&init_user_ns, info->uid_min);
42 filp->f_cred->fsuid <= info->uid_max) ^ 53 kuid_t uid_max = make_kuid(&init_user_ns, info->uid_max);
54 if ((uid_gte(filp->f_cred->fsuid, uid_min) &&
55 uid_lte(filp->f_cred->fsuid, uid_max)) ^
43 !(info->invert & XT_OWNER_UID)) 56 !(info->invert & XT_OWNER_UID))
44 return false; 57 return false;
58 }
45 59
46 if (info->match & XT_OWNER_GID) 60 if (info->match & XT_OWNER_GID) {
47 if ((filp->f_cred->fsgid >= info->gid_min && 61 kgid_t gid_min = make_kgid(&init_user_ns, info->gid_min);
48 filp->f_cred->fsgid <= info->gid_max) ^ 62 kgid_t gid_max = make_kgid(&init_user_ns, info->gid_max);
63 if ((gid_gte(filp->f_cred->fsgid, gid_min) &&
64 gid_lte(filp->f_cred->fsgid, gid_max)) ^
49 !(info->invert & XT_OWNER_GID)) 65 !(info->invert & XT_OWNER_GID))
50 return false; 66 return false;
67 }
51 68
52 return true; 69 return true;
53} 70}
@@ -56,6 +73,7 @@ static struct xt_match owner_mt_reg __read_mostly = {
56 .name = "owner", 73 .name = "owner",
57 .revision = 1, 74 .revision = 1,
58 .family = NFPROTO_UNSPEC, 75 .family = NFPROTO_UNSPEC,
76 .checkentry = owner_check,
59 .match = owner_mt, 77 .match = owner_mt,
60 .matchsize = sizeof(struct xt_owner_match_info), 78 .matchsize = sizeof(struct xt_owner_match_info),
61 .hooks = (1 << NF_INET_LOCAL_OUT) | 79 .hooks = (1 << NF_INET_LOCAL_OUT) |
diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c
index ae2ad1eec8d0..4635c9b00459 100644
--- a/net/netfilter/xt_recent.c
+++ b/net/netfilter/xt_recent.c
@@ -317,6 +317,8 @@ static int recent_mt_check(const struct xt_mtchk_param *par,
317 struct recent_table *t; 317 struct recent_table *t;
318#ifdef CONFIG_PROC_FS 318#ifdef CONFIG_PROC_FS
319 struct proc_dir_entry *pde; 319 struct proc_dir_entry *pde;
320 kuid_t uid;
321 kgid_t gid;
320#endif 322#endif
321 unsigned int i; 323 unsigned int i;
322 int ret = -EINVAL; 324 int ret = -EINVAL;
@@ -372,6 +374,13 @@ static int recent_mt_check(const struct xt_mtchk_param *par,
372 for (i = 0; i < ip_list_hash_size; i++) 374 for (i = 0; i < ip_list_hash_size; i++)
373 INIT_LIST_HEAD(&t->iphash[i]); 375 INIT_LIST_HEAD(&t->iphash[i]);
374#ifdef CONFIG_PROC_FS 376#ifdef CONFIG_PROC_FS
377 uid = make_kuid(&init_user_ns, ip_list_uid);
378 gid = make_kgid(&init_user_ns, ip_list_gid);
379 if (!uid_valid(uid) || !gid_valid(gid)) {
380 kfree(t);
381 ret = -EINVAL;
382 goto out;
383 }
375 pde = proc_create_data(t->name, ip_list_perms, recent_net->xt_recent, 384 pde = proc_create_data(t->name, ip_list_perms, recent_net->xt_recent,
376 &recent_mt_fops, t); 385 &recent_mt_fops, t);
377 if (pde == NULL) { 386 if (pde == NULL) {
@@ -379,8 +388,8 @@ static int recent_mt_check(const struct xt_mtchk_param *par,
379 ret = -ENOMEM; 388 ret = -ENOMEM;
380 goto out; 389 goto out;
381 } 390 }
382 pde->uid = ip_list_uid; 391 pde->uid = uid;
383 pde->gid = ip_list_gid; 392 pde->gid = gid;
384#endif 393#endif
385 spin_lock_bh(&recent_lock); 394 spin_lock_bh(&recent_lock);
386 list_add_tail(&t->list, &recent_net->tables); 395 list_add_tail(&t->list, &recent_net->tables);