]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - net/ipv4/tcp_probe.c
tcp: tcp_probe buffer overflow and incorrect return value
[karo-tx-linux.git] / net / ipv4 / tcp_probe.c
index b76398d1b4547d291e52051276c80ff7df36880b..a79a547464a5a21303f75483fef1d1ec63abefa5 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/ktime.h>
 #include <linux/time.h>
+#include <net/net_namespace.h>
 
 #include <net/tcp.h>
 
@@ -189,19 +190,18 @@ static ssize_t tcpprobe_read(struct file *file, char __user *buf,
 
                width = tcpprobe_sprint(tbuf, sizeof(tbuf));
 
-               if (width < len)
+               if (cnt + width < len)
                        tcp_probe.tail = (tcp_probe.tail + 1) % bufsize;
 
                spin_unlock_bh(&tcp_probe.lock);
 
                /* if record greater than space available
                   return partial buffer (so far) */
-               if (width >= len)
+               if (cnt + width >= len)
                        break;
 
-               error = copy_to_user(buf + cnt, tbuf, width);
-               if (error)
-                       break;
+               if (copy_to_user(buf + cnt, tbuf, width))
+                       return -EFAULT;
                cnt += width;
        }
 
@@ -228,7 +228,7 @@ static __init int tcpprobe_init(void)
        if (!tcp_probe.log)
                goto err0;
 
-       if (!proc_net_fops_create(procname, S_IRUSR, &tcpprobe_fops))
+       if (!proc_net_fops_create(&init_net, procname, S_IRUSR, &tcpprobe_fops))
                goto err0;
 
        ret = register_jprobe(&tcp_jprobe);
@@ -238,7 +238,7 @@ static __init int tcpprobe_init(void)
        pr_info("TCP probe registered (port=%d)\n", port);
        return 0;
  err1:
-       proc_net_remove(procname);
+       proc_net_remove(&init_net, procname);
  err0:
        kfree(tcp_probe.log);
        return ret;
@@ -247,7 +247,7 @@ module_init(tcpprobe_init);
 
 static __exit void tcpprobe_exit(void)
 {
-       proc_net_remove(procname);
+       proc_net_remove(&init_net, procname);
        unregister_jprobe(&tcp_jprobe);
        kfree(tcp_probe.log);
 }