[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <668e3f30-1ffb-31e3-231b-705489993885@embeddedor.com>
Date: Wed, 24 Mar 2021 19:46:35 -0500
From: "Gustavo A. R. Silva" <gustavo@...eddedor.com>
To: "Martin K. Petersen" <martin.petersen@...cle.com>,
"Gustavo A. R. Silva" <gustavoars@...nel.org>
Cc: Adaptec OEM Raid Solutions <aacraid@...rosemi.com>,
"James E.J. Bottomley" <jejb@...ux.ibm.com>,
linux-scsi@...r.kernel.org, linux-kernel@...r.kernel.org,
linux-hardening@...r.kernel.org
Subject: Re: [PATCH][next] scsi: aacraid: Replace one-element array with
flexible-array member
Hi Martin,
On 3/24/21 20:18, Martin K. Petersen wrote:
>
> Hi Gustavo!
>
> Your changes and the original code do not appear to be functionally
> equivalent.
>
>> @@ -1235,8 +1235,8 @@ static int aac_read_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u3
>> if (ret < 0)
>> return ret;
>> command = ContainerRawIo2;
>> - fibsize = sizeof(struct aac_raw_io2) +
>> - ((le32_to_cpu(readcmd2->sgeCnt)-1) * sizeof(struct sge_ieee1212));
>> + fibsize = struct_size(readcmd2, sge,
>> + le32_to_cpu(readcmd2->sgeCnt));
>
> The old code allocated sgeCnt-1 elements (whether that was a mistake or
> not I do not know) whereas the new code would send a larger fib to the
> ASIC. I don't have any aacraid adapters and I am hesitant to merging
> changes that have not been validated on real hardware.
Precisely this sort of confusion is one of the things we want to avoid
by using flexible-array members instead of one-element arrays.
fibsize is actually the same for both the old and the new code. The
difference is that in the original code, the one-element array _sge_
at the bottom of struct aac_raw_io2, contributes to the size of the
structure, as it occupies at least as much space as a single object
of its type. On the other hand, flexible-array members don't contribute
to the size of the enclosing structure. See below...
Old code:
$ pahole -C aac_raw_io2 drivers/scsi/aacraid/aachba.o
struct aac_raw_io2 {
__le32 blockLow; /* 0 4 */
__le32 blockHigh; /* 4 4 */
__le32 byteCount; /* 8 4 */
__le16 cid; /* 12 2 */
__le16 flags; /* 14 2 */
__le32 sgeFirstSize; /* 16 4 */
__le32 sgeNominalSize; /* 20 4 */
u8 sgeCnt; /* 24 1 */
u8 bpTotal; /* 25 1 */
u8 bpComplete; /* 26 1 */
u8 sgeFirstIndex; /* 27 1 */
u8 unused[4]; /* 28 4 */
struct sge_ieee1212 sge[1]; /* 32 16 */
/* size: 48, cachelines: 1, members: 13 */
/* last cacheline: 48 bytes */
};
New code:
$ pahole -C aac_raw_io2 drivers/scsi/aacraid/aachba.o
struct aac_raw_io2 {
__le32 blockLow; /* 0 4 */
__le32 blockHigh; /* 4 4 */
__le32 byteCount; /* 8 4 */
__le16 cid; /* 12 2 */
__le16 flags; /* 14 2 */
__le32 sgeFirstSize; /* 16 4 */
__le32 sgeNominalSize; /* 20 4 */
u8 sgeCnt; /* 24 1 */
u8 bpTotal; /* 25 1 */
u8 bpComplete; /* 26 1 */
u8 sgeFirstIndex; /* 27 1 */
u8 unused[4]; /* 28 4 */
struct sge_ieee1212 sge[]; /* 32 0 */
/* size: 32, cachelines: 1, members: 13 */
/* last cacheline: 32 bytes */
};
So, the old code allocates sgeCnt-1 elements because sizeof(struct aac_raw_io2) is
already counting one element of the _sge_ array.
Please, let me know if this is clear now.
Thanks!
--
Gustavo
Powered by blists - more mailing lists