From 36a5eb40be58777e5cc9a68c46bb7991d4e0a07a Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 27 Mar 2019 19:15:03 +0530 Subject: [PATCH] asoc: Use dma_buf_get along with dma_buf_fd Use dma_buf_get along with dma_buf_fd on the obtained fd in order to increment the reference count and avoid use after free on fd when it is freed from userspace. CRs-Fixed: 2419587 Change-Id: I57e1396234eebb60224ed58182cca80888e94a9e Signed-off-by: Aditya Bavanari --- asoc/msm-pcm-q6-noirq.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/asoc/msm-pcm-q6-noirq.c b/asoc/msm-pcm-q6-noirq.c index b33eba3fc76a..5b978311b0ff 100644 --- a/asoc/msm-pcm-q6-noirq.c +++ b/asoc/msm-pcm-q6-noirq.c @@ -445,6 +445,8 @@ static int msm_pcm_mmap_fd(struct snd_pcm_substream *substream, struct audio_port_data *apd; struct audio_buffer *ab; int dir = -1; + struct dma_buf *buf = NULL; + int rc = 0; if (!substream->runtime) { pr_err("%s substream runtime not found\n", __func__); @@ -471,12 +473,25 @@ static int msm_pcm_mmap_fd(struct snd_pcm_substream *substream, * used to call dma_buf_fd internally. */ mmap_fd->fd = dma_buf_fd(ab->dma_buf, O_CLOEXEC); - if (mmap_fd->fd >= 0) { - mmap_fd->dir = dir; - mmap_fd->actual_size = ab->actual_size; - mmap_fd->size = ab->size; + if (mmap_fd->fd < 0) { + pr_err("%s: dma_buf_fd failed, fd:%d\n", + __func__, mmap_fd->fd); + rc = -EFAULT; + goto buf_fd_fail; } - return mmap_fd->fd < 0 ? -EFAULT : 0; + mmap_fd->dir = dir; + mmap_fd->actual_size = ab->actual_size; + mmap_fd->size = ab->size; + + buf = dma_buf_get(mmap_fd->fd); + if (IS_ERR_OR_NULL(buf)) { + pr_err("%s: dma_buf_get failed, fd:%d\n", + __func__, mmap_fd->fd); + rc = -EINVAL; + } + +buf_fd_fail: + return rc; } static int msm_pcm_ioctl(struct snd_pcm_substream *substream,