From nobody Wed Oct 27 17:38:47 2021 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id DC3BD182DBE2; Wed, 27 Oct 2021 17:38:47 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4HfbX75DH8z4fnZ; Wed, 27 Oct 2021 17:38:47 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 808971484F; Wed, 27 Oct 2021 17:38:47 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 19RHcljt057736; Wed, 27 Oct 2021 17:38:47 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 19RHclQ6057735; Wed, 27 Oct 2021 17:38:47 GMT (envelope-from git) Date: Wed, 27 Oct 2021 17:38:47 GMT Message-Id: <202110271738.19RHclQ6057735@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Jessica Clarke Subject: git: 34fb1c133c5b - main - Fix intra-object buffer overread for labeled msdosfs volumes List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: jrtc27 X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 34fb1c133c5b8616f14f1d740d99747b427f5571 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by jrtc27: URL: https://cgit.FreeBSD.org/src/commit/?id=34fb1c133c5b8616f14f1d740d99747b427f5571 commit 34fb1c133c5b8616f14f1d740d99747b427f5571 Author: Jessica Clarke AuthorDate: 2021-10-24 18:49:21 +0000 Commit: Jessica Clarke CommitDate: 2021-10-27 17:38:37 +0000 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. Found by: CHERI Reviewed by: imp Differential Revision: https://reviews.freebsd.org/D32579 --- sys/geom/label/g_label_msdosfs.c | 20 +++++++++++++------- usr.sbin/fstyp/msdosfs.c | 20 +++++++++++++------- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/sys/geom/label/g_label_msdosfs.c b/sys/geom/label/g_label_msdosfs.c index d6ccb8b334ee..2ba35ff80f51 100644 --- a/sys/geom/label/g_label_msdosfs.c +++ b/sys/geom/label/g_label_msdosfs.c @@ -50,6 +50,7 @@ g_label_msdosfs_taste(struct g_consumer *cp, char *label, size_t size) FAT32_BSBPB *pfat32_bsbpb; FAT_DES *pfat_entry; uint8_t *sector0, *sector; + size_t copysize; g_topology_assert_not(); pp = cp->provider; @@ -111,8 +112,9 @@ g_label_msdosfs_taste(struct g_consumer *cp, char *label, size_t size) pp->name); goto error; } - 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; @@ -133,8 +135,10 @@ g_label_msdosfs_taste(struct g_consumer *cp, char *label, size_t size) */ 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) + 1); + memcpy(label, pfat32_bsbpb->BS_VolLab, copysize); + label[copysize] = '\0'; goto endofchecks; } @@ -184,9 +188,11 @@ g_label_msdosfs_taste(struct g_consumer *cp, char *label, size_t size) */ 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) < diff --git a/usr.sbin/fstyp/msdosfs.c b/usr.sbin/fstyp/msdosfs.c index 3d86802f6a2e..ce745869edba 100644 --- a/usr.sbin/fstyp/msdosfs.c +++ b/usr.sbin/fstyp/msdosfs.c @@ -48,6 +48,7 @@ fstyp_msdosfs(FILE *fp, char *label, size_t size) FAT32_BSBPB *pfat32_bsbpb; FAT_DES *pfat_entry; uint8_t *sector0, *sector; + size_t copysize; sector0 = NULL; sector = NULL; @@ -83,8 +84,9 @@ fstyp_msdosfs(FILE *fp, char *label, size_t size) 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; @@ -101,8 +103,10 @@ fstyp_msdosfs(FILE *fp, char *label, size_t size) */ 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) + 1); + memcpy(label, pfat32_bsbpb->BS_VolLab, copysize); + label[copysize] = '\0'; goto endofchecks; } @@ -146,9 +150,11 @@ fstyp_msdosfs(FILE *fp, char *label, size_t size) */ 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) <