netfilter: log: Check param to avoid overflow in nf_log_set
authorGao Feng <fgao@ikuai8.com>
Mon, 29 Aug 2016 10:25:28 +0000 (18:25 +0800)
committerPablo Neira Ayuso <pablo@netfilter.org>
Tue, 30 Aug 2016 09:52:32 +0000 (11:52 +0200)
The nf_log_set is an interface function, so it should do the strict sanity
check of parameters. Convert the return value of nf_log_set as int instead
of void. When the pf is invalid, return -EOPNOTSUPP.

Signed-off-by: Gao Feng <fgao@ikuai8.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/net/netfilter/nf_log.h
net/bridge/netfilter/nf_log_bridge.c
net/ipv4/netfilter/nf_log_arp.c
net/ipv4/netfilter/nf_log_ipv4.c
net/ipv6/netfilter/nf_log_ipv6.c
net/netfilter/nf_log.c

index 83d855ba6af12fe3524c677005653243b47dffd3..ee07dc8b0a7bd06c2f563657dde75a11315e8497 100644 (file)
@@ -60,8 +60,7 @@ struct nf_logger {
 int nf_log_register(u_int8_t pf, struct nf_logger *logger);
 void nf_log_unregister(struct nf_logger *logger);
 
-void nf_log_set(struct net *net, u_int8_t pf,
-               const struct nf_logger *logger);
+int nf_log_set(struct net *net, u_int8_t pf, const struct nf_logger *logger);
 void nf_log_unset(struct net *net, const struct nf_logger *logger);
 
 int nf_log_bind_pf(struct net *net, u_int8_t pf,
index 5d9953a90929199aad6eaa7a2cf44ed6b3cd8f60..1663df59854502b997d9bc56bb49712c0b99f28a 100644 (file)
@@ -50,8 +50,7 @@ static struct nf_logger nf_bridge_logger __read_mostly = {
 
 static int __net_init nf_log_bridge_net_init(struct net *net)
 {
-       nf_log_set(net, NFPROTO_BRIDGE, &nf_bridge_logger);
-       return 0;
+       return nf_log_set(net, NFPROTO_BRIDGE, &nf_bridge_logger);
 }
 
 static void __net_exit nf_log_bridge_net_exit(struct net *net)
index cf8f2d4e867a8dd0483b6397d2ba9f9f13619573..8945c26538149110c979ce58abd4f56461908718 100644 (file)
@@ -111,8 +111,7 @@ static struct nf_logger nf_arp_logger __read_mostly = {
 
 static int __net_init nf_log_arp_net_init(struct net *net)
 {
-       nf_log_set(net, NFPROTO_ARP, &nf_arp_logger);
-       return 0;
+       return nf_log_set(net, NFPROTO_ARP, &nf_arp_logger);
 }
 
 static void __net_exit nf_log_arp_net_exit(struct net *net)
index 076aadda04737eb7fa829adc14eb98ea37867655..20f225593a8b14563d68f13685d571aa2cfc47b8 100644 (file)
@@ -347,8 +347,7 @@ static struct nf_logger nf_ip_logger __read_mostly = {
 
 static int __net_init nf_log_ipv4_net_init(struct net *net)
 {
-       nf_log_set(net, NFPROTO_IPV4, &nf_ip_logger);
-       return 0;
+       return nf_log_set(net, NFPROTO_IPV4, &nf_ip_logger);
 }
 
 static void __net_exit nf_log_ipv4_net_exit(struct net *net)
index 8dd869642f45a032fcd0c1303319313392244a13..c1bcf699a23d1fb00f4d389bcdf6bcbe286d9e7d 100644 (file)
@@ -379,8 +379,7 @@ static struct nf_logger nf_ip6_logger __read_mostly = {
 
 static int __net_init nf_log_ipv6_net_init(struct net *net)
 {
-       nf_log_set(net, NFPROTO_IPV6, &nf_ip6_logger);
-       return 0;
+       return nf_log_set(net, NFPROTO_IPV6, &nf_ip6_logger);
 }
 
 static void __net_exit nf_log_ipv6_net_exit(struct net *net)
index aa5847a16713e9caddb74127dfd73dd50ee57b83..30a17d649a8329af7f671c79616c2b6325e10c8d 100644 (file)
@@ -39,12 +39,12 @@ static struct nf_logger *__find_logger(int pf, const char *str_logger)
        return NULL;
 }
 
-void nf_log_set(struct net *net, u_int8_t pf, const struct nf_logger *logger)
+int nf_log_set(struct net *net, u_int8_t pf, const struct nf_logger *logger)
 {
        const struct nf_logger *log;
 
-       if (pf == NFPROTO_UNSPEC)
-               return;
+       if (pf == NFPROTO_UNSPEC || pf >= ARRAY_SIZE(net->nf.nf_loggers))
+               return -EOPNOTSUPP;
 
        mutex_lock(&nf_log_mutex);
        log = nft_log_dereference(net->nf.nf_loggers[pf]);
@@ -52,6 +52,8 @@ void nf_log_set(struct net *net, u_int8_t pf, const struct nf_logger *logger)
                rcu_assign_pointer(net->nf.nf_loggers[pf], logger);
 
        mutex_unlock(&nf_log_mutex);
+
+       return 0;
 }
 EXPORT_SYMBOL(nf_log_set);