fix memory leaks in tracing_buffers_splice_read()
authorAl Viro <viro@zeniv.linux.org.uk>
Sat, 17 Sep 2016 22:31:46 +0000 (18:31 -0400)
committerWilly Tarreau <w@1wt.eu>
Mon, 6 Feb 2017 22:33:04 +0000 (23:33 +0100)
commit 1ae2293dd6d2f5c823cf97e60b70d03631cd622f upstream.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Willy Tarreau <w@1wt.eu>
kernel/trace/trace.c

index eff26a976f0243aa3cc3ec73542c83388a769612..4ff36f73f1a32ce303859f88a4309a45d841bca5 100644 (file)
@@ -5168,11 +5168,6 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
        }
 #endif
 
-       if (splice_grow_spd(pipe, &spd)) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
        if (*ppos & (PAGE_SIZE - 1)) {
                ret = -EINVAL;
                goto out;
@@ -5186,6 +5181,11 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
                len &= PAGE_MASK;
        }
 
+       if (splice_grow_spd(pipe, &spd)) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
  again:
        trace_access_lock(iter->cpu_file);
        entries = ring_buffer_entries_cpu(iter->trace_buffer->buffer, iter->cpu_file);
@@ -5241,21 +5241,22 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
        if (!spd.nr_pages) {
                if ((file->f_flags & O_NONBLOCK) || (flags & SPLICE_F_NONBLOCK)) {
                        ret = -EAGAIN;
-                       goto out;
+                       goto out_shrink;
                }
                mutex_unlock(&trace_types_lock);
                ret = iter->trace->wait_pipe(iter);
                mutex_lock(&trace_types_lock);
                if (ret)
-                       goto out;
+                       goto out_shrink;
                if (signal_pending(current)) {
                        ret = -EINTR;
-                       goto out;
+                       goto out_shrink;
                }
                goto again;
        }
 
        ret = splice_to_pipe(pipe, &spd);
+out_shrink:
        splice_shrink_spd(&spd);
 out:
        mutex_unlock(&trace_types_lock);