mirror of
https://github.com/SCST-project/scst.git
synced 2026-10-22 06:02:33 +00:00
qla2x00t-32gbit: Zero SFP DMA buffer in FRU/I2C bsg handlers
The FRU and I2C bsg handlers stage their transfer in a DMA_POOL_SIZE
(256-byte) bounce buffer obtained from dma_pool_alloc(), which does not
zero the allocation. They initialize only a few leading bytes before
handing the buffer to qla2x00_write_sfp().
qla2x00_write_sfp() can override the transfer length with a user-supplied
value:
if (len == 1)
opt |= BIT_0;
if (opt & BIT_0)
len = *sfp;
*sfp is the first byte of the (user-controlled) payload, so len can grow
up to 255. The device then DMA-reads len bytes from the 256-byte pool
buffer. Since only a small prefix was written
(e.g. MAX_FRU_SIZE == 36 bytes for a FRU version, one byte for a FRU
status register), the hardware reads past the initialized region and
writes up to ~219 bytes of stale DMA-pool heap memory to the device
flash.
Allocate the buffer with dma_pool_zalloc() in all five FRU/I2C handlers
so any bytes beyond the initialized data are zero rather than stale heap
contents.
Fixes: 697a4bc69159 ("[SCSI] qla2xxx: Provide method for updating I2C attached VPD.")
Fixes: 9ebb5d9c69f1 ("[SCSI] qla2xxx: Add I2C BSG interface.")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-dev@google.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://patch.msgid.link/20260730155838.2119230-32-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
[ commit b47d4a1547d9ef21b2e9d1a739fe2204d4be05dc upstream ]
This commit is contained in:
committed by
Gleb Chesnokov
parent
132ecbeab3
commit
de730f4d80
@@ -2011,7 +2011,7 @@ qla2x00_update_fru_versions(BSG_JOB_TYPE *bsg_job)
|
||||
struct qla_image_version *image;
|
||||
uint32_t count;
|
||||
dma_addr_t sfp_dma;
|
||||
void *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
|
||||
void *sfp = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
|
||||
|
||||
if (!sfp) {
|
||||
bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
|
||||
@@ -2069,7 +2069,7 @@ qla2x00_read_fru_status(BSG_JOB_TYPE *bsg_job)
|
||||
uint8_t bsg[DMA_POOL_SIZE] = {};
|
||||
struct qla_status_reg *sr = (void *)bsg;
|
||||
dma_addr_t sfp_dma;
|
||||
uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
|
||||
uint8_t *sfp = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
|
||||
|
||||
if (!sfp) {
|
||||
bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
|
||||
@@ -2120,7 +2120,7 @@ qla2x00_write_fru_status(BSG_JOB_TYPE *bsg_job)
|
||||
uint8_t bsg[DMA_POOL_SIZE] = {};
|
||||
struct qla_status_reg *sr = (void *)bsg;
|
||||
dma_addr_t sfp_dma;
|
||||
uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
|
||||
uint8_t *sfp = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
|
||||
|
||||
if (!sfp) {
|
||||
bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
|
||||
@@ -2167,7 +2167,7 @@ qla2x00_write_i2c(BSG_JOB_TYPE *bsg_job)
|
||||
uint8_t bsg[DMA_POOL_SIZE] = {};
|
||||
struct qla_i2c_access *i2c = (void *)bsg;
|
||||
dma_addr_t sfp_dma;
|
||||
uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
|
||||
uint8_t *sfp = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
|
||||
|
||||
if (!sfp) {
|
||||
bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
|
||||
@@ -2213,7 +2213,7 @@ qla2x00_read_i2c(BSG_JOB_TYPE *bsg_job)
|
||||
uint8_t bsg[DMA_POOL_SIZE] = {};
|
||||
struct qla_i2c_access *i2c = (void *)bsg;
|
||||
dma_addr_t sfp_dma;
|
||||
uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
|
||||
uint8_t *sfp = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
|
||||
|
||||
if (!sfp) {
|
||||
bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
|
||||
|
||||
Reference in New Issue
Block a user