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


Reply via email to