[PATCH] ufs: free the buffer head container in ubh_bforget

Ali Ahmet Memis <[email protected]>
Newsgroups gmane.linux.kernel.stable,gmane.linux.file-systems,gmane.linux.kernel
Message-ID <[email protected]>
ubh_bforget() forgets the buffer heads referenced by a struct
ufs_buffer_head but never frees the container itself, unlike its
sibling ubh_brelse() which calls kfree() on the way out. The only
caller, free_full_branch(), allocates the container through ubh_bread()
while releasing an indirect block during truncate, so every fully
removed indirect block leaks one ufs_buffer_head. Truncating or
unlinking a large file then leaks one allocation per indirect block,
which kmemleak reports with a free_full_branch, ufs_truncate_blocks,
ufs_evict_inode backtrace.

Free the container after forgetting its buffers, mirroring ubh_brelse().

Luis Henriques posted a fix for this leak in 2018, but it was never
applied while fs/ufs had no active maintainer, and the leak is still
present.

Link: https://lore.kernel.org/all/[email protected]/
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: [email protected]
Signed-off-by: Ali Ahmet Memis <[email protected]>
---
 fs/ufs/util.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/fs/ufs/util.c b/fs/ufs/util.c
index dff6f7461..3c65fbef6 100644
--- a/fs/ufs/util.c
+++ b/fs/ufs/util.c
@@ -117,8 +117,10 @@ void ubh_bforget (struct ufs_buffer_head * ubh)
 	unsigned i;
 	if (!ubh) 
 		return;
-	for ( i = 0; i < ubh->count; i++ ) if ( ubh->bh[i] ) 
-		bforget (ubh->bh[i]);
+	for (i = 0; i < ubh->count; i++)
+		if (ubh->bh[i])
+			bforget(ubh->bh[i]);
+	kfree(ubh);
 }
  
 int ubh_buffer_dirty (struct ufs_buffer_head * ubh)
-- 
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.