In preparation for removing the strlcat() API[1], replace its uses in lpfc_vport_symbolic_node_name().
The function builds five unconditional fragments, so one scnprintf() call composes the whole string. The intermediate tmp buffer and the per fragment overflow checks become unnecessary. scnprintf() truncates at the buffer size and returns the number of bytes it wrote, which equals the length that the removed strnlen() call computed. The old code capped every fragment at MAXHOSTNAMELEN bytes before appending it, independently of the room left in the destination. The replacement formats each fragment directly into the destination, so a fragment longer than MAXHOSTNAMELEN is no longer truncated when the destination has room for it. Link: https://github.com/KSPP/linux/issues/370 [1] Signed-off-by: Ian Bridges <[email protected]> --- The MAXHOSTNAMELEN cap can bind on three fragments. A model name longer than 56 characters, a host name longer than 59 characters or an OS name longer than 59 characters now reaches the symbolic node name in full instead of being cut at the old tmp boundary. The firmware revision and driver version fragments are too short for the cap by their own bounds. The differential harness swept eighteen buffer sizes between 1 and 300 across 4000 randomized field sets and found the outputs identical everywhere the cap did not bind, with every difference classified as this cap removal. The KUnit corpus executed representative cases of the same truncation behavior as compiled kernel code. drivers/scsi/lpfc/lpfc_ct.c | 29 +++++------------------------ 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index c7853e7fe071..0734ab3be3e3 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -1823,34 +1823,15 @@ lpfc_vport_symbolic_node_name(struct lpfc_vport *vport, char *symbol, size_t size) { char fwrev[FW_REV_STR_SIZE] = {0}; - char tmp[MAXHOSTNAMELEN] = {0}; - - memset(symbol, 0, size); - - scnprintf(tmp, sizeof(tmp), "Emulex %s", vport->phba->ModelName); - if (strlcat(symbol, tmp, size) >= size) - goto buffer_done; lpfc_decode_firmware_rev(vport->phba, fwrev, 0); - scnprintf(tmp, sizeof(tmp), " FV%s", fwrev); - if (strlcat(symbol, tmp, size) >= size) - goto buffer_done; - - scnprintf(tmp, sizeof(tmp), " DV%s", lpfc_release_version); - if (strlcat(symbol, tmp, size) >= size) - goto buffer_done; - - scnprintf(tmp, sizeof(tmp), " HN:%s", vport->phba->os_host_name); - if (strlcat(symbol, tmp, size) >= size) - goto buffer_done; + memset(symbol, 0, size); /* Note :- OS name is "Linux" */ - scnprintf(tmp, sizeof(tmp), " OS:%s", init_utsname()->sysname); - strlcat(symbol, tmp, size); - -buffer_done: - return strnlen(symbol, size); - + return scnprintf(symbol, size, "Emulex %s FV%s DV%s HN:%s OS:%s", + vport->phba->ModelName, fwrev, + lpfc_release_version, vport->phba->os_host_name, + init_utsname()->sysname); } static uint32_t -- 2.47.3

