From: Gleb C. <lna...@ya...> - 2025-05-19 17:48:52
|
Commit: 989802f GitHub URL: https://github.com/SCST-project/scst/commit/989802f48dbd40dbe84d22298a1a9554afa7f6f1 Author: Gleb Chesnokov Date: 2025-05-19T20:46:54+03:00 Log Message: ----------- scst: Replace snprintf() with scnprintf() Replace snprintf() with scnprintf() in two places: - code paths that build up a buffer incrementally - sysfs attribute “show” handlers scnprintf() guarantees its return value is the number of bytes actually written (never exceeding the buffer), preventing potential overruns. This patch does not change any functionality. Modified Paths: -------------- iscsi-scst/kernel/conn.c | 8 +- iscsi-scst/kernel/session.c | 4 +- scst/src/dev_handlers/scst_vdisk.c | 105 +++++++-------- scst/src/scst_debug.c | 40 +++--- scst_local/scst_local.c | 11 +- srpt/src/ib_srpt.c | 23 ++-- 6 files changed, 93 insertions(+), 98 deletions(-) =================================================================== diff --git a/iscsi-scst/kernel/conn.c b/iscsi-scst/kernel/conn.c index 73c7eae..dcc6a0f 100644 --- a/iscsi-scst/kernel/conn.c +++ b/iscsi-scst/kernel/conn.c @@ -169,17 +169,17 @@ static struct kobj_attribute iscsi_conn_target_ip_attr = static ssize_t iscsi_conn_transport_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - int pos; struct iscsi_conn *conn; + ssize_t ret; TRACE_ENTRY(); conn = container_of(kobj, struct iscsi_conn, conn_kobj); - pos = snprintf(buf, SCST_SYSFS_BLOCK_SIZE, "%s\n", conn->transport->name); + ret = scnprintf(buf, SCST_SYSFS_BLOCK_SIZE, "%s\n", conn->transport->name); - TRACE_EXIT_RES(pos); - return pos; + TRACE_EXIT_RES(ret); + return ret; } static struct kobj_attribute iscsi_conn_transport_attr = diff --git a/iscsi-scst/kernel/session.c b/iscsi-scst/kernel/session.c index 1a428ce..9bfe05c 100644 --- a/iscsi-scst/kernel/session.c +++ b/iscsi-scst/kernel/session.c @@ -488,7 +488,7 @@ static ssize_t iscsi_sess_thread_pid_show(struct kobject *kobj, struct kobj_attr struct iscsi_session *sess = scst_sess_get_tgt_priv(scst_sess); struct iscsi_thread_pool *thr_pool = sess->sess_thr_pool; struct iscsi_thread *t; - int res = -ENOENT; + ssize_t res = -ENOENT; if (!thr_pool) goto out; @@ -497,7 +497,7 @@ static ssize_t iscsi_sess_thread_pid_show(struct kobject *kobj, struct kobj_attr mutex_lock(&thr_pool->tp_mutex); list_for_each_entry(t, &thr_pool->threads_list, threads_list_entry) - res += scnprintf(buf + res, PAGE_SIZE - res, "%d%s", + res += scnprintf(buf + res, SCST_SYSFS_BLOCK_SIZE - res, "%d%s", task_pid_vnr(t->thr), list_is_last(&t->threads_list_entry, &thr_pool->threads_list) ? diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index 6aa5764..2c31761 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -6376,82 +6376,84 @@ out_done: static void vdisk_report_registering(const struct scst_vdisk_dev *virt_dev) { enum { buf_size = 256 }; - char *buf = kmalloc(buf_size, GFP_KERNEL); - int i, j; + char *buf; + int ret, pos; + buf = kmalloc(buf_size, GFP_KERNEL); if (!buf) { PRINT_ERROR("%s: out of memory", __func__); return; } - i = snprintf(buf, buf_size, "Registering virtual %s device %s ", - virt_dev->vdev_devt->name, virt_dev->name); - j = i; + ret = scnprintf(buf, buf_size, "Registering virtual %s device %s ", + virt_dev->vdev_devt->name, virt_dev->name); + pos = ret; if (virt_dev->wt_flag) - i += snprintf(&buf[i], buf_size - i, "(WRITE_THROUGH"); + ret += scnprintf(buf + ret, buf_size - ret, "(WRITE_THROUGH"); if (virt_dev->nv_cache) - i += snprintf(&buf[i], buf_size - i, "%sNV_CACHE", - (j == i) ? "(" : ", "); + ret += scnprintf(buf + ret, buf_size - ret, "%sNV_CACHE", + ret == pos ? "(" : ", "); if (virt_dev->rd_only) - i += snprintf(&buf[i], buf_size - i, "%sREAD_ONLY", - (j == i) ? "(" : ", "); + ret += scnprintf(buf + ret, buf_size - ret, "%sREAD_ONLY", + ret == pos ? "(" : ", "); if (virt_dev->o_direct_flag) - i += snprintf(&buf[i], buf_size - i, "%sO_DIRECT", - (j == i) ? "(" : ", "); + ret += scnprintf(buf + ret, buf_size - ret, "%sO_DIRECT", + ret == pos ? "(" : ", "); if (virt_dev->nullio) - i += snprintf(&buf[i], buf_size - i, "%sNULLIO", - (j == i) ? "(" : ", "); + ret += scnprintf(buf + ret, buf_size - ret, "%sNULLIO", + ret == pos ? "(" : ", "); if (virt_dev->blockio) - i += snprintf(&buf[i], buf_size - i, "%sBLOCKIO", - (j == i) ? "(" : ", "); + ret += scnprintf(buf + ret, buf_size - ret, "%sBLOCKIO", + ret == pos ? "(" : ", "); if (virt_dev->removable) - i += snprintf(&buf[i], buf_size - i, "%sREMOVABLE", - (j == i) ? "(" : ", "); + ret += scnprintf(buf + ret, buf_size - ret, "%sREMOVABLE", + ret == pos ? "(" : ", "); if (!virt_dev->dev_active) - i += snprintf(&buf[i], buf_size - i, "%sINACTIVE", - (j == i) ? "(" : ", "); + ret += scnprintf(buf + ret, buf_size - ret, "%sINACTIVE", + ret == pos ? "(" : ", "); if (virt_dev->tst != DEF_TST) - i += snprintf(&buf[i], buf_size - i, "%sTST %d", - (j == i) ? "(" : ", ", virt_dev->tst); + ret += scnprintf(buf + ret, buf_size - ret, "%sTST %d", + ret == pos ? "(" : ", ", virt_dev->tst); if (virt_dev->rotational) - i += snprintf(&buf[i], buf_size - i, "%sROTATIONAL", - (j == i) ? "(" : ", "); + ret += scnprintf(buf + ret, buf_size - ret, "%sROTATIONAL", + ret == pos ? "(" : ", "); if (virt_dev->thin_provisioned) - i += snprintf(&buf[i], buf_size - i, "%sTHIN_PROVISIONED", - (j == i) ? "(" : ", "); + ret += scnprintf(buf + ret, buf_size - ret, "%sTHIN_PROVISIONED", + ret == pos ? "(" : ", "); if (virt_dev->dif_mode != SCST_DIF_MODE_NONE) { - i += snprintf(&buf[i], buf_size - i, "%sDIF MODE %x, DIF TYPE %d", - (j == i) ? "(" : ", ", - virt_dev->dif_mode, virt_dev->dif_type); + ret += scnprintf(buf + ret, buf_size - ret, "%sDIF MODE %x, DIF TYPE %d", + ret == pos ? "(" : ", ", + virt_dev->dif_mode, virt_dev->dif_type); + if (virt_dev->dif_filename) - i += snprintf(&buf[i], buf_size - i, ", DIF FILENAME %s", - virt_dev->dif_filename); + ret += scnprintf(buf + ret, buf_size - ret, ", DIF FILENAME %s", + virt_dev->dif_filename); else if (virt_dev->dif_static_app_tag_combined != SCST_DIF_NO_CHECK_APP_TAG) - i += snprintf(&buf[i], buf_size - i, ", DIF STATIC APP TAG %llx", - (long long)be64_to_cpu(virt_dev->dif_static_app_tag_combined)); + ret += scnprintf(buf + ret, buf_size - ret, ", DIF STATIC APP TAG %llx", + (long long)be64_to_cpu(virt_dev->dif_static_app_tag_combined)); } if (virt_dev->async) - i += snprintf(&buf[i], buf_size - i, "%sASYNC", - (j == i) ? "(" : ", "); + ret += scnprintf(buf + ret, buf_size - ret, "%sASYNC", + ret == pos ? "(" : ", "); if (virt_dev->dummy) - i += snprintf(&buf[i], buf_size - i, "%sDUMMY", - (j == i) ? "(" : ", "); + ret += scnprintf(buf + ret, buf_size - ret, "%sDUMMY", + ret == pos ? "(" : ", "); - PRINT_INFO("%s%s", buf, j == i ? "" : ")"); + PRINT_INFO("%s%s", buf, ret == pos ? "" : ")"); kfree(buf); } @@ -8150,9 +8152,9 @@ out_put: static ssize_t vdev_sysfs_filename_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - int res = 0; struct scst_device *dev; struct scst_sysfs_work_item *work; + ssize_t res = 0; TRACE_ENTRY(); @@ -8173,7 +8175,7 @@ static ssize_t vdev_sysfs_filename_show(struct kobject *kobj, struct kobj_attrib if (res != 0) goto out_put; - res = snprintf(buf, SCST_SYSFS_BLOCK_SIZE, "%s\n", work->res_buf); + res = scnprintf(buf, SCST_SYSFS_BLOCK_SIZE, "%s\n", work->res_buf); out_put: scst_sysfs_work_put(work); @@ -9040,41 +9042,36 @@ static ssize_t vdev_sysfs_inq_vend_specific_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - int pos; struct scst_device *dev; struct scst_vdisk_dev *virt_dev; + ssize_t ret; dev = container_of(kobj, struct scst_device, dev_kobj); virt_dev = dev->dh_priv; read_lock(&vdisk_serial_rwlock); - pos = snprintf(buf, SCST_SYSFS_BLOCK_SIZE, "%.*s\n%s", - virt_dev->inq_vend_specific_len, - virt_dev->inq_vend_specific, - virt_dev->inq_vend_specific_len ? - SCST_SYSFS_KEY_MARK "\n" : ""); + ret = scnprintf(buf, SCST_SYSFS_BLOCK_SIZE, "%.*s\n%s", + virt_dev->inq_vend_specific_len, + virt_dev->inq_vend_specific, + virt_dev->inq_vend_specific_len ? SCST_SYSFS_KEY_MARK "\n" : ""); read_unlock(&vdisk_serial_rwlock); - return pos; + return ret; } static ssize_t vdev_sysfs_active_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - int pos; struct scst_device *dev; struct scst_vdisk_dev *virt_dev; dev = container_of(kobj, struct scst_device, dev_kobj); virt_dev = dev->dh_priv; - pos = snprintf(buf, SCST_SYSFS_BLOCK_SIZE, "%d\n%s", - virt_dev->dev_active, - virt_dev->dev_active != DEF_DEV_ACTIVE ? - SCST_SYSFS_KEY_MARK "\n" : ""); - - return pos; + return scnprintf(buf, SCST_SYSFS_BLOCK_SIZE, "%d\n%s", + virt_dev->dev_active, + virt_dev->dev_active != DEF_DEV_ACTIVE ? SCST_SYSFS_KEY_MARK "\n" : ""); } static int vdev_sysfs_process_active_store(struct scst_sysfs_work_item *work) diff --git a/scst/src/scst_debug.c b/scst/src/scst_debug.c index 562fbb4..1d71559 100644 --- a/scst/src/scst_debug.c +++ b/scst/src/scst_debug.c @@ -63,27 +63,26 @@ static inline int get_current_tid(void) int debug_print_with_prefix(unsigned long trace_flag, const char *severity, const char *prefix, const char *func, int line, const char *fmt, ...) { - int i; - unsigned long flags; int pid = get_current_tid(); + unsigned long flags; va_list args; + int ret; spin_lock_irqsave(&trace_buf_lock, flags); strscpy(trace_buf, severity, TRACE_BUF_SIZE); - i = strlen(trace_buf); + ret = strlen(trace_buf); if (trace_flag & TRACE_PID) - i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, "[%d]: ", pid); + ret += scnprintf(trace_buf + ret, TRACE_BUF_SIZE - ret, "[%d]: ", pid); if (prefix) - i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, "%s: ", - prefix); + ret += scnprintf(trace_buf + ret, TRACE_BUF_SIZE - ret, "%s: ", prefix); if (trace_flag & TRACE_FUNCTION) - i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, "%s:", func); + ret += scnprintf(trace_buf + ret, TRACE_BUF_SIZE - ret, "%s:", func); if (trace_flag & TRACE_LINE) - i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, "%i:", line); + ret += scnprintf(trace_buf + ret, TRACE_BUF_SIZE - ret, "%i:", line); - i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, "%s\n", fmt); + ret += scnprintf(trace_buf + ret, TRACE_BUF_SIZE - ret, "%s\n", fmt); va_start(args, fmt); vprintk(trace_buf, args); @@ -91,7 +90,7 @@ int debug_print_with_prefix(unsigned long trace_flag, const char *severity, cons spin_unlock_irqrestore(&trace_buf_lock, flags); - return i; + return ret; } EXPORT_SYMBOL(debug_print_with_prefix); @@ -102,9 +101,9 @@ EXPORT_SYMBOL(debug_print_with_prefix); */ void debug_print_buffer(const void *data, int len) { - int z, z1, i; const unsigned char *buf = (const unsigned char *)data; unsigned long flags; + int z, z1, i; if (!buf) return; @@ -115,28 +114,27 @@ void debug_print_buffer(const void *data, int len) for (z = 0, z1 = 0, i = 0; z < len; z++) { if (z % 16 == 0) { if (z != 0) { - i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, - " "); - for (; (z1 < z) && (i < TRACE_BUF_SIZE - 1); - z1++) { + i += scnprintf(trace_buf + i, TRACE_BUF_SIZE - i, " "); + + for (; z1 < z && i < TRACE_BUF_SIZE - 1; z1++) { if (buf[z1] >= 0x20 && buf[z1] < 0x80) trace_buf[i++] = buf[z1]; else trace_buf[i++] = '.'; } trace_buf[i] = '\0'; + PRINT(KERN_INFO, "%s", trace_buf); i = 0; } - i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, - "%4x: ", z); + i += scnprintf(trace_buf + i, TRACE_BUF_SIZE - i, "%4x: ", z); } - i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, "%02x ", - buf[z]); + i += scnprintf(trace_buf + i, TRACE_BUF_SIZE - i, "%02x ", buf[z]); } - i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, " "); - for (; (z1 < z) && (i < TRACE_BUF_SIZE - 1); z1++) { + i += scnprintf(trace_buf + i, TRACE_BUF_SIZE - i, " "); + + for (; z1 < z && i < TRACE_BUF_SIZE - 1; z1++) { if (buf[z1] > 0x20 && buf[z1] < 0x80) trace_buf[i++] = buf[z1]; else diff --git a/scst_local/scst_local.c b/scst_local/scst_local.c index 3c1e1e8..82c16f7 100644 --- a/scst_local/scst_local.c +++ b/scst_local/scst_local.c @@ -438,12 +438,15 @@ static const struct attribute *scst_local_tgt_attrs[] = { static ssize_t host_no_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - struct scst_session *scst_sess = - container_of(kobj, struct scst_session, sess_kobj); + struct scst_session *scst_sess = container_of(kobj, struct scst_session, sess_kobj); struct scst_local_sess *sess = scst_sess_get_tgt_priv(scst_sess); - struct Scsi_Host *host = sess->shost; + struct Scsi_Host *host; - return host ? snprintf(buf, PAGE_SIZE, "%u\n", host->host_no) : -EINVAL; + host = sess->shost; + if (!host) + return -EINVAL; + + return scnprintf(buf, SCST_SYSFS_BLOCK_SIZE, "%u\n", host->host_no); } static struct kobj_attribute scst_local_host_no_attr = __ATTR_RO(host_no); diff --git a/srpt/src/ib_srpt.c b/srpt/src/ib_srpt.c index 03f3272..27aece6 100644 --- a/srpt/src/ib_srpt.c +++ b/srpt/src/ib_srpt.c @@ -3954,12 +3954,12 @@ static ssize_t show_comp_v_mask(struct kobject *kobj, if (!sport) goto out; #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0) - res = cpumask_scnprintf(buf, PAGE_SIZE, &sport->comp_v_mask); + res = cpumask_scnprintf(buf, SCST_SYSFS_BLOCK_SIZE, &sport->comp_v_mask); #else - res = scnprintf(buf, PAGE_SIZE, "%*pb", + res = scnprintf(buf, SCST_SYSFS_BLOCK_SIZE, "%*pb", cpumask_pr_args(&sport->comp_v_mask)); #endif - res += scnprintf(&buf[res], PAGE_SIZE - res, "\n%s\n", + res += scnprintf(buf + res, SCST_SYSFS_BLOCK_SIZE - res, "\n%s\n", SCST_SYSFS_KEY_MARK); out: @@ -4064,25 +4064,22 @@ out: static struct kobj_attribute srpt_link_layer_attr = __ATTR(link_layer, S_IRUGO, srpt_show_link_layer, NULL); -static ssize_t show_port_id(struct kobject *kobj, struct kobj_attribute *attr, - char *buf) +static ssize_t show_port_id(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - struct scst_tgt *scst_tgt = container_of(kobj, struct scst_tgt, - tgt_kobj); + struct scst_tgt *scst_tgt = container_of(kobj, struct scst_tgt, tgt_kobj); struct srpt_port *sport = scst_tgt_get_tgt_priv(scst_tgt); - int res = -E_TGT_PRIV_NOT_YET_SET; + ssize_t res = -E_TGT_PRIV_NOT_YET_SET; if (!sport) goto out; mutex_lock(&sport->mutex); - snprintf(buf, PAGE_SIZE, "%s\n%s", sport->port_id, - strcmp(sport->port_id, DEFAULT_SRPT_ID_STRING) ? - SCST_SYSFS_KEY_MARK "\n" : ""); + res = scnprintf(buf, SCST_SYSFS_BLOCK_SIZE, "%s\n%s", + sport->port_id, + strcmp(sport->port_id, DEFAULT_SRPT_ID_STRING) ? + SCST_SYSFS_KEY_MARK "\n" : ""); mutex_unlock(&sport->mutex); - res = strlen(buf); - out: return res; } |