tracing: Fix a memory leak by early error exit in trace_pid_write() [Linux 5.1]

tracing: Fix a memory leak by early error exit in trace_pid_write() [Linux 5.1]

This Linux kernel change "tracing: Fix a memory leak by early error exit in trace_pid_write()" is included in the Linux 5.1 release. This change is authored by Wenwen Wang <wang6495 [at] umn.edu> on Fri Apr 19 21:22:59 2019 -0500. The commit for this change in Linux stable tree is 91862cc (patch).

tracing: Fix a memory leak by early error exit in trace_pid_write()

In trace_pid_write(), the buffer for trace parser is allocated through
kmalloc() in trace_parser_get_init(). Later on, after the buffer is used,
it is then freed through kfree() in trace_parser_put(). However, it is
possible that trace_pid_write() is terminated due to unexpected errors,
e.g., ENOMEM. In that case, the allocated buffer will not be freed, which
is a memory leak bug.

To fix this issue, free the allocated buffer when an error is encountered.

Link: http://lkml.kernel.org/r/1555726979-15633-1-git-send-email-wang6495@umn.edu

Fixes: f4d34a87e9c10 ("tracing: Use pid bitmap instead of a pid array for set_event_pid")
Cc: stable@vger.kernel.org
Signed-off-by: Wenwen Wang <wang6495@umn.edu>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>

There are 5 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 kernel/trace/trace.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 0cfa13a6..46f68fa 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -496,8 +496,10 @@ int trace_pid_write(struct trace_pid_list *filtered_pids,
     * not modified.
     */
    pid_list = kmalloc(sizeof(*pid_list), GFP_KERNEL);
-   if (!pid_list)
+   if (!pid_list) {
+       trace_parser_put(&parser);
        return -ENOMEM;
+   }

    pid_list->pid_max = READ_ONCE(pid_max);

@@ -507,6 +509,7 @@ int trace_pid_write(struct trace_pid_list *filtered_pids,

    pid_list->pids = vzalloc((pid_list->pid_max + 7) >> 3);
    if (!pid_list->pids) {
+       trace_parser_put(&parser);
        kfree(pid_list);
        return -ENOMEM;
    }

Leave a Reply

Your email address will not be published. Required fields are marked *