* [PATCH v3 1/3] netfilter: log: protect nf_log_register against double registering
@ 2014-10-29 12:04 Marcelo Ricardo Leitner
2014-10-29 12:04 ` [PATCH v3 2/3] Do error handling if __build_packet_message fails Marcelo Ricardo Leitner
2014-10-29 12:04 ` [PATCH v3 3/3] Make use of pr_fmt where applicable Marcelo Ricardo Leitner
0 siblings, 2 replies; 4+ messages in thread
From: Marcelo Ricardo Leitner @ 2014-10-29 12:04 UTC (permalink / raw)
To: netfilter-devel
Currently, despite the comment right before the function,
nf_log_register allows registering two loggers on with the same type and
end up overwriting the previous register.
Not a real issue today as current tree doesn't have two loggers for the
same type but it's better to get this protected.
Also make sure that all of its callers do error checking.
Signed-off-by: Marcelo Ricardo Leitner <mleitner@redhat.com>
---
net/ipv4/netfilter/nf_log_arp.c | 12 +++++++++++-
net/ipv4/netfilter/nf_log_ipv4.c | 12 +++++++++++-
net/ipv6/netfilter/nf_log_ipv6.c | 12 +++++++++++-
net/netfilter/nf_log.c | 16 +++++++++++++---
4 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/net/ipv4/netfilter/nf_log_arp.c b/net/ipv4/netfilter/nf_log_arp.c
index ccfc78db12ee8acae68faf451f2cf6bc5597f2c1..0c8799a0c9e46df1bd414251c4d5661da024fae1 100644
--- a/net/ipv4/netfilter/nf_log_arp.c
+++ b/net/ipv4/netfilter/nf_log_arp.c
@@ -10,6 +10,7 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/spinlock.h>
@@ -130,8 +131,17 @@ static int __init nf_log_arp_init(void)
if (ret < 0)
return ret;
- nf_log_register(NFPROTO_ARP, &nf_arp_logger);
+ ret = nf_log_register(NFPROTO_ARP, &nf_arp_logger);
+ if (ret < 0) {
+ pr_err("failed to register logger\n");
+ goto err1;
+ }
+
return 0;
+
+err1:
+ unregister_pernet_subsys(&nf_log_arp_net_ops);
+ return ret;
}
static void __exit nf_log_arp_exit(void)
diff --git a/net/ipv4/netfilter/nf_log_ipv4.c b/net/ipv4/netfilter/nf_log_ipv4.c
index 078bdca1b607a167e05e7cf1bdfedccdd5aca92a..75101980eeee197a4f8413bbd7d29f4fd9e4bb74 100644
--- a/net/ipv4/netfilter/nf_log_ipv4.c
+++ b/net/ipv4/netfilter/nf_log_ipv4.c
@@ -5,6 +5,7 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/spinlock.h>
@@ -366,8 +367,17 @@ static int __init nf_log_ipv4_init(void)
if (ret < 0)
return ret;
- nf_log_register(NFPROTO_IPV4, &nf_ip_logger);
+ ret = nf_log_register(NFPROTO_IPV4, &nf_ip_logger);
+ if (ret < 0) {
+ pr_err("failed to register logger\n");
+ goto err1;
+ }
+
return 0;
+
+err1:
+ unregister_pernet_subsys(&nf_log_ipv4_net_ops);
+ return ret;
}
static void __exit nf_log_ipv4_exit(void)
diff --git a/net/ipv6/netfilter/nf_log_ipv6.c b/net/ipv6/netfilter/nf_log_ipv6.c
index 7b17a0be93e7eccb2a26cd3294713d0f1112158d..7fc34d1681a195ff071406811771b8327337db22 100644
--- a/net/ipv6/netfilter/nf_log_ipv6.c
+++ b/net/ipv6/netfilter/nf_log_ipv6.c
@@ -5,6 +5,7 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/spinlock.h>
@@ -398,8 +399,17 @@ static int __init nf_log_ipv6_init(void)
if (ret < 0)
return ret;
- nf_log_register(NFPROTO_IPV6, &nf_ip6_logger);
+ ret = nf_log_register(NFPROTO_IPV6, &nf_ip6_logger);
+ if (ret < 0) {
+ pr_err("failed to register logger\n");
+ goto err1;
+ }
+
return 0;
+
+err1:
+ unregister_pernet_subsys(&nf_log_ipv6_net_ops);
+ return ret;
}
static void __exit nf_log_ipv6_exit(void)
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
index 5eaf047ed37facad0df59e70428c08ef8717a70d..9562e393fdf7e178b0c48bff25ace88495c2224f 100644
--- a/net/netfilter/nf_log.c
+++ b/net/netfilter/nf_log.c
@@ -75,6 +75,7 @@ EXPORT_SYMBOL(nf_log_unset);
int nf_log_register(u_int8_t pf, struct nf_logger *logger)
{
int i;
+ int ret = 0;
if (pf >= ARRAY_SIZE(init_net.nf.nf_loggers))
return -EINVAL;
@@ -82,16 +83,25 @@ int nf_log_register(u_int8_t pf, struct nf_logger *logger)
mutex_lock(&nf_log_mutex);
if (pf == NFPROTO_UNSPEC) {
+ for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++) {
+ if (rcu_access_pointer(loggers[i][logger->type])) {
+ ret = -EEXIST;
+ goto unlock;
+ }
+ }
for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++)
rcu_assign_pointer(loggers[i][logger->type], logger);
} else {
- /* register at end of list to honor first register win */
+ if (rcu_access_pointer(loggers[pf][logger->type])) {
+ ret = -EEXIST;
+ goto unlock;
+ }
rcu_assign_pointer(loggers[pf][logger->type], logger);
}
+unlock:
mutex_unlock(&nf_log_mutex);
-
- return 0;
+ return ret;
}
EXPORT_SYMBOL(nf_log_register);
--
1.9.3
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v3 2/3] Do error handling if __build_packet_message fails
2014-10-29 12:04 [PATCH v3 1/3] netfilter: log: protect nf_log_register against double registering Marcelo Ricardo Leitner
@ 2014-10-29 12:04 ` Marcelo Ricardo Leitner
2014-10-29 12:46 ` Marcelo Ricardo Leitner
2014-10-29 12:04 ` [PATCH v3 3/3] Make use of pr_fmt where applicable Marcelo Ricardo Leitner
1 sibling, 1 reply; 4+ messages in thread
From: Marcelo Ricardo Leitner @ 2014-10-29 12:04 UTC (permalink / raw)
To: netfilter-devel
Currently, we don't check if __build_packet_message fails or not and
that leaves it prone to sending incomplete messages to userspace.
This commit fixes it by canceling the new message if there was any issue
while building it and makes sure the skb is freed if it was the only
messsage in it.
Signed-off-by: Marcelo Ricardo Leitner <mleitner@redhat.com>
---
net/netfilter/nfnetlink_log.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index b1e3a05794169283ed50d1c0fb4f44d9e7753eeb..05184a3d860885c10c3e977fdc47fb86e3528afa 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -568,10 +568,8 @@ __build_packet_message(struct nfnl_log_net *log,
struct nlattr *nla;
int size = nla_attr_size(data_len);
- if (skb_tailroom(inst->skb) < nla_total_size(data_len)) {
- printk(KERN_WARNING "nfnetlink_log: no tailroom!\n");
- return -1;
- }
+ if (skb_tailroom(inst->skb) < nla_total_size(data_len))
+ goto nla_put_failure;
nla = (struct nlattr *)skb_put(inst->skb, nla_total_size(data_len));
nla->nla_type = NFULA_PAYLOAD;
@@ -586,6 +584,7 @@ __build_packet_message(struct nfnl_log_net *log,
nla_put_failure:
PRINTR(KERN_ERR "nfnetlink_log: error creating log nlmsg\n");
+ nlmsg_cancel(skb, nlh);
return -1;
}
@@ -708,8 +707,9 @@ nfulnl_log_packet(struct net *net,
inst->qlen++;
- __build_packet_message(log, inst, skb, data_len, pf,
- hooknum, in, out, prefix, plen);
+ if (__build_packet_message(log, inst, skb, data_len, pf,
+ hooknum, in, out, prefix, plen))
+ goto build_failure;
if (inst->qlen >= qthreshold)
__nfulnl_flush(inst);
@@ -726,6 +726,15 @@ unlock_and_release:
instance_put(inst);
return;
+build_failure:
+ /* If no other messages in it, we're good to free it. */
+ if (!inst->skb->len) {
+ kfree_skb(inst->skb);
+ inst->skb = NULL;
+ }
+
+ inst->qlen--;
+
alloc_failure:
/* FIXME: statistics */
goto unlock_and_release;
--
1.9.3
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v3 3/3] Make use of pr_fmt where applicable
2014-10-29 12:04 [PATCH v3 1/3] netfilter: log: protect nf_log_register against double registering Marcelo Ricardo Leitner
2014-10-29 12:04 ` [PATCH v3 2/3] Do error handling if __build_packet_message fails Marcelo Ricardo Leitner
@ 2014-10-29 12:04 ` Marcelo Ricardo Leitner
1 sibling, 0 replies; 4+ messages in thread
From: Marcelo Ricardo Leitner @ 2014-10-29 12:04 UTC (permalink / raw)
To: netfilter-devel
And also remove PRINTR macro, as it was used only once, wasn't helping
much and was actually making it harder to use pr_err().
Signed-off-by: Marcelo Ricardo Leitner <mleitner@redhat.com>
---
net/netfilter/nfnetlink_log.c | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 05184a3d860885c10c3e977fdc47fb86e3528afa..cf496c7a6bccd1b748e996fb4f8d07be6408dab9 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -12,6 +12,8 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/if_arp.h>
@@ -45,9 +47,6 @@
#define NFULNL_QTHRESH_DEFAULT 100 /* 100 packets */
#define NFULNL_COPY_RANGE_MAX 0xFFFF /* max packet size is limited by 16-bit struct nfattr nfa_len field */
-#define PRINTR(x, args...) do { if (net_ratelimit()) \
- printk(x, ## args); } while (0);
-
struct nfulnl_instance {
struct hlist_node hlist; /* global list of instances */
spinlock_t lock;
@@ -335,8 +334,7 @@ nfulnl_alloc_skb(struct net *net, u32 peer_portid, unsigned int inst_size,
skb = nfnetlink_alloc_skb(net, pkt_size,
peer_portid, GFP_ATOMIC);
if (!skb)
- pr_err("nfnetlink_log: can't even alloc %u bytes\n",
- pkt_size);
+ pr_err("can't even alloc %u bytes\n", pkt_size);
}
}
@@ -583,7 +581,6 @@ __build_packet_message(struct nfnl_log_net *log,
return 0;
nla_put_failure:
- PRINTR(KERN_ERR "nfnetlink_log: error creating log nlmsg\n");
nlmsg_cancel(skb, nlh);
return -1;
}
@@ -1077,19 +1074,19 @@ static int __init nfnetlink_log_init(void)
netlink_register_notifier(&nfulnl_rtnl_notifier);
status = nfnetlink_subsys_register(&nfulnl_subsys);
if (status < 0) {
- pr_err("log: failed to create netlink socket\n");
+ pr_err("failed to create netlink socket\n");
goto cleanup_netlink_notifier;
}
status = nf_log_register(NFPROTO_UNSPEC, &nfulnl_logger);
if (status < 0) {
- pr_err("log: failed to register logger\n");
+ pr_err("failed to register logger\n");
goto cleanup_subsys;
}
status = register_pernet_subsys(&nfnl_log_net_ops);
if (status < 0) {
- pr_err("log: failed to register pernet ops\n");
+ pr_err("failed to register pernet ops\n");
goto cleanup_logger;
}
return status;
--
1.9.3
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v3 2/3] Do error handling if __build_packet_message fails
2014-10-29 12:04 ` [PATCH v3 2/3] Do error handling if __build_packet_message fails Marcelo Ricardo Leitner
@ 2014-10-29 12:46 ` Marcelo Ricardo Leitner
0 siblings, 0 replies; 4+ messages in thread
From: Marcelo Ricardo Leitner @ 2014-10-29 12:46 UTC (permalink / raw)
To: netfilter-devel
On 29-10-2014 10:04, Marcelo Ricardo Leitner wrote:
> Currently, we don't check if __build_packet_message fails or not and
> that leaves it prone to sending incomplete messages to userspace.
>
> This commit fixes it by canceling the new message if there was any issue
> while building it and makes sure the skb is freed if it was the only
> messsage in it.
>
> Signed-off-by: Marcelo Ricardo Leitner <mleitner@redhat.com>
> ---
> net/netfilter/nfnetlink_log.c | 21 +++++++++++++++------
> 1 file changed, 15 insertions(+), 6 deletions(-)
>
> diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
> index b1e3a05794169283ed50d1c0fb4f44d9e7753eeb..05184a3d860885c10c3e977fdc47fb86e3528afa 100644
> --- a/net/netfilter/nfnetlink_log.c
> +++ b/net/netfilter/nfnetlink_log.c
> @@ -568,10 +568,8 @@ __build_packet_message(struct nfnl_log_net *log,
> struct nlattr *nla;
> int size = nla_attr_size(data_len);
>
> - if (skb_tailroom(inst->skb) < nla_total_size(data_len)) {
> - printk(KERN_WARNING "nfnetlink_log: no tailroom!\n");
> - return -1;
> - }
> + if (skb_tailroom(inst->skb) < nla_total_size(data_len))
> + goto nla_put_failure;
>
> nla = (struct nlattr *)skb_put(inst->skb, nla_total_size(data_len));
> nla->nla_type = NFULA_PAYLOAD;
> @@ -586,6 +584,7 @@ __build_packet_message(struct nfnl_log_net *log,
>
> nla_put_failure:
> PRINTR(KERN_ERR "nfnetlink_log: error creating log nlmsg\n");
> + nlmsg_cancel(skb, nlh);
> return -1;
> }
>
> @@ -708,8 +707,9 @@ nfulnl_log_packet(struct net *net,
>
> inst->qlen++;
>
> - __build_packet_message(log, inst, skb, data_len, pf,
> - hooknum, in, out, prefix, plen);
> + if (__build_packet_message(log, inst, skb, data_len, pf,
> + hooknum, in, out, prefix, plen))
bad alignment, sorry.. I'll fix this.
Marcelo
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2014-10-29 12:46 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-10-29 12:04 [PATCH v3 1/3] netfilter: log: protect nf_log_register against double registering Marcelo Ricardo Leitner
2014-10-29 12:04 ` [PATCH v3 2/3] Do error handling if __build_packet_message fails Marcelo Ricardo Leitner
2014-10-29 12:46 ` Marcelo Ricardo Leitner
2014-10-29 12:04 ` [PATCH v3 3/3] Make use of pr_fmt where applicable Marcelo Ricardo Leitner
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).