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 <abavanar@codeaurora.org>
diff --git a/asoc/msm-pcm-q6-noirq.c b/asoc/msm-pcm-q6-noirq.c
index b33eba3..5b97831 100644
--- a/asoc/msm-pcm-q6-noirq.c
+++ b/asoc/msm-pcm-q6-noirq.c
@@ -445,6 +445,8 @@
 	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 @@
 	 * 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,