git: a314c60625af - main - mount(8): Avoid truncation when fstab-formatting unionfs mount info

From: Jason A. Harmening <jah_at_FreeBSD.org>
Date: Mon, 30 Dec 2024 00:41:22 UTC
The branch main has been updated by jah:

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

commit a314c60625af1829b7e12c3a4cedb74d7f69d074
Author:     Jason A. Harmening <jah@FreeBSD.org>
AuthorDate: 2024-12-22 06:36:30 +0000
Commit:     Jason A. Harmening <jah@FreeBSD.org>
CommitDate: 2024-12-30 00:39:49 +0000

    mount(8): Avoid truncation when fstab-formatting unionfs mount info
    
    When displaying unionfs mounts in fstab format (`mount -p`), mount(8)
    currently uses strlcpy to remove the disposition prefix from the mount
    name returned by getmntinfo(3).  But strlcpy, like strcpy before it,
    does not guarantee correct behavior if the source and destination
    buffers overlap.
    
    Just offset the buffer and avoid the destructive copy in the first
    place.
    
    PR:             283420
    Reviewed by:    imp (previous version), olce
    MFC after:      1 week
    Differential Revision: https://reviews.freebsd.org/D48177
---
 sbin/mount/mount.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/sbin/mount/mount.c b/sbin/mount/mount.c
index 1b8eceb9a6ed..cf603a63e394 100644
--- a/sbin/mount/mount.c
+++ b/sbin/mount/mount.c
@@ -892,9 +892,11 @@ void
 putfsent(struct statfs *ent)
 {
 	struct fstab *fst;
+	const char *mntfromname;
 	char *opts, *rw;
 	int l;
 
+	mntfromname = ent->f_mntfromname;
 	opts = NULL;
 	/* flags2opts() doesn't return the "rw" option. */
 	if ((ent->f_flags & MNT_RDONLY) != 0)
@@ -905,16 +907,14 @@ putfsent(struct statfs *ent)
 	opts = flags2opts(ent->f_flags);
 	opts = catopt(rw, opts);
 
-	if (strncmp(ent->f_mntfromname, "<below>", 7) == 0 ||
-	    strncmp(ent->f_mntfromname, "<above>", 7) == 0) {
-		strlcpy(ent->f_mntfromname,
-		    (strnstr(ent->f_mntfromname, ":", 8) +1),
-		    sizeof(ent->f_mntfromname));
+	if (strncmp(mntfromname, "<below>:", 8) == 0 ||
+	    strncmp(mntfromname, "<above>:", 8) == 0) {
+		mntfromname += 8;
 	}
 
-	l = strlen(ent->f_mntfromname);
+	l = strlen(mntfromname);
 	xo_emit("{:device}{P:/%s}{P:/%s}{P:/%s}",
-	    ent->f_mntfromname,
+	    mntfromname,
 	    l < 8 ? "\t" : "",
 	    l < 16 ? "\t" : "",
 	    l < 24 ? "\t" : " ");
@@ -930,7 +930,7 @@ putfsent(struct statfs *ent)
 	    l < 8 ? "\t" : " ");
 	free(opts);
 
-	if ((fst = getfsspec(ent->f_mntfromname)))
+	if ((fst = getfsspec(mntfromname)))
 		xo_emit("{P:\t}{n:dump/%u}{P: }{n:pass/%u}\n",
 		    fst->fs_freq, fst->fs_passno);
 	else if ((fst = getfsfile(ent->f_mntonname)))