summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2008-03-26 16:49:40 -0700
committerDavid S. Miller <davem@davemloft.net>2008-03-26 16:49:40 -0700
commita233352506be35aafd49c0ba8c88ca96ebde1c3d (patch)
tree61bcc9f1f7a84ab926e0f2c8c32fe52e9124da3d
parent9b674e82b73a61844967b32e1b4ecaf8eb9d1805 (diff)
downloadlinux-3.10-a233352506be35aafd49c0ba8c88ca96ebde1c3d.tar.gz
linux-3.10-a233352506be35aafd49c0ba8c88ca96ebde1c3d.tar.bz2
linux-3.10-a233352506be35aafd49c0ba8c88ca96ebde1c3d.zip
[IPV6]: Fix potential net leak and oops in ipv6 routing code.
The commits f3db4851 ([NETNS][IPV6] ip6_fib - fib6_clean_all handle several network namespaces) and 69ddb805 ([NETNS][IPV6] route6 - Make proc entry /proc/net/rt6_stats per namespace) made some proc files per net. Both of them introduced potential OOPS - get_proc_net can return NULL, but this check is lost - and a struct net leak - in case single_open() fails the previously got net is not put. Kill all these bugs with one patch. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Acked-by: Daniel Lezcano <dlezcano@fr.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/ipv6/route.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index ac442837143..cd82b6db35f 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2390,10 +2390,18 @@ static int ipv6_route_show(struct seq_file *m, void *v)
static int ipv6_route_open(struct inode *inode, struct file *file)
{
+ int err;
struct net *net = get_proc_net(inode);
if (!net)
return -ENXIO;
- return single_open(file, ipv6_route_show, net);
+
+ err = single_open(file, ipv6_route_show, net);
+ if (err < 0) {
+ put_net(net);
+ return err;
+ }
+
+ return 0;
}
static int ipv6_route_release(struct inode *inode, struct file *file)
@@ -2429,8 +2437,18 @@ static int rt6_stats_seq_show(struct seq_file *seq, void *v)
static int rt6_stats_seq_open(struct inode *inode, struct file *file)
{
+ int err;
struct net *net = get_proc_net(inode);
- return single_open(file, rt6_stats_seq_show, net);
+ if (!net)
+ return -ENXIO;
+
+ err = single_open(file, rt6_stats_seq_show, net);
+ if (err < 0) {
+ put_net(net);
+ return err;
+ }
+
+ return 0;
}
static int rt6_stats_seq_release(struct inode *inode, struct file *file)