* [PATCH][next] scsi: qla2xxx: Fix memcpy field-spanning write issue
@ 2025-07-30 22:54 Gustavo A. R. Silva
2025-07-31 3:17 ` Martin K. Petersen
0 siblings, 1 reply; 3+ messages in thread
From: Gustavo A. R. Silva @ 2025-07-30 22:54 UTC (permalink / raw)
To: Chris Leech, Bryan Gurney, Nilesh Javali, James E.J. Bottomley,
Martin K. Petersen
Cc: GR-QLogic-Storage-Upstream, linux-scsi, linux-kernel,
Gustavo A. R. Silva, linux-hardening
purex_item.iocb is defined as a 64-element u8 array, but 64 is the
minimum size and it can be allocated larger. This makes it a standard
empty flex array.
This was motivated by field-spanning write warnings during FPIN testing.
https://lore.kernel.org/linux-nvme/20250709211919.49100-1-bgurney@redhat.com/
> kernel: memcpy: detected field-spanning write (size 60) of single field
> "((uint8_t *)fpin_pkt + buffer_copy_offset)"
> at drivers/scsi/qla2xxx/qla_isr.c:1221 (size 44)
I removed the outer wrapper from the iocb flex array, so that it can be
linked to `purex_item.size` with `__counted_by`.
These changes remove the default minimum 64-byte allocation, requiring
further changes.
In `struct scsi_qla_host` the embedded `default_item` is now followed
by `__default_item_iocb[QLA_DEFAULT_PAYLOAD_SIZE]` to reserve space
that will be used as `default_item.iocb`. This is wrapped using the
`TRAILING_OVERLAP()` macro helper, which effectively creates a union
between flexible-array member `default_item.iocb` and `__default_item_iocb`.
Since `struct pure_item` now contains a flexible-array member, the
helper must be placed at the end of `struct scsi_qla_host` to prevent
a `-Wflex-array-member-not-at-end` warning.
`qla24xx_alloc_purex_item()` is adjusted to no longer expect the
default minimum size to be part of `sizeof(struct purex_item)`,
the entire flexible array size is added to the structure size for
allocation.
This also slightly changes the layout of the purex_item struct, as
2-bytes of padding are added between `size` and `iocb`. The resulting
size is the same, but iocb is shifted 2-bytes (the original `purex_item`
structure was padded at the end, after the 64-byte defined array size).
I don't think this is a problem.
Tested-by: Bryan Gurney <bgurney@redhat.com>
Co-developed-by: Chris Leech <cleech@redhat.com>
Signed-off-by: Chris Leech <cleech@redhat.com>
Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
---
drivers/scsi/qla2xxx/qla_def.h | 10 ++++++----
drivers/scsi/qla2xxx/qla_isr.c | 17 ++++++++---------
drivers/scsi/qla2xxx/qla_nvme.c | 2 +-
drivers/scsi/qla2xxx/qla_os.c | 5 +++--
4 files changed, 18 insertions(+), 16 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index cb95b7b12051..604e66bead1e 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -4890,9 +4890,7 @@ struct purex_item {
struct purex_item *pkt);
atomic_t in_use;
uint16_t size;
- struct {
- uint8_t iocb[64];
- } iocb;
+ uint8_t iocb[] __counted_by(size);
};
#include "qla_edif.h"
@@ -5101,7 +5099,6 @@ typedef struct scsi_qla_host {
struct list_head head;
spinlock_t lock;
} purex_list;
- struct purex_item default_item;
struct name_list_extended gnl;
/* Count of active session/fcport */
@@ -5130,6 +5127,11 @@ typedef struct scsi_qla_host {
#define DPORT_DIAG_IN_PROGRESS BIT_0
#define DPORT_DIAG_CHIP_RESET_IN_PROGRESS BIT_1
uint16_t dport_status;
+
+ /* Must be last --ends in a flexible-array member. */
+ TRAILING_OVERLAP(struct purex_item, default_item, iocb,
+ uint8_t __default_item_iocb[QLA_DEFAULT_PAYLOAD_SIZE];
+ );
} scsi_qla_host_t;
struct qla27xx_image_status {
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index c4c6b5c6658c..4559b490614d 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -1077,17 +1077,17 @@ static struct purex_item *
qla24xx_alloc_purex_item(scsi_qla_host_t *vha, uint16_t size)
{
struct purex_item *item = NULL;
- uint8_t item_hdr_size = sizeof(*item);
if (size > QLA_DEFAULT_PAYLOAD_SIZE) {
- item = kzalloc(item_hdr_size +
- (size - QLA_DEFAULT_PAYLOAD_SIZE), GFP_ATOMIC);
+ item = kzalloc(struct_size(item, iocb, size), GFP_ATOMIC);
} else {
if (atomic_inc_return(&vha->default_item.in_use) == 1) {
item = &vha->default_item;
goto initialize_purex_header;
} else {
- item = kzalloc(item_hdr_size, GFP_ATOMIC);
+ item = kzalloc(
+ struct_size(item, iocb, QLA_DEFAULT_PAYLOAD_SIZE),
+ GFP_ATOMIC);
}
}
if (!item) {
@@ -1127,17 +1127,16 @@ qla24xx_queue_purex_item(scsi_qla_host_t *vha, struct purex_item *pkt,
* @vha: SCSI driver HA context
* @pkt: ELS packet
*/
-static struct purex_item
-*qla24xx_copy_std_pkt(struct scsi_qla_host *vha, void *pkt)
+static struct purex_item *
+qla24xx_copy_std_pkt(struct scsi_qla_host *vha, void *pkt)
{
struct purex_item *item;
- item = qla24xx_alloc_purex_item(vha,
- QLA_DEFAULT_PAYLOAD_SIZE);
+ item = qla24xx_alloc_purex_item(vha, QLA_DEFAULT_PAYLOAD_SIZE);
if (!item)
return item;
- memcpy(&item->iocb, pkt, sizeof(item->iocb));
+ memcpy(&item->iocb, pkt, QLA_DEFAULT_PAYLOAD_SIZE);
return item;
}
diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c
index 8ee2e337c9e1..92488890bc04 100644
--- a/drivers/scsi/qla2xxx/qla_nvme.c
+++ b/drivers/scsi/qla2xxx/qla_nvme.c
@@ -1308,7 +1308,7 @@ void qla2xxx_process_purls_iocb(void **pkt, struct rsp_que **rsp)
ql_dbg(ql_dbg_unsol, vha, 0x2121,
"PURLS OP[%01x] size %d xchg addr 0x%x portid %06x\n",
- item->iocb.iocb[3], item->size, uctx->exchange_address,
+ item->iocb[3], item->size, uctx->exchange_address,
fcport->d_id.b24);
/* +48 0 1 2 3 4 5 6 7 8 9 A B C D E F
* ----- -----------------------------------------------
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index d4b484c0fd9d..253f802605d6 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -6459,9 +6459,10 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
void
qla24xx_free_purex_item(struct purex_item *item)
{
- if (item == &item->vha->default_item)
+ if (item == &item->vha->default_item) {
memset(&item->vha->default_item, 0, sizeof(struct purex_item));
- else
+ memset(&item->vha->__default_item_iocb, 0, QLA_DEFAULT_PAYLOAD_SIZE);
+ } else
kfree(item);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH][next] scsi: qla2xxx: Fix memcpy field-spanning write issue
2025-07-30 22:54 [PATCH][next] scsi: qla2xxx: Fix memcpy field-spanning write issue Gustavo A. R. Silva
@ 2025-07-31 3:17 ` Martin K. Petersen
2025-08-12 13:52 ` Gustavo A. R. Silva
0 siblings, 1 reply; 3+ messages in thread
From: Martin K. Petersen @ 2025-07-31 3:17 UTC (permalink / raw)
To: Gustavo A. R. Silva
Cc: Chris Leech, Bryan Gurney, Nilesh Javali, James E.J. Bottomley,
Martin K. Petersen, GR-QLogic-Storage-Upstream, linux-scsi,
linux-kernel, linux-hardening
Gustavo,
> +
> + /* Must be last --ends in a flexible-array member. */
> + TRAILING_OVERLAP(struct purex_item, default_item, iocb,
> + uint8_t __default_item_iocb[QLA_DEFAULT_PAYLOAD_SIZE];
> + );
> } scsi_qla_host_t;
Looks OK to me but will have to wait for TRAILING_OVERLAP() to land.
--
Martin K. Petersen
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH][next] scsi: qla2xxx: Fix memcpy field-spanning write issue
2025-07-31 3:17 ` Martin K. Petersen
@ 2025-08-12 13:52 ` Gustavo A. R. Silva
0 siblings, 0 replies; 3+ messages in thread
From: Gustavo A. R. Silva @ 2025-08-12 13:52 UTC (permalink / raw)
To: Martin K. Petersen, Gustavo A. R. Silva
Cc: Chris Leech, Bryan Gurney, Nilesh Javali, James E.J. Bottomley,
GR-QLogic-Storage-Upstream, linux-scsi, linux-kernel,
linux-hardening
Hi Martin,
On 31/07/25 12:17, Martin K. Petersen wrote:
>
> Gustavo,
>
>> +
>> + /* Must be last --ends in a flexible-array member. */
>> + TRAILING_OVERLAP(struct purex_item, default_item, iocb,
>> + uint8_t __default_item_iocb[QLA_DEFAULT_PAYLOAD_SIZE];
>> + );
>> } scsi_qla_host_t;
>
> Looks OK to me but will have to wait for TRAILING_OVERLAP() to land.
>
The helper is already out in -rc1. :)
Thanks!
-Gustavo
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-08-12 13:54 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-30 22:54 [PATCH][next] scsi: qla2xxx: Fix memcpy field-spanning write issue Gustavo A. R. Silva
2025-07-31 3:17 ` Martin K. Petersen
2025-08-12 13:52 ` Gustavo A. R. Silva
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.