lpfc_rx_monitor_report() formats each record into a stack buffer, then
appends it with seq_buf_puts(), relying on seq_buf_puts() appending
nothing when a string does not fit: the debugfs output then ends at the
last whole record, and the record left out is read in full next time.
The next patch makes seq_buf_puts() copy as much as fits instead, as
seq_buf_printf() and strlcat() do.

Print each record with seq_buf_printf(), and when it does not fit, end
the string where the record began, since the reader takes the buffer up
to its NUL. This also takes the DBG_LOG_STR_SZ buffer off the stack.

Build tested ARCH=x86_64 with GCC 16.2.0, CONFIG_SCSI_LPFC=m and W=1.

Assisted-by: LLM
Signed-off-by: Kees Cook <[email protected]>
---
 drivers/scsi/lpfc/lpfc_sli.c | 45 +++++++++++++++++++++---------------
 1 file changed, 27 insertions(+), 18 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index cfa4371169f1..a7b1ea67ed98 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -8108,7 +8108,6 @@ u32 lpfc_rx_monitor_report(struct lpfc_hba *phba,
        spinlock_t *ring_lock = &rx_monitor->lock;
        u32 ring_size = rx_monitor->entries;
        u32 cnt = 0;
-       char tmp[DBG_LOG_STR_SZ] = {0};
        bool log_to_kmsg = (!buf || !buf_len) ? true : false;
        struct seq_buf s;
 
@@ -8133,27 +8132,37 @@ u32 lpfc_rx_monitor_report(struct lpfc_hba *phba,
 
                /* Read out this entry's data. */
                if (!log_to_kmsg) {
+                       unsigned int len;
+
+                       /* A header that did not fit leaves no room. */
+                       if (seq_buf_has_overflowed(&s))
+                               break;
+                       len = seq_buf_used(&s);
+
+                       seq_buf_printf(&s,
+                                      
"%03d:\t%-16llu%-16llu%-16llu%-16llu%-8llu%-8llu%-8llu%-8u%-8u%-8u%u(%u)\n",
+                                      *head_idx,
+                                      entry->max_bytes_per_interval,
+                                      entry->cmf_bytes,
+                                      entry->total_bytes,
+                                      entry->rcv_bytes,
+                                      entry->avg_io_latency,
+                                      entry->avg_io_size,
+                                      entry->max_read_cnt,
+                                      entry->cmf_busy, entry->io_cnt,
+                                      entry->cmf_info,
+                                      entry->timer_utilization,
+                                      entry->timer_interval);
+
                        /*
                         * Drop a record whole if it does not fit, without
-                        * consuming its ring entry.
+                        * consuming its ring entry: the reader takes the
+                        * string up to its NUL.
                         */
-                       scnprintf(tmp, sizeof(tmp),
-                                 
"%03d:\t%-16llu%-16llu%-16llu%-16llu%-8llu%-8llu%-8llu%-8u%-8u%-8u%u(%u)\n",
-                                 *head_idx,
-                                 entry->max_bytes_per_interval,
-                                 entry->cmf_bytes,
-                                 entry->total_bytes,
-                                 entry->rcv_bytes,
-                                 entry->avg_io_latency,
-                                 entry->avg_io_size,
-                                 entry->max_read_cnt,
-                                 entry->cmf_busy, entry->io_cnt,
-                                 entry->cmf_info,
-                                 entry->timer_utilization,
-                                 entry->timer_interval);
-
-                       if (seq_buf_puts(&s, tmp) < 0)
+                       if (seq_buf_has_overflowed(&s)) {
+                               buf[len] = '\0';
                                break;
+                       }
                } else {
                        lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
                                        "4410 %02u: MBPI %llu Xmit %llu "
-- 
2.55.0


Reply via email to