From: Mathias Krause minipli@grsecurity.net
stable inclusion from stable-v5.10.101 commit a5ce7ee5fcc07583159f54ab4af5164de00148f5 bugzilla: https://gitee.com/openeuler/kernel/issues/I5669Z
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
[ Upstream commit 46963e2e0629cb31c96b1d47ddd89dc3d8990b34 ]
If the copy back to userland fails for the FASTRPC_IOCTL_ALLOC_DMA_BUFF ioctl(), we shouldn't assume that 'buf->dmabuf' is still valid. In fact, dma_buf_fd() called fd_install() before, i.e. "consumed" one reference, leaving us with none.
Calling dma_buf_put() will therefore put a reference we no longer own, leading to a valid file descritor table entry for an already released 'file' object which is a straight use-after-free.
Simply avoid calling dma_buf_put() and rely on the process exit code to do the necessary cleanup, if needed, i.e. if the file descriptor is still valid.
Fixes: 6cffd79504ce ("misc: fastrpc: Add support for dmabuf exporter") Acked-by: Christian König christian.koenig@amd.com Signed-off-by: Mathias Krause minipli@grsecurity.net Link: https://lore.kernel.org/r/20220127130218.809261-1-minipli@grsecurity.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yu Liao liaoyu15@huawei.com Reviewed-by: Wei Li liwei391@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/misc/fastrpc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index ef49ac8d9101..d0471fec37fb 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -1284,7 +1284,14 @@ static int fastrpc_dmabuf_alloc(struct fastrpc_user *fl, char __user *argp) }
if (copy_to_user(argp, &bp, sizeof(bp))) { - dma_buf_put(buf->dmabuf); + /* + * The usercopy failed, but we can't do much about it, as + * dma_buf_fd() already called fd_install() and made the + * file descriptor accessible for the current process. It + * might already be closed and dmabuf no longer valid when + * we reach this point. Therefore "leak" the fd and rely on + * the process exit path to do any required cleanup. + */ return -EFAULT; }