Commit 2605fbd8 authored by Takashi Iwai's avatar Takashi Iwai Committed by Martin K. Petersen

scsi: fnic: Use scnprintf() for avoiding potential buffer overflow

Since snprintf() returns the would-be-output size instead of the actual
output size, the succeeding calls may go beyond the given buffer limit.
Fix it by replacing with scnprintf().

Link: https://lore.kernel.org/r/20200315094241.9086-4-tiwai@suse.de
Cc: "James E . J . Bottomley" <jejb@linux.ibm.com>
Cc: "Martin K . Petersen" <martin.petersen@oracle.com>
Cc: Satish Kharat <satishkh@cisco.com>
Cc: Sesidhar Baddela <sebaddel@cisco.com>
Cc: Karan Tilak Kumar <kartilak@cisco.com>
Cc: linux-scsi@vger.kernel.org
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 7cd1615e
...@@ -138,7 +138,7 @@ int fnic_get_trace_data(fnic_dbgfs_t *fnic_dbgfs_prt) ...@@ -138,7 +138,7 @@ int fnic_get_trace_data(fnic_dbgfs_t *fnic_dbgfs_prt)
* Dump trace buffer entry to memory file * Dump trace buffer entry to memory file
* and increment read index @rd_idx * and increment read index @rd_idx
*/ */
len += snprintf(fnic_dbgfs_prt->buffer + len, len += scnprintf(fnic_dbgfs_prt->buffer + len,
(trace_max_pages * PAGE_SIZE * 3) - len, (trace_max_pages * PAGE_SIZE * 3) - len,
"%16llu.%09lu %-50s %8x %8x %16llx %16llx " "%16llu.%09lu %-50s %8x %8x %16llx %16llx "
"%16llx %16llx %16llx\n", (u64)val.tv_sec, "%16llx %16llx %16llx\n", (u64)val.tv_sec,
...@@ -180,7 +180,7 @@ int fnic_get_trace_data(fnic_dbgfs_t *fnic_dbgfs_prt) ...@@ -180,7 +180,7 @@ int fnic_get_trace_data(fnic_dbgfs_t *fnic_dbgfs_prt)
* Dump trace buffer entry to memory file * Dump trace buffer entry to memory file
* and increment read index @rd_idx * and increment read index @rd_idx
*/ */
len += snprintf(fnic_dbgfs_prt->buffer + len, len += scnprintf(fnic_dbgfs_prt->buffer + len,
(trace_max_pages * PAGE_SIZE * 3) - len, (trace_max_pages * PAGE_SIZE * 3) - len,
"%16llu.%09lu %-50s %8x %8x %16llx %16llx " "%16llu.%09lu %-50s %8x %8x %16llx %16llx "
"%16llx %16llx %16llx\n", (u64)val.tv_sec, "%16llx %16llx %16llx\n", (u64)val.tv_sec,
...@@ -220,12 +220,12 @@ int fnic_get_stats_data(struct stats_debug_info *debug, ...@@ -220,12 +220,12 @@ int fnic_get_stats_data(struct stats_debug_info *debug,
struct timespec64 val1, val2; struct timespec64 val1, val2;
ktime_get_real_ts64(&val1); ktime_get_real_ts64(&val1);
len = snprintf(debug->debug_buffer + len, buf_size - len, len = scnprintf(debug->debug_buffer + len, buf_size - len,
"------------------------------------------\n" "------------------------------------------\n"
"\t\tTime\n" "\t\tTime\n"
"------------------------------------------\n"); "------------------------------------------\n");
len += snprintf(debug->debug_buffer + len, buf_size - len, len += scnprintf(debug->debug_buffer + len, buf_size - len,
"Current time : [%lld:%ld]\n" "Current time : [%lld:%ld]\n"
"Last stats reset time: [%lld:%09ld]\n" "Last stats reset time: [%lld:%09ld]\n"
"Last stats read time: [%lld:%ld]\n" "Last stats read time: [%lld:%ld]\n"
...@@ -243,11 +243,11 @@ int fnic_get_stats_data(struct stats_debug_info *debug, ...@@ -243,11 +243,11 @@ int fnic_get_stats_data(struct stats_debug_info *debug,
stats->stats_timestamps.last_read_time = val1; stats->stats_timestamps.last_read_time = val1;
len += snprintf(debug->debug_buffer + len, buf_size - len, len += scnprintf(debug->debug_buffer + len, buf_size - len,
"------------------------------------------\n" "------------------------------------------\n"
"\t\tIO Statistics\n" "\t\tIO Statistics\n"
"------------------------------------------\n"); "------------------------------------------\n");
len += snprintf(debug->debug_buffer + len, buf_size - len, len += scnprintf(debug->debug_buffer + len, buf_size - len,
"Number of Active IOs: %lld\nMaximum Active IOs: %lld\n" "Number of Active IOs: %lld\nMaximum Active IOs: %lld\n"
"Number of IOs: %lld\nNumber of IO Completions: %lld\n" "Number of IOs: %lld\nNumber of IO Completions: %lld\n"
"Number of IO Failures: %lld\nNumber of IO NOT Found: %lld\n" "Number of IO Failures: %lld\nNumber of IO NOT Found: %lld\n"
...@@ -280,16 +280,16 @@ int fnic_get_stats_data(struct stats_debug_info *debug, ...@@ -280,16 +280,16 @@ int fnic_get_stats_data(struct stats_debug_info *debug,
(u64)atomic64_read(&stats->io_stats.io_btw_10000_to_30000_msec), (u64)atomic64_read(&stats->io_stats.io_btw_10000_to_30000_msec),
(u64)atomic64_read(&stats->io_stats.io_greater_than_30000_msec)); (u64)atomic64_read(&stats->io_stats.io_greater_than_30000_msec));
len += snprintf(debug->debug_buffer + len, buf_size - len, len += scnprintf(debug->debug_buffer + len, buf_size - len,
"\nCurrent Max IO time : %lld\n", "\nCurrent Max IO time : %lld\n",
(u64)atomic64_read(&stats->io_stats.current_max_io_time)); (u64)atomic64_read(&stats->io_stats.current_max_io_time));
len += snprintf(debug->debug_buffer + len, buf_size - len, len += scnprintf(debug->debug_buffer + len, buf_size - len,
"\n------------------------------------------\n" "\n------------------------------------------\n"
"\t\tAbort Statistics\n" "\t\tAbort Statistics\n"
"------------------------------------------\n"); "------------------------------------------\n");
len += snprintf(debug->debug_buffer + len, buf_size - len, len += scnprintf(debug->debug_buffer + len, buf_size - len,
"Number of Aborts: %lld\n" "Number of Aborts: %lld\n"
"Number of Abort Failures: %lld\n" "Number of Abort Failures: %lld\n"
"Number of Abort Driver Timeouts: %lld\n" "Number of Abort Driver Timeouts: %lld\n"
...@@ -318,12 +318,12 @@ int fnic_get_stats_data(struct stats_debug_info *debug, ...@@ -318,12 +318,12 @@ int fnic_get_stats_data(struct stats_debug_info *debug,
(u64)atomic64_read(&stats->abts_stats.abort_issued_btw_50_to_60_sec), (u64)atomic64_read(&stats->abts_stats.abort_issued_btw_50_to_60_sec),
(u64)atomic64_read(&stats->abts_stats.abort_issued_greater_than_60_sec)); (u64)atomic64_read(&stats->abts_stats.abort_issued_greater_than_60_sec));
len += snprintf(debug->debug_buffer + len, buf_size - len, len += scnprintf(debug->debug_buffer + len, buf_size - len,
"\n------------------------------------------\n" "\n------------------------------------------\n"
"\t\tTerminate Statistics\n" "\t\tTerminate Statistics\n"
"------------------------------------------\n"); "------------------------------------------\n");
len += snprintf(debug->debug_buffer + len, buf_size - len, len += scnprintf(debug->debug_buffer + len, buf_size - len,
"Number of Terminates: %lld\n" "Number of Terminates: %lld\n"
"Maximum Terminates: %lld\n" "Maximum Terminates: %lld\n"
"Number of Terminate Driver Timeouts: %lld\n" "Number of Terminate Driver Timeouts: %lld\n"
...@@ -337,12 +337,12 @@ int fnic_get_stats_data(struct stats_debug_info *debug, ...@@ -337,12 +337,12 @@ int fnic_get_stats_data(struct stats_debug_info *debug,
(u64)atomic64_read(&stats->term_stats.terminate_io_not_found), (u64)atomic64_read(&stats->term_stats.terminate_io_not_found),
(u64)atomic64_read(&stats->term_stats.terminate_failures)); (u64)atomic64_read(&stats->term_stats.terminate_failures));
len += snprintf(debug->debug_buffer + len, buf_size - len, len += scnprintf(debug->debug_buffer + len, buf_size - len,
"\n------------------------------------------\n" "\n------------------------------------------\n"
"\t\tReset Statistics\n" "\t\tReset Statistics\n"
"------------------------------------------\n"); "------------------------------------------\n");
len += snprintf(debug->debug_buffer + len, buf_size - len, len += scnprintf(debug->debug_buffer + len, buf_size - len,
"Number of Device Resets: %lld\n" "Number of Device Resets: %lld\n"
"Number of Device Reset Failures: %lld\n" "Number of Device Reset Failures: %lld\n"
"Number of Device Reset Aborts: %lld\n" "Number of Device Reset Aborts: %lld\n"
...@@ -368,12 +368,12 @@ int fnic_get_stats_data(struct stats_debug_info *debug, ...@@ -368,12 +368,12 @@ int fnic_get_stats_data(struct stats_debug_info *debug,
&stats->reset_stats.fnic_reset_completions), &stats->reset_stats.fnic_reset_completions),
(u64)atomic64_read(&stats->reset_stats.fnic_reset_failures)); (u64)atomic64_read(&stats->reset_stats.fnic_reset_failures));
len += snprintf(debug->debug_buffer + len, buf_size - len, len += scnprintf(debug->debug_buffer + len, buf_size - len,
"\n------------------------------------------\n" "\n------------------------------------------\n"
"\t\tFirmware Statistics\n" "\t\tFirmware Statistics\n"
"------------------------------------------\n"); "------------------------------------------\n");
len += snprintf(debug->debug_buffer + len, buf_size - len, len += scnprintf(debug->debug_buffer + len, buf_size - len,
"Number of Active FW Requests %lld\n" "Number of Active FW Requests %lld\n"
"Maximum FW Requests: %lld\n" "Maximum FW Requests: %lld\n"
"Number of FW out of resources: %lld\n" "Number of FW out of resources: %lld\n"
...@@ -383,12 +383,12 @@ int fnic_get_stats_data(struct stats_debug_info *debug, ...@@ -383,12 +383,12 @@ int fnic_get_stats_data(struct stats_debug_info *debug,
(u64)atomic64_read(&stats->fw_stats.fw_out_of_resources), (u64)atomic64_read(&stats->fw_stats.fw_out_of_resources),
(u64)atomic64_read(&stats->fw_stats.io_fw_errs)); (u64)atomic64_read(&stats->fw_stats.io_fw_errs));
len += snprintf(debug->debug_buffer + len, buf_size - len, len += scnprintf(debug->debug_buffer + len, buf_size - len,
"\n------------------------------------------\n" "\n------------------------------------------\n"
"\t\tVlan Discovery Statistics\n" "\t\tVlan Discovery Statistics\n"
"------------------------------------------\n"); "------------------------------------------\n");
len += snprintf(debug->debug_buffer + len, buf_size - len, len += scnprintf(debug->debug_buffer + len, buf_size - len,
"Number of Vlan Discovery Requests Sent %lld\n" "Number of Vlan Discovery Requests Sent %lld\n"
"Vlan Response Received with no FCF VLAN ID: %lld\n" "Vlan Response Received with no FCF VLAN ID: %lld\n"
"No solicitations recvd after vlan set, expiry count: %lld\n" "No solicitations recvd after vlan set, expiry count: %lld\n"
...@@ -398,7 +398,7 @@ int fnic_get_stats_data(struct stats_debug_info *debug, ...@@ -398,7 +398,7 @@ int fnic_get_stats_data(struct stats_debug_info *debug,
(u64)atomic64_read(&stats->vlan_stats.sol_expiry_count), (u64)atomic64_read(&stats->vlan_stats.sol_expiry_count),
(u64)atomic64_read(&stats->vlan_stats.flogi_rejects)); (u64)atomic64_read(&stats->vlan_stats.flogi_rejects));
len += snprintf(debug->debug_buffer + len, buf_size - len, len += scnprintf(debug->debug_buffer + len, buf_size - len,
"\n------------------------------------------\n" "\n------------------------------------------\n"
"\t\tOther Important Statistics\n" "\t\tOther Important Statistics\n"
"------------------------------------------\n"); "------------------------------------------\n");
...@@ -406,7 +406,7 @@ int fnic_get_stats_data(struct stats_debug_info *debug, ...@@ -406,7 +406,7 @@ int fnic_get_stats_data(struct stats_debug_info *debug,
jiffies_to_timespec64(stats->misc_stats.last_isr_time, &val1); jiffies_to_timespec64(stats->misc_stats.last_isr_time, &val1);
jiffies_to_timespec64(stats->misc_stats.last_ack_time, &val2); jiffies_to_timespec64(stats->misc_stats.last_ack_time, &val2);
len += snprintf(debug->debug_buffer + len, buf_size - len, len += scnprintf(debug->debug_buffer + len, buf_size - len,
"Last ISR time: %llu (%8llu.%09lu)\n" "Last ISR time: %llu (%8llu.%09lu)\n"
"Last ACK time: %llu (%8llu.%09lu)\n" "Last ACK time: %llu (%8llu.%09lu)\n"
"Max ISR jiffies: %llu\n" "Max ISR jiffies: %llu\n"
...@@ -452,7 +452,7 @@ int fnic_get_stats_data(struct stats_debug_info *debug, ...@@ -452,7 +452,7 @@ int fnic_get_stats_data(struct stats_debug_info *debug,
(u64)atomic64_read(&stats->misc_stats.rport_not_ready), (u64)atomic64_read(&stats->misc_stats.rport_not_ready),
(u64)atomic64_read(&stats->misc_stats.frame_errors)); (u64)atomic64_read(&stats->misc_stats.frame_errors));
len += snprintf(debug->debug_buffer + len, buf_size - len, len += scnprintf(debug->debug_buffer + len, buf_size - len,
"Firmware reported port speed: %llu\n", "Firmware reported port speed: %llu\n",
(u64)atomic64_read( (u64)atomic64_read(
&stats->misc_stats.current_port_speed)); &stats->misc_stats.current_port_speed));
...@@ -742,7 +742,7 @@ int fnic_fc_trace_get_data(fnic_dbgfs_t *fnic_dbgfs_prt, u8 rdata_flag) ...@@ -742,7 +742,7 @@ int fnic_fc_trace_get_data(fnic_dbgfs_t *fnic_dbgfs_prt, u8 rdata_flag)
rd_idx = fc_trace_entries.rd_idx; rd_idx = fc_trace_entries.rd_idx;
wr_idx = fc_trace_entries.wr_idx; wr_idx = fc_trace_entries.wr_idx;
if (rdata_flag == 0) { if (rdata_flag == 0) {
len += snprintf(fnic_dbgfs_prt->buffer + len, len += scnprintf(fnic_dbgfs_prt->buffer + len,
(fnic_fc_trace_max_pages * PAGE_SIZE * 3) - len, (fnic_fc_trace_max_pages * PAGE_SIZE * 3) - len,
"Time Stamp (UTC)\t\t" "Time Stamp (UTC)\t\t"
"Host No: F Type: len: FCoE_FRAME:\n"); "Host No: F Type: len: FCoE_FRAME:\n");
...@@ -762,11 +762,11 @@ int fnic_fc_trace_get_data(fnic_dbgfs_t *fnic_dbgfs_prt, u8 rdata_flag) ...@@ -762,11 +762,11 @@ int fnic_fc_trace_get_data(fnic_dbgfs_t *fnic_dbgfs_prt, u8 rdata_flag)
} else { } else {
fc_trace = (char *)tdata; fc_trace = (char *)tdata;
for (j = 0; j < FC_TRC_SIZE_BYTES; j++) { for (j = 0; j < FC_TRC_SIZE_BYTES; j++) {
len += snprintf(fnic_dbgfs_prt->buffer + len, len += scnprintf(fnic_dbgfs_prt->buffer + len,
(fnic_fc_trace_max_pages * PAGE_SIZE * 3) (fnic_fc_trace_max_pages * PAGE_SIZE * 3)
- len, "%02x", fc_trace[j] & 0xff); - len, "%02x", fc_trace[j] & 0xff);
} /* for loop */ } /* for loop */
len += snprintf(fnic_dbgfs_prt->buffer + len, len += scnprintf(fnic_dbgfs_prt->buffer + len,
(fnic_fc_trace_max_pages * PAGE_SIZE * 3) - len, (fnic_fc_trace_max_pages * PAGE_SIZE * 3) - len,
"\n"); "\n");
} }
...@@ -810,7 +810,7 @@ void copy_and_format_trace_data(struct fc_trace_hdr *tdata, ...@@ -810,7 +810,7 @@ void copy_and_format_trace_data(struct fc_trace_hdr *tdata,
time64_to_tm(tdata->time_stamp.tv_sec, 0, &tm); time64_to_tm(tdata->time_stamp.tv_sec, 0, &tm);
fmt = "%02d:%02d:%04ld %02d:%02d:%02d.%09lu ns%8x %c%8x\t"; fmt = "%02d:%02d:%04ld %02d:%02d:%02d.%09lu ns%8x %c%8x\t";
len += snprintf(fnic_dbgfs_prt->buffer + len, len += scnprintf(fnic_dbgfs_prt->buffer + len,
max_size - len, max_size - len,
fmt, fmt,
tm.tm_mon + 1, tm.tm_mday, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_year + 1900,
...@@ -823,25 +823,25 @@ void copy_and_format_trace_data(struct fc_trace_hdr *tdata, ...@@ -823,25 +823,25 @@ void copy_and_format_trace_data(struct fc_trace_hdr *tdata,
for (j = 0; j < min_t(u8, tdata->frame_len, for (j = 0; j < min_t(u8, tdata->frame_len,
(u8)(FC_TRC_SIZE_BYTES - FC_TRC_HEADER_SIZE)); j++) { (u8)(FC_TRC_SIZE_BYTES - FC_TRC_HEADER_SIZE)); j++) {
if (tdata->frame_type == FNIC_FC_LE) { if (tdata->frame_type == FNIC_FC_LE) {
len += snprintf(fnic_dbgfs_prt->buffer + len, len += scnprintf(fnic_dbgfs_prt->buffer + len,
max_size - len, "%c", fc_trace[j]); max_size - len, "%c", fc_trace[j]);
} else { } else {
len += snprintf(fnic_dbgfs_prt->buffer + len, len += scnprintf(fnic_dbgfs_prt->buffer + len,
max_size - len, "%02x", fc_trace[j] & 0xff); max_size - len, "%02x", fc_trace[j] & 0xff);
len += snprintf(fnic_dbgfs_prt->buffer + len, len += scnprintf(fnic_dbgfs_prt->buffer + len,
max_size - len, " "); max_size - len, " ");
if (j == ethhdr_len || if (j == ethhdr_len ||
j == ethhdr_len + fcoehdr_len || j == ethhdr_len + fcoehdr_len ||
j == ethhdr_len + fcoehdr_len + fchdr_len || j == ethhdr_len + fcoehdr_len + fchdr_len ||
(i > 3 && j%fchdr_len == 0)) { (i > 3 && j%fchdr_len == 0)) {
len += snprintf(fnic_dbgfs_prt->buffer len += scnprintf(fnic_dbgfs_prt->buffer
+ len, max_size - len, + len, max_size - len,
"\n\t\t\t\t\t\t\t\t"); "\n\t\t\t\t\t\t\t\t");
i++; i++;
} }
} /* end of else*/ } /* end of else*/
} /* End of for loop*/ } /* End of for loop*/
len += snprintf(fnic_dbgfs_prt->buffer + len, len += scnprintf(fnic_dbgfs_prt->buffer + len,
max_size - len, "\n"); max_size - len, "\n");
*orig_len = len; *orig_len = len;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment