git: 324150d6dab8 - main - ufs: Avoid subobject overflow in snapshot expunge code

From: Jessica Clarke <jrtc27_at_FreeBSD.org>
Date: Sun, 02 Jan 2022 20:56:17 UTC
The branch main has been updated by jrtc27:

URL: https://cgit.FreeBSD.org/src/commit/?id=324150d6dab8a5fcde98c6cc1869da0becb7c3bb

commit 324150d6dab8a5fcde98c6cc1869da0becb7c3bb
Author:     Jessica Clarke <jrtc27@FreeBSD.org>
AuthorDate: 2022-01-02 20:55:49 +0000
Commit:     Jessica Clarke <jrtc27@FreeBSD.org>
CommitDate: 2022-01-02 20:55:49 +0000

    ufs: Avoid subobject overflow in snapshot expunge code
    
    The code here tries to be smart and zeroes out both di_db and di_ib with
    a single bzero call, thereby overrunning the di_db subobject. This is
    fine on most architectures, if a little dodgy. However, on CHERI, the
    compiler can optionally restrict the bounds on pointers to subobjects to
    just that subobject, in order to mitigate intra-object buffer overflows,
    and this is enabled in CheriBSD's pure-capability kernels.
    
    Instead, use separate bzero calls for each array, and let the compiler
    optimise it as it sees fit; even if it's not generating inline zeroing
    code, Clang will happily optimise two consecutive bzero's to a single
    larger call.
    
    Reviewed by:    mckusick
    Differential Revision:  https://reviews.freebsd.org/D33651
---
 sys/ufs/ffs/ffs_snapshot.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/sys/ufs/ffs/ffs_snapshot.c b/sys/ufs/ffs/ffs_snapshot.c
index 59e5012c0019..c5063bf5f747 100644
--- a/sys/ufs/ffs/ffs_snapshot.c
+++ b/sys/ufs/ffs/ffs_snapshot.c
@@ -1084,7 +1084,8 @@ expunge_ufs1(snapvp, cancelip, fs, acctfunc, expungetype, clearmode)
 	dip->di_size = 0;
 	dip->di_blocks = 0;
 	dip->di_flags &= ~SF_SNAPSHOT;
-	bzero(&dip->di_db[0], (UFS_NDADDR + UFS_NIADDR) * sizeof(ufs1_daddr_t));
+	bzero(dip->di_db, UFS_NDADDR * sizeof(ufs1_daddr_t));
+	bzero(dip->di_ib, UFS_NIADDR * sizeof(ufs1_daddr_t));
 	bdwrite(bp);
 	/*
 	 * Now go through and expunge all the blocks in the file
@@ -1366,7 +1367,8 @@ expunge_ufs2(snapvp, cancelip, fs, acctfunc, expungetype, clearmode)
 	dip->di_size = 0;
 	dip->di_blocks = 0;
 	dip->di_flags &= ~SF_SNAPSHOT;
-	bzero(&dip->di_db[0], (UFS_NDADDR + UFS_NIADDR) * sizeof(ufs2_daddr_t));
+	bzero(dip->di_db, UFS_NDADDR * sizeof(ufs2_daddr_t));
+	bzero(dip->di_ib, UFS_NIADDR * sizeof(ufs2_daddr_t));
 	if (clearmode || cancelip->i_effnlink == 0)
 		dip->di_mode = 0;
 	else