On Wed, Jun 17, 2020 at 07:57:20AM +0530, Souptick Joarder wrote: > There is a bug, when get_user_pages() failed but partially pinned > pages are not unpinned. Fixed it. > > Also, int is more appropriate type for rv. Changed it. > > Signed-off-by: Souptick Joarder <jrdr.linux@xxxxxxxxx> > Cc: John Hubbard <jhubbard@xxxxxxxxxx> > Cc: Bharath Vedartham <linux.bhar@xxxxxxxxx> > Cc: Dan Carpenter <dan.carpenter@xxxxxxxxxx> > --- > drivers/staging/kpc2000/kpc_dma/fileops.c | 6 +++++- > 1 file changed, 5 insertions(+), 1 deletion(-) > > diff --git a/drivers/staging/kpc2000/kpc_dma/fileops.c b/drivers/staging/kpc2000/kpc_dma/fileops.c > index 8975346..b136353 100644 > --- a/drivers/staging/kpc2000/kpc_dma/fileops.c > +++ b/drivers/staging/kpc2000/kpc_dma/fileops.c > @@ -35,7 +35,7 @@ static int kpc_dma_transfer(struct dev_private_data *priv, > unsigned long iov_base, size_t iov_len) > { > unsigned int i = 0; > - long rv = 0; > + int rv = 0; > struct kpc_dma_device *ldev; > struct aio_cb_data *acd; > DECLARE_COMPLETION_ONSTACK(done); > @@ -193,6 +193,10 @@ static int kpc_dma_transfer(struct dev_private_data *priv, > put_page(acd->user_pages[i]); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > > err_get_user_pages: > + if (rv > 0) { > + for (i = 0; i < rv; i++) > + put_pages(acd->user_pages[i]) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > + } This isn't a complete fix. "rv" is the negative error code but here we are returning a positive value on this path. Also it's ugly to have same put_page() loop repeated twice. It would be better to write it like this: rv = get_user_pages(iov_base, acd->page_count, FOLL_TOUCH | FOLL_WRITE | FOLL_GET, acd->user_pages, NULL); mmap_read_unlock(current->mm); /* release the semaphore */ if (rv < 0) goto free_pages; if (rv != acd->page_count) { acd->page_count = rv; rv = -EFAULT; goto put_pages; } ... put_pages: for (i = 0 ; i < acd->page_count ; i++) put_pages(acd->user_pages[i]); free_pages: kfree(acd->user_pages); regards, dan carpenter _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel