From: Ranjan Kumar <ranjan.kumar@broadcom.com>
To: linux-scsi@vger.kernel.org, martin.petersen@oracle.com
Cc: sathya.prakash@broadcom.com, chandrakanth.patil@broadcom.com,
sweeti.vandure@broadcom.com, vishakhavc@google.com,
ipylypiv@google.com, Ranjan Kumar <ranjan.kumar@broadcom.com>,
Sashiko <sashiko-bot@kernel.org>
Subject: [PATCH 18/21] scsi: mpi3mr: Fix partly written and lost entries in the log data buffer
Date: Wed, 4 Nov 2026 17:30:59 +0530 [thread overview]
Message-ID: <20261104120103.503871-19-ranjan.kumar@broadcom.com> (raw)
In-Reply-To: <20261104120103.503871-1-ranjan.kumar@broadcom.com>
Log data events are saved from the event handlers while the get and enable
ioctls read and publish the same buffer, index and entry size, all without
a lock. A read can return an entry that is only partly written, and two
events handled at the same time can take the same index so one is lost.
Add a lock for the log data buffer and take it in the writer and in both
ioctls.
Fixes: f5e6d5a34376 ("scsi: mpi3mr: Add support for driver commands")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260825210411.301535-1-chandrakanth.patil@broadcom.com?part=5
Signed-off-by: Ranjan Kumar <ranjan.kumar@broadcom.com>
---
drivers/scsi/mpi3mr/mpi3mr.h | 2 ++
drivers/scsi/mpi3mr/mpi3mr_app.c | 43 +++++++++++++++++++++++---------
drivers/scsi/mpi3mr/mpi3mr_fw.c | 3 +++
drivers/scsi/mpi3mr/mpi3mr_os.c | 1 +
4 files changed, 37 insertions(+), 12 deletions(-)
diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h
index deb8a1eea917..c87c85adb680 100644
--- a/drivers/scsi/mpi3mr/mpi3mr.h
+++ b/drivers/scsi/mpi3mr/mpi3mr.h
@@ -1165,6 +1165,7 @@ struct scmd_priv {
* @logdata_buf: Circular buffer to store log data entries
* @logdata_buf_idx: Index of entry in buffer to store
* @logdata_entry_sz: log data entry size
+ * @logdata_lock: Lock for the log data buffer, index and entry size
* @adm_req_q_bar_writeq_lock: Admin request queue lock
* @adm_reply_q_bar_writeq_lock: Admin reply queue lock
* @pend_large_data_sz: Counter to track pending large data
@@ -1374,6 +1375,7 @@ struct mpi3mr_ioc {
u8 *logdata_buf;
u16 logdata_buf_idx;
u16 logdata_entry_sz;
+ spinlock_t logdata_lock;
spinlock_t adm_req_q_bar_writeq_lock;
spinlock_t adm_reply_q_bar_writeq_lock;
diff --git a/drivers/scsi/mpi3mr/mpi3mr_app.c b/drivers/scsi/mpi3mr/mpi3mr_app.c
index bf2c8c413a80..310ead2c644e 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_app.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_app.c
@@ -1309,20 +1309,27 @@ static long mpi3mr_enable_logdata(struct mpi3mr_ioc *mrioc,
struct bsg_job *job)
{
struct mpi3mr_logdata_enable logdata_enable;
+ unsigned long flags;
+ u16 entry_sz;
+ u8 *buf;
if (!mrioc->logdata_buf) {
if (mrioc->reply_sz <=
(sizeof(struct mpi3_event_notification_reply) - 4))
return -EINVAL;
- mrioc->logdata_entry_sz =
+ entry_sz =
(mrioc->reply_sz - (sizeof(struct mpi3_event_notification_reply) - 4))
+ MPI3MR_BSG_LOGDATA_ENTRY_HEADER_SZ;
- mrioc->logdata_buf_idx = 0;
- mrioc->logdata_buf = kcalloc(MPI3MR_BSG_LOGDATA_MAX_ENTRIES,
- mrioc->logdata_entry_sz, GFP_KERNEL);
-
- if (!mrioc->logdata_buf)
+ buf = kcalloc(MPI3MR_BSG_LOGDATA_MAX_ENTRIES, entry_sz,
+ GFP_KERNEL);
+ if (!buf)
return -ENOMEM;
+
+ spin_lock_irqsave(&mrioc->logdata_lock, flags);
+ mrioc->logdata_entry_sz = entry_sz;
+ mrioc->logdata_buf_idx = 0;
+ mrioc->logdata_buf = buf;
+ spin_unlock_irqrestore(&mrioc->logdata_lock, flags);
}
memset(&logdata_enable, 0, sizeof(logdata_enable));
@@ -1349,11 +1356,15 @@ static long mpi3mr_enable_logdata(struct mpi3mr_ioc *mrioc,
static long mpi3mr_get_logdata(struct mpi3mr_ioc *mrioc,
struct bsg_job *job)
{
- u16 entry_sz = mrioc->logdata_entry_sz;
+ unsigned long flags;
+ u16 entry_sz;
u32 num_entries, sz;
+ long rval = -EINVAL;
+ spin_lock_irqsave(&mrioc->logdata_lock, flags);
+ entry_sz = mrioc->logdata_entry_sz;
if ((!mrioc->logdata_buf) || (job->request_payload.payload_len < entry_sz))
- return -EINVAL;
+ goto out;
num_entries = job->request_payload.payload_len / entry_sz;
if (num_entries > MPI3MR_BSG_LOGDATA_MAX_ENTRIES)
@@ -1364,9 +1375,11 @@ static long mpi3mr_get_logdata(struct mpi3mr_ioc *mrioc,
sg_copy_from_buffer(job->request_payload.sg_list,
job->request_payload.sg_cnt,
mrioc->logdata_buf, sz);
- return 0;
+ rval = 0;
}
- return -EINVAL;
+out:
+ spin_unlock_irqrestore(&mrioc->logdata_lock, flags);
+ return rval;
}
/**
@@ -3023,13 +3036,18 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
void mpi3mr_app_save_logdata_th(struct mpi3mr_ioc *mrioc, char *event_data,
u16 event_data_size)
{
- u32 index = mrioc->logdata_buf_idx;
+ u32 index;
size_t entry_payload_len, sz;
struct mpi3mr_logdata_entry *entry;
+ unsigned long flags;
- if (!(mrioc->logdata_buf))
+ spin_lock_irqsave(&mrioc->logdata_lock, flags);
+ if (!(mrioc->logdata_buf)) {
+ spin_unlock_irqrestore(&mrioc->logdata_lock, flags);
return;
+ }
+ index = mrioc->logdata_buf_idx;
entry = (struct mpi3mr_logdata_entry *)
(mrioc->logdata_buf + (index * mrioc->logdata_entry_sz));
entry->valid_entry = 1;
@@ -3042,6 +3060,7 @@ void mpi3mr_app_save_logdata_th(struct mpi3mr_ioc *mrioc, char *event_data,
memcpy(entry->data, event_data, sz);
mrioc->logdata_buf_idx =
((++index) % MPI3MR_BSG_LOGDATA_MAX_ENTRIES);
+ spin_unlock_irqrestore(&mrioc->logdata_lock, flags);
atomic64_inc(&event_counter);
}
diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c
index 6d43112aebb7..637cf575e6bb 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_fw.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c
@@ -5029,6 +5029,7 @@ void mpi3mr_memset_buffers(struct mpi3mr_ioc *mrioc)
void mpi3mr_free_mem(struct mpi3mr_ioc *mrioc)
{
u16 i, j;
+ unsigned long flags;
struct mpi3mr_intr_info *intr_info;
struct diag_buffer_desc *diag_buffer;
@@ -5197,8 +5198,10 @@ void mpi3mr_free_mem(struct mpi3mr_ioc *mrioc)
kfree(mrioc->throttle_groups);
mrioc->throttle_groups = NULL;
+ spin_lock_irqsave(&mrioc->logdata_lock, flags);
kfree(mrioc->logdata_buf);
mrioc->logdata_buf = NULL;
+ spin_unlock_irqrestore(&mrioc->logdata_lock, flags);
}
diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c
index ed9e83a4119c..7a7ef199d3cd 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_os.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_os.c
@@ -5717,6 +5717,7 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
spin_lock_init(&mrioc->adm_reply_q_bar_writeq_lock);
spin_lock_init(&mrioc->sas_node_lock);
spin_lock_init(&mrioc->trigger_lock);
+ spin_lock_init(&mrioc->logdata_lock);
INIT_LIST_HEAD(&mrioc->fwevt_list);
INIT_LIST_HEAD(&mrioc->tgtdev_list);
--
2.47.3
next prev parent reply other threads:[~2026-11-04 12:10 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-04 12:00 [PATCH 00/21] scsi: mpi3mr: Fix issues reported by Sashiko Ranjan Kumar
2026-11-04 12:00 ` [PATCH 01/21] scsi: mpi3mr: Fix out-of-bounds read of the BSG request Ranjan Kumar
2026-11-04 12:00 ` [PATCH 02/21] scsi: mpi3mr: Fix integer wrap in BSG buffer entry lengths Ranjan Kumar
2026-11-04 12:00 ` [PATCH 03/21] scsi: mpi3mr: Remove redundant BSG buffer length checks Ranjan Kumar
2026-11-04 12:00 ` [PATCH 04/21] scsi: mpi3mr: Fix PRP list leak in BSG passthrough Ranjan Kumar
2026-11-04 12:00 ` [PATCH 05/21] scsi: mpi3mr: Fix reposting of invalid reply address on the admin queue Ranjan Kumar
2026-11-04 12:00 ` [PATCH 06/21] scsi: mpi3mr: Fix endianness of device handles in BSG requests Ranjan Kumar
2026-11-04 12:00 ` [PATCH 07/21] scsi: mpi3mr: Fix integer overflow in the HDB upload bounds check Ranjan Kumar
2026-11-04 12:00 ` [PATCH 08/21] scsi: mpi3mr: Fix integer overflow in the log data size calculation Ranjan Kumar
2026-11-04 12:00 ` [PATCH 09/21] scsi: mpi3mr: Queue DEVICE_INFO_CHANGED events to the bottom half again Ranjan Kumar
2026-11-04 12:00 ` [PATCH 10/21] scsi: mpi3mr: Fix target device reference leaks Ranjan Kumar
2026-11-04 12:00 ` [PATCH 11/21] scsi: mpi3mr: Fix the 32 bit shift when building the phy mask Ranjan Kumar
2026-11-04 12:00 ` [PATCH 12/21] scsi: mpi3mr: Fix empty device list race in the all targets query Ranjan Kumar
2026-11-04 12:00 ` [PATCH 13/21] scsi: mpi3mr: Fix the lowest phy number for phys 32 and above Ranjan Kumar
2026-11-04 12:00 ` [PATCH 14/21] scsi: mpi3mr: Fix target private data use after free in BSG passthrough Ranjan Kumar
2026-11-04 12:28 ` sashiko-bot
2026-11-04 12:00 ` [PATCH 15/21] scsi: mpi3mr: Fix block_io accounting when a target is re-created during BSG Ranjan Kumar
2026-11-04 12:28 ` sashiko-bot
2026-11-04 12:00 ` [PATCH 16/21] scsi: mpi3mr: Fix sense buffer use after free on BSG command completion Ranjan Kumar
2026-11-04 12:26 ` sashiko-bot
2026-11-04 12:00 ` [PATCH 17/21] scsi: mpi3mr: Reject a too small reply size when enabling log data Ranjan Kumar
2026-11-04 12:00 ` Ranjan Kumar [this message]
2026-11-04 12:01 ` [PATCH 19/21] scsi: mpi3mr: Fix byte order handling in the NVMe passthrough commands Ranjan Kumar
2026-11-04 12:01 ` [PATCH 20/21] scsi: mpi3mr: Fix byte order of the BSG status reply Ranjan Kumar
2026-11-04 12:01 ` [PATCH 21/21] scsi: mpi3mr: Use the correct conversion for the diag buffer post request Ranjan Kumar
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=20261104120103.503871-19-ranjan.kumar@broadcom.com \
--to=ranjan.kumar@broadcom.com \
--cc=chandrakanth.patil@broadcom.com \
--cc=ipylypiv@google.com \
--cc=linux-scsi@vger.kernel.org \
--cc=martin.petersen@oracle.com \
--cc=sashiko-bot@kernel.org \
--cc=sathya.prakash@broadcom.com \
--cc=sweeti.vandure@broadcom.com \
--cc=vishakhavc@google.com \
/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 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.