git: 8adca661c2bb - stable/14 - mpi3mr: Check for copyin errors in mpi3mr_map_data_buffer_dma()

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Tue, 02 Jan 2024 00:37:15 UTC
The branch stable/14 has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=8adca661c2bbcec780d0ad532be4a870090e35db

commit 8adca661c2bbcec780d0ad532be4a870090e35db
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2023-12-26 01:38:12 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2024-01-02 00:29:45 +0000

    mpi3mr: Check for copyin errors in mpi3mr_map_data_buffer_dma()
    
    A failed copyin will cause the driver to use the contents of
    uninitialized buffers instead, which is unlikely to be the behaviour
    that we want.  Check for errors.
    
    This is in preparation for annotating copyin() and related functions
    with __result_use_check.
    
    Reviewed by:    imp
    MFC after:      1 week
    Differential Revision:  https://reviews.freebsd.org/D43098
    
    (cherry picked from commit 6bfb7306ef92aaccffae42ed00ce6d7201b76966)
---
 sys/dev/mpi3mr/mpi3mr_app.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/sys/dev/mpi3mr/mpi3mr_app.c b/sys/dev/mpi3mr/mpi3mr_app.c
index 001753732a35..cf3afc7bba95 100644
--- a/sys/dev/mpi3mr/mpi3mr_app.c
+++ b/sys/dev/mpi3mr/mpi3mr_app.c
@@ -544,6 +544,7 @@ static int mpi3mr_map_data_buffer_dma(struct mpi3mr_softc *sc,
 {
 	U16 i, needed_desc = (dma_buffers->kern_buf_len / MPI3MR_IOCTL_SGE_SIZE);
 	U32 buf_len = dma_buffers->kern_buf_len, copied_len = 0;
+	int error;
 	
 	if (dma_buffers->kern_buf_len % MPI3MR_IOCTL_SGE_SIZE)
 		needed_desc++;
@@ -559,6 +560,7 @@ static int mpi3mr_map_data_buffer_dma(struct mpi3mr_softc *sc,
 	if (!dma_buffers->dma_desc)
 		return -1;
 
+	error = 0;
 	for (i = 0; i < needed_desc; i++, desc_count++) {
 
 		dma_buffers->dma_desc[i].addr = sc->ioctl_sge[desc_count].addr;
@@ -573,12 +575,19 @@ static int mpi3mr_map_data_buffer_dma(struct mpi3mr_softc *sc,
 		memset(dma_buffers->dma_desc[i].addr, 0, sc->ioctl_sge[desc_count].size);
 
 		if (dma_buffers->data_dir == MPI3MR_APP_DDO) {
-			copyin(((U8 *)dma_buffers->user_buf + copied_len),
+			error = copyin(((U8 *)dma_buffers->user_buf + copied_len),
 			       dma_buffers->dma_desc[i].addr,
 			       dma_buffers->dma_desc[i].size);
+			if (error != 0)
+				break;
 			copied_len += dma_buffers->dma_desc[i].size;
 		}
 	}
+	if (error != 0) {
+		printf("%s: DMA copyin error %d\n", __func__, error);
+		free(dma_buffers->dma_desc, M_MPI3MR);
+		return -1;
+	}
 
 	dma_buffers->num_dma_desc = needed_desc;