[PATCH] libtracefs: Fix memory leak in tracefs_tracing_dir_is_mounted()
Bean Huo <[email protected]> Thu, 30 Jul 2026 18:13:59 +0200
| Newsgroups | org.kernel.vger.linux-trace-devel |
|---|---|
| Message-ID | <[email protected]> |
From: Bean Huo <[email protected]> tfs_find_debug_tracing_dir() returns a newly allocated string on every call, and the caller owns it -- tfs_find_tracing_dir() documents that the result "must be freed by free()". But tracefs_tracing_dir_is_mounted() passes that pointer straight out through @path, whose own documentation says it "must not be freed". The two contracts cannot both hold: the allocation is unreachable the moment the function returns, and no caller is permitted to release it. The result is a leak of the tracing directory path on every call, and two of them when the directory was not mounted and @mount asked for it to be. valgrind on an application that calls it once at startup: 20 bytes in 1 blocks are definitely lost in loss record 2 of 3 at 0x4848899: malloc by 0x4A2C58E: strdup (strdup.c:42) by 0x13014C: find_tracing_dir (tracefs-utils.c:155) by 0x1301A7: tracefs_tracing_dir_is_mounted (tracefs-utils.c:178) The library already keeps exactly the cache this function needs: tracefs_tracing_dir() memoises the path in a static, revalidates it with test_dir(), and is documented as returning a string that must not be freed. Use tfs_find_debug_tracing_dir() only to probe -- it is still needed for that, because unlike tracefs_tracing_dir() it can be told not to mount, which is what @mount == false requires -- then release the probe copy and return the cached path. Note this changes @path when a custom directory is in effect: it now reports tracefs_set_tracing_dir()'s value rather than the detected mount point. That makes @path agree with the directory the rest of the library actually operates on, which seems the more useful answer, but it is a visible change and not merely an internal cleanup. The return value is unaffected -- it still comes from probing the real mount state. Signed-off-by: Bean Huo <[email protected]> --- src/tracefs-utils.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/tracefs-utils.c b/src/tracefs-utils.c index d1aced0..96a1fa9 100644 --- a/src/tracefs-utils.c +++ b/src/tracefs-utils.c @@ -173,12 +173,19 @@ __hidden char *tfs_find_debug_tracing_dir(bool debugfs, bool mount) */ int tracefs_tracing_dir_is_mounted(bool mount, const char **path) { - const char *dir; + char *dir; + /* + * tfs_find_debug_tracing_dir() allocates a new string on every call + * and the caller owns it, but @path is documented as not freeable. + * Use it only to probe (unlike tracefs_tracing_dir() it can be told + * not to mount), then hand back the cached path the library owns. + */ dir = tfs_find_debug_tracing_dir(false, false); if (dir) { + free(dir); if (path) - *path = dir; + *path = tracefs_tracing_dir(); return 1; } if (!mount) @@ -187,8 +194,9 @@ int tracefs_tracing_dir_is_mounted(bool mount, const char **path) dir = tfs_find_debug_tracing_dir(false, mount); if (!dir) return -1; + free(dir); if (path) - *path = dir; + *path = tracefs_tracing_dir(); return 0; } -- 2.34.1