4.20-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Pavel Shilovsky <[email protected]>

commit 9bda8723da2d55b1de833b98cf802b88006e5b69 upstream.

Allocation of a page array for non-cached IO was separated from
allocation of rdata and wdata structures and this introduced memory
leaks and a possible null pointer dereference. This patch fixes
these problems.

Cc: <[email protected]>
Signed-off-by: Pavel Shilovsky <[email protected]>
Signed-off-by: Steve French <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
 fs/cifs/file.c |   11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2670,6 +2670,7 @@ cifs_write_from_iter(loff_t offset, size
 
                        rc = cifs_write_allocate_pages(wdata->pages, nr_pages);
                        if (rc) {
+                               kvfree(wdata->pages);
                                kfree(wdata);
                                add_credits_and_wake_if(server, credits, 0);
                                break;
@@ -2681,6 +2682,7 @@ cifs_write_from_iter(loff_t offset, size
                        if (rc) {
                                for (i = 0; i < nr_pages; i++)
                                        put_page(wdata->pages[i]);
+                               kvfree(wdata->pages);
                                kfree(wdata);
                                add_credits_and_wake_if(server, credits, 0);
                                break;
@@ -3360,8 +3362,12 @@ cifs_send_async_read(loff_t offset, size
                        }
 
                        rc = cifs_read_allocate_pages(rdata, npages);
-                       if (rc)
-                               goto error;
+                       if (rc) {
+                               kvfree(rdata->pages);
+                               kfree(rdata);
+                               add_credits_and_wake_if(server, credits, 0);
+                               break;
+                       }
 
                        rdata->tailsz = PAGE_SIZE;
                }
@@ -3381,7 +3387,6 @@ cifs_send_async_read(loff_t offset, size
                if (!rdata->cfile->invalidHandle ||
                    !(rc = cifs_reopen_file(rdata->cfile, true)))
                        rc = server->ops->async_readv(rdata);
-error:
                if (rc) {
                        add_credits_and_wake_if(server, rdata->credits, 0);
                        kref_put(&rdata->refcount,


Reply via email to