s390/cert_store: fix string length handling
authorPeter Oberparleiter <oberpar@linux.ibm.com>
Tue, 12 Sep 2023 14:47:32 +0000 (16:47 +0200)
committerVasily Gorbik <gor@linux.ibm.com>
Tue, 19 Sep 2023 11:25:44 +0000 (13:25 +0200)
Building cert_store.o with W=1 reveals this bug:

        CC      arch/s390/kernel/cert_store.o
          arch/s390/kernel/cert_store.c:443:45: warning: ‘sprintf’ may write a terminating nul past the end of the destination [-Wformat-overflow=]
            443 |         sprintf(desc + name_len, ":%04u:%08u", vce->vce_hdr.vc_index, cs_token);
                |                                             ^
          arch/s390/kernel/cert_store.c:443:9: note: ‘sprintf’ output between 15 and 18 bytes into a destination of size 15
            443 |         sprintf(desc + name_len, ":%04u:%08u", vce->vce_hdr.vc_index, cs_token);

Fix this by using the correct maximum width for each integer component
in both buffer length calculation and format string. Also switch to
using snprintf() to guard against potential future changes to the
integer range of each component.

Fixes: 8cf57d7217c3 ("s390: add support for user-defined certificates")
Reported-by: Heiko Carstens <hca@linux.ibm.com>
Reviewed-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
arch/s390/kernel/cert_store.c

index 3986a044eb367f5ab08f3f8b0e9ac58f834e1236..554447768bddc7d0d27aa16ddbf0727c6ef95d4e 100644 (file)
@@ -432,15 +432,16 @@ static char *get_key_description(struct vcssb *vcssb, const struct vce *vce)
        char *desc;
 
        cs_token = vcssb->cs_token;
-       /* Description string contains "%64s:%04u:%08u\0". */
+       /* Description string contains "%64s:%05u:%010u\0". */
        name_len = sizeof(vce->vce_hdr.vc_name);
-       len = name_len + 1 + 4 + 1 + 8 + 1;
+       len = name_len + 1 + 5 + 1 + 10 + 1;
        desc = kmalloc(len, GFP_KERNEL);
        if (!desc)
                return NULL;
 
        memcpy(desc, vce->vce_hdr.vc_name, name_len);
-       sprintf(desc + name_len, ":%04u:%08u", vce->vce_hdr.vc_index, cs_token);
+       snprintf(desc + name_len, len - name_len, ":%05u:%010u",
+                vce->vce_hdr.vc_index, cs_token);
 
        return desc;
 }