From a01ff11cb73d7a1988f6241f63d141371ff23717 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Mon, 25 Dec 2023 20:38:57 -0500 Subject: [PATCH] ocs: Check for copyin errors in the ioctl handler If copyin() fails, the driver will blindly proceed with whatever had been in the uninitialized DMA buffer. This is not what we want. Check for copyin failures. This is in preparation for annotating copyin() and related functions with __result_use_check. Reviewed by: ram MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D43097 --- sys/dev/ocs_fc/ocs_ioctl.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/sys/dev/ocs_fc/ocs_ioctl.c b/sys/dev/ocs_fc/ocs_ioctl.c index 6021ddf5c0d6..71ba17d5f72a 100644 --- a/sys/dev/ocs_fc/ocs_ioctl.c +++ b/sys/dev/ocs_fc/ocs_ioctl.c @@ -86,6 +86,7 @@ static int ocs_process_sli_config (ocs_t *ocs, ocs_ioctl_elxu_mbox_t *mcmd, ocs_dma_t *dma) { sli4_cmd_sli_config_t *sli_config = (sli4_cmd_sli_config_t *)mcmd->payload; + int error; if (sli_config->emb) { sli4_req_hdr_t *req = (sli4_req_hdr_t *)sli_config->payload.embed; @@ -127,7 +128,13 @@ ocs_process_sli_config (ocs_t *ocs, ocs_ioctl_elxu_mbox_t *mcmd, ocs_dma_t *dma) wrobj->host_buffer_descriptor[0].u.data.buffer_address_high = ocs_addr32_hi(dma->phys); /* copy the data into the DMA buffer */ - copyin((void *)(uintptr_t)mcmd->in_addr, dma->virt, mcmd->in_bytes); + error = copyin((void *)(uintptr_t)mcmd->in_addr, dma->virt, mcmd->in_bytes); + if (error != 0) { + device_printf(ocs->dev, "%s: COMMON_WRITE_OBJECT - copyin failed: %d\n", + __func__, error); + ocs_dma_free(ocs, dma); + return error; + } } break; case SLI4_OPC_COMMON_DELETE_OBJECT: @@ -170,7 +177,13 @@ ocs_process_sli_config (ocs_t *ocs, ocs_ioctl_elxu_mbox_t *mcmd, ocs_dma_t *dma) return ENXIO; } - copyin((void *)(uintptr_t)mcmd->in_addr, dma->virt, mcmd->in_bytes); + error = copyin((void *)(uintptr_t)mcmd->in_addr, dma->virt, mcmd->in_bytes); + if (error != 0) { + device_printf(ocs->dev, "%s: non-embedded - copyin failed: %d\n", + __func__, error); + ocs_dma_free(ocs, dma); + return error; + } sli_config->payload.mem.address_low = ocs_addr32_lo(dma->phys); sli_config->payload.mem.address_high = ocs_addr32_hi(dma->phys); @@ -184,6 +197,9 @@ static int ocs_process_mbx_ioctl(ocs_t *ocs, ocs_ioctl_elxu_mbox_t *mcmd) { ocs_dma_t dma = { 0 }; + int error; + + error = 0; if ((ELXU_BSD_MAGIC != mcmd->magic) || (sizeof(ocs_ioctl_elxu_mbox_t) != mcmd->size)) { @@ -238,13 +254,13 @@ ocs_process_mbx_ioctl(ocs_t *ocs, ocs_ioctl_elxu_mbox_t *mcmd) if( SLI4_MBOX_COMMAND_SLI_CONFIG == ((sli4_mbox_command_header_t *)mcmd->payload)->command && mcmd->out_bytes && dma.virt) { - copyout(dma.virt, (void *)(uintptr_t)mcmd->out_addr, mcmd->out_bytes); + error = copyout(dma.virt, (void *)(uintptr_t)mcmd->out_addr, mcmd->out_bytes); } no_support: ocs_dma_free(ocs, &dma); - return 0; + return error; } /**