[lvc-project] [PATCH] scsi: NCR5380: Prevent potential out-of-bounds read in spi_print_msg()

Rand Deeb rand.sec96 at gmail.com
Mon May 5 08:00:00 MSK 2025


On Wed, Apr 30, 2025 at 3:59 PM James Bottomley
<James.Bottomley at hansenpartnership.com> wrote:
>
> On Wed, 2025-04-30 at 14:59 +0300, Rand Deeb wrote:
> > spi_print_msg() assumes that the input buffer is large enough to
> > contain the full SCSI message, including extended messages which may
> > access msg[2], msg[3], msg[7], and beyond based on message type.
>
> That's true because it's a generic function designed to work for all
> parallel card.  However, this card only a narrow non-HVD low frequency
> one, so it only really speaks a tiny subset of this (in particular it
> would never speak messages over 3 bytes).

Thank you for clarifying this. I wasn’t aware that the NCR5380 is so
strictly limited in terms of message support.I assumed a more generic
scenario when applying defensive checks, without considering the practical
behavior of this specific hardware.

> > NCR5380_reselect() currently allocates a 3-byte buffer for 'msg'
> > and reads only a single byte from the SCSI bus before passing it to
> > spi_print_msg(), which can result in a potential out-of-bounds read
> > if the message is malformed or declares a longer length.

That makes sense. My initial assumption was that, even if unlikely, a
malformed or non-compliant message could theoretically appear. But I now
see that this isn’t realistic for these devices, and no evidence suggests
this has ever occurred in the field.

> The reselect protocol *requires* the next message to be an identify.
> Since these cards and the devices they attack to are all decades old, I
> think if they were going to behave like this we'd have seen it by now.
>
> The bottom line is we don't add this type of thing to a device facing
> interface unless there's evidence of an actual negotiation problem.

Understood and I agree. Defensive programming without a known issue on
hardware-level interfaces introduces unnecessary complexity.

> You didn't test this, did you?  The above code instructs the card to
> wait for 16 bytes on reselection and abort if they aren't found ...

You’re absolutely right. I misjudged the effect of changing the read length.

Given this, I’ll drop the patch entirely, as there’s no actual problem to
fix. The intent was only to silence static analysis tools, but I now
realize this isn’t a valid justification for modifying a stable hardware-
facing path.

Thanks again for the review and your insights.

Best regards,
Rand Deeb

On Wed, Apr 30, 2025 at 3:59 PM James Bottomley
<James.Bottomley at hansenpartnership.com> wrote:
>
> On Wed, 2025-04-30 at 14:59 +0300, Rand Deeb wrote:
> > spi_print_msg() assumes that the input buffer is large enough to
> > contain the full SCSI message, including extended messages which may
> > access msg[2], msg[3], msg[7], and beyond based on message type.
>
> That's true because it's a generic function designed to work for all
> parallel card.  However, this card only a narrow non-HVD low frequency
> one, so it only really speaks a tiny subset of this (in particular it
> would never speak messages over 3 bytes).
>
> > NCR5380_reselect() currently allocates a 3-byte buffer for 'msg'
> > and reads only a single byte from the SCSI bus before passing it to
> > spi_print_msg(), which can result in a potential out-of-bounds read
> > if the message is malformed or declares a longer length.
>
> The reselect protocol *requires* the next message to be an identify.
> Since these cards and the devices they attack to are all decades old, I
> think if they were going to behave like this we'd have seen it by now.
>
> The bottom line is we don't add this type of thing to a device facing
> interface unless there's evidence of an actual negotiation problem.
>
> [...]
> > @@ -2084,7 +2084,7 @@ static void NCR5380_reselect(struct Scsi_Host
> > *instance)
> >       msg[0] = NCR5380_read(CURRENT_SCSI_DATA_REG);
> >  #else
> >       {
> > -             int len = 1;
> > +             int len = sizeof(msg);
>
> You didn't test this, did you?  The above code instructs the card to
> wait for 16 bytes on reselection and abort if they aren't found ...
> i.e. every reselection now aborts because the device is only sending a
> one byte message.
>
> Regards,
>
> James
>



More information about the lvc-project mailing list