All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] scsi: scsi_dh_rdac: fix NULL pointer dereference in error handling
@ 2026-07-13  6:36 Aleksey Shishkin
  2026-07-13  6:53 ` sashiko-bot
  0 siblings, 1 reply; 2+ messages in thread
From: Aleksey Shishkin @ 2026-07-13  6:36 UTC (permalink / raw)
  Cc: linux-kernel, Aleksey Shishkin, James E.J. Bottomley,
	Martin K. Petersen, Kees Cook, linux-scsi, linux-kernel

From: Aleksey Shishkin <aishishkin@cloud.ru>

There is a critical logic error in error handling. If get_controller()
fails and returns NULL, the function sets err = SCSI_DH_RES_TEMP_UNAVAIL.
However, immediately after spin_unlock(), the code unconditionally
overwrites err with SCSI_DH_OK.

This causes the kernel to falsely report a successful initialization,
leading to an inevitable Null Pointer Dereference (Kernel Panic) later
when the driver attempts to use the uninitialized h->ctlr.

Fix this by moving the assignment err = SCSI_DH_OK inside the else block
so it is only set when the controller is successfully acquired.

Signed-off-by: Aleksey Shishkin <aishishkin@cloud.ru>
---
 drivers/scsi/device_handler/scsi_dh_rdac.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
index 88c8e36b221e..ed02e1737bd7 100644
--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -455,9 +455,9 @@ static int initialize_controller(struct scsi_device *sdev,
 		else {
 			h->sdev = sdev;
 			list_add_rcu(&h->node, &h->ctlr->dh_list);
+			err = SCSI_DH_OK;
 		}
 		spin_unlock(&list_lock);
-		err = SCSI_DH_OK;
 	}
 	return err;
 }
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] scsi: scsi_dh_rdac: fix NULL pointer dereference in error handling
  2026-07-13  6:36 [PATCH] scsi: scsi_dh_rdac: fix NULL pointer dereference in error handling Aleksey Shishkin
@ 2026-07-13  6:53 ` sashiko-bot
  0 siblings, 0 replies; 2+ messages in thread
From: sashiko-bot @ 2026-07-13  6:53 UTC (permalink / raw)
  To: Aleksey Shishkin; +Cc: linux-scsi

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

Pre-existing issues:
- [Critical] A malicious SCSI device can trigger a stack buffer overflow in `get_lun_info()` by providing an oversized `array_uniq_id_len` in VPD page 0xC8.
- [High] In the error handling path of `rdac_bus_attach()`, if an initialization step such as `check_ownership` or `set_mode_select` fails, the handler data `h` is freed without removing `h->node` from the RCU-protected `h->ctlr->dh_list`, causing a Use-After-Free.
- [High] A time-of-check to time-of-use (TOCTOU) race condition between `rdac_bus_detach()` and the `send_mode_select()` workqueue function allows detachment to proceed while work is actively executing, resulting in Use-After-Free of handler data.
--

--- Patch [1]: [PATCH] scsi: scsi_dh_rdac: fix NULL pointer dereference in error handling ---
commit 712793434a46fcd5b5270defe36dc411e0363100
Author: Aleksey Shishkin <aishishkin@cloud.ru>
Subject: scsi: scsi_dh_rdac: fix NULL pointer dereference in error handling

This patch fixes a logic error in error handling where the return code was
incorrectly overwritten to SCSI_DH_OK after a failed get_controller() call,
moving the assignment into the success block.

> diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
> index 88c8e36b221e2..ed02e1737bd79 100644
> --- a/drivers/scsi/device_handler/scsi_dh_rdac.c
> +++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
> @@ -455,9 +455,9 @@ static int initialize_controller(struct scsi_device *sdev,
>  		else {
>  			h->sdev = sdev;
>  			list_add_rcu(&h->node, &h->ctlr->dh_list);
> +			err = SCSI_DH_OK;
>  		}

[Severity: High]
This is a pre-existing issue, but I noticed a potential use-after-free in the
error handling path.

When initialize_controller() succeeds, it adds the node to the RCU list here.
However, if a subsequent initialization step fails in rdac_bus_attach(),
the error path looks like this:

rdac_bus_attach() {
    ...
clean_ctlr:
	spin_lock(&list_lock);
	kref_put(&h->ctlr->kref, release_controller);
	spin_unlock(&list_lock);

failed:
	kfree(h);
}

Is it possible to reach kfree(h) without removing the node from the
controller's dh_list? If the controller remains alive and is shared by
another LUN, could subsequent RCU traversals of the list access this freed
memory?

>  		spin_unlock(&list_lock);
> -		err = SCSI_DH_OK;
>  	}
>  	return err;
>  }

[Severity: High]
This is a pre-existing issue, but does rdac_bus_detach() have a race condition
with the mode select workqueue?

In rdac_bus_detach(), the code locklessly checks ms_queued before flushing:

rdac_bus_detach() {
    ...
    if (h->ctlr && h->ctlr->ms_queued)
        flush_workqueue(kmpath_rdacd);
    ...
}

However, the worker thread send_mode_select() clears this flag early before
completing the potentially blocking SCSI command:

send_mode_select() {
    ...
    ctlr->ms_queued = 0;
    ctlr->ms_sdev = NULL;
    ...
}

Could rdac_bus_detach() run concurrently during this window, see ms_queued as
zero, skip the workqueue flush, and proceed to free the handler data while
the worker is still actively executing?

[Severity: Critical]
This is a pre-existing issue, but is there a potential stack buffer overflow
in get_lun_info()?

The function retrieves device data into inqp and uses array_uniq_id_len
directly for a memory copy:

get_lun_info() {
    ...
    memcpy(array_id, inqp->array_unique_id, inqp->array_uniq_id_len);
    ...
}

The destination buffer is a 16-byte fixed-size stack array declared in
rdac_bus_attach():

rdac_bus_attach() {
    char array_id[UNIQUE_ID_LEN];
    ...
}

Since array_uniq_id_len is provided by the device (potentially up to 255),
could an untrusted or misconfigured device provide an oversized length and
overflow the stack frame?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260713063640.3081603-1-demonaxsh@gmail.com?part=1

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-07-13  6:53 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-13  6:36 [PATCH] scsi: scsi_dh_rdac: fix NULL pointer dereference in error handling Aleksey Shishkin
2026-07-13  6:53 ` sashiko-bot

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.