Linux SCSI subsystem development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Aleksey Shishkin" <demonaxsh@gmail.com>
Cc: linux-scsi@vger.kernel.org
Subject: Re: [PATCH] scsi: scsi_dh_rdac: fix NULL pointer dereference in error handling
Date: Mon, 13 Jul 2026 06:53:18 +0000	[thread overview]
Message-ID: <20260713065318.CDEEE1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260713063640.3081603-1-demonaxsh@gmail.com>

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

      reply	other threads:[~2026-07-13  6:53 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260713065318.CDEEE1F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=demonaxsh@gmail.com \
    --cc=linux-scsi@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox