From bc425cd926be5780293e34a801f97124ce041690 Mon Sep 17 00:00:00 2001 From: Tomohiro Kusumi Date: Wed, 3 Nov 2021 22:35:00 +0900 Subject: [PATCH] usr.sbin/fstyp: Fix intra-object buffer overread for labeled msdosfs volumes Volume labels, like directory entries, are padded with spaces and so have no NUL terminator. Whilst the MIN for the dsize argument to strlcpy ensures that the copy does not overflow the destination, strlcpy is defined to return the number of characters in the source string, regardless of the provided dsize, and so keeps reading until it finds a NUL, which likely exists somewhere within the following fields, but On CHERI with the subobject bounds enabled in the compiler this buffer overread will be detected and trap with a bounds violation. taken from FreeBSD 34fb1c133c5b8616f14f1d740d99747b427f5571 63d24336fd1aad81a4bdefb11d8c487cee5f88a0 --- usr.sbin/fstyp/msdosfs.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/usr.sbin/fstyp/msdosfs.c b/usr.sbin/fstyp/msdosfs.c index 7d7dee39d2..1d91d48e37 100644 --- a/usr.sbin/fstyp/msdosfs.c +++ b/usr.sbin/fstyp/msdosfs.c @@ -47,6 +47,7 @@ fstyp_msdosfs(FILE *fp, char *label, size_t size, const char *devpath) FAT32_BSBPB *pfat32_bsbpb; FAT_DES *pfat_entry; uint8_t *sector0, *sector; + size_t copysize; sector0 = NULL; sector = NULL; @@ -82,8 +83,9 @@ fstyp_msdosfs(FILE *fp, char *label, size_t size, const char *devpath) sizeof(pfat_bsbpb->BS_VolLab)) == 0) { goto endofchecks; } - strlcpy(label, pfat_bsbpb->BS_VolLab, - MIN(size, sizeof(pfat_bsbpb->BS_VolLab) + 1)); + copysize = MIN(size - 1, sizeof(pfat_bsbpb->BS_VolLab)); + memcpy(label, pfat_bsbpb->BS_VolLab, copysize); + label[copysize] = '\0'; } else if (UINT32BYTES(pfat32_bsbpb->BPB_FATSz32) != 0) { uint32_t fat_FirstDataSector, fat_BytesPerSector, offset; @@ -100,8 +102,10 @@ fstyp_msdosfs(FILE *fp, char *label, size_t size, const char *devpath) */ if (strncmp(pfat32_bsbpb->BS_VolLab, LABEL_NO_NAME, sizeof(pfat32_bsbpb->BS_VolLab)) != 0) { - strlcpy(label, pfat32_bsbpb->BS_VolLab, - MIN(size, sizeof(pfat32_bsbpb->BS_VolLab) + 1)); + copysize = MIN(size - 1, + sizeof(pfat32_bsbpb->BS_VolLab)); + memcpy(label, pfat32_bsbpb->BS_VolLab, copysize); + label[copysize] = '\0'; goto endofchecks; } @@ -145,9 +149,11 @@ fstyp_msdosfs(FILE *fp, char *label, size_t size, const char *devpath) */ if (pfat_entry->DIR_Attr & FAT_DES_ATTR_VOLUME_ID) { - strlcpy(label, pfat_entry->DIR_Name, - MIN(size, - sizeof(pfat_entry->DIR_Name) + 1)); + copysize = MIN(size - 1, + sizeof(pfat_entry->DIR_Name)); + memcpy(label, pfat_entry->DIR_Name, + copysize); + label[copysize] = '\0'; goto endofchecks; } } while((uint8_t *)(++pfat_entry) < -- 2.11.4.GIT