FAILED: patch "[PATCH] NFS: Fix memory leaks and corruption in readdir" failed to apply to 4.4-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 4b310319c6a8ce708f1033d57145e2aa027a883c Mon Sep 17 00:00:00 2001
From: Trond Myklebust <[email protected]>
Date: Sun, 2 Feb 2020 17:53:53 -0500
Subject: [PATCH] NFS: Fix memory leaks and corruption in readdir
nfs_readdir_xdr_to_array() must not exit without having initialised the array, so that the page cache deletion routines can safely call nfs_readdir_clear_array().
Furthermore, we should ensure that if we exit nfs_readdir_filler() with an error, we free up any page contents to prevent a leak if we try to fill the page again.
fs/nfs/dir.c +15 -2
@@ -162,6 +162,17 @@ typedef struct {bool eof; } nfs_readdir_descriptor_t; +static +void nfs_readdir_init_array (struct page *page) +{ +struct nfs_cache_array *array; + + array =kmap_atomic (page); +memset (array,0 ,sizeof (struct nfs_cache_array )); + array->eof_index =-1 ; +kunmap_atomic (array); +} +/* * we are freeing strings created by nfs_add_to_readdir_array() */
@@ -174,6 +185,7 @@ void nfs_readdir_clear_array(struct page *page) array =kmap_atomic (page);for (i =0 ; i < array->size; i++)kfree (array->array[i].string.name); + array->size =0 ;kunmap_atomic (array); }
@@ -610,6 +622,8 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,int status = -ENOMEM ;unsigned int array_size =ARRAY_SIZE (pages); +nfs_readdir_init_array (page); + entry.prev_cookie =0 ; entry.cookie = desc->last_cookie; entry.eof =0 ;
@@ -626,8 +640,6 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page, } array =kmap (page); -memset (array,0 ,sizeof (struct nfs_cache_array )); - array->eof_index =-1 ; status =nfs_readdir_alloc_pages (pages, array_size);if (status <0 )
@@ -682,6 +694,7 @@ int nfs_readdir_filler(void *data, struct page* page)unlock_page (page);return 0 ; error: +nfs_readdir_clear_array (page);unlock_page (page);return ret; }