The branch stable/13 has been updated by mckusick:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=5628a0901987c5f72403cf69e23701f4cc7bc2e2
commit 5628a0901987c5f72403cf69e23701f4cc7bc2e2
Author:     Kirk McKusick <mckus...@freebsd.org>
AuthorDate: 2022-02-20 21:18:05 +0000
Commit:     Kirk McKusick <mckus...@freebsd.org>
CommitDate: 2022-02-26 21:34:11 +0000

    Avoid unaligned writes by fsck_ffs(8).
    
    (cherry picked from commit 7a1c1f6a0332c5b60349a5df0e3ce64e5005b2ff)
---
 sbin/fsck_ffs/setup.c | 30 +++++++++++++++++-------------
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/sbin/fsck_ffs/setup.c b/sbin/fsck_ffs/setup.c
index 87676e8ca7ce..375ba897199a 100644
--- a/sbin/fsck_ffs/setup.c
+++ b/sbin/fsck_ffs/setup.c
@@ -399,17 +399,19 @@ chkrecovery(int devfd)
 {
        struct fsrecovery *fsr;
        char *fsrbuf;
-       u_int secsize;
+       u_int secsize, rdsize;
 
        /*
         * Could not determine if backup material exists, so do not
         * offer to create it.
         */
        fsrbuf = NULL;
+       rdsize = sblock.fs_fsize;
        if (ioctl(devfd, DIOCGSECTORSIZE, &secsize) == -1 ||
-           (fsrbuf = Malloc(secsize)) == NULL ||
-           blread(devfd, fsrbuf, (SBLOCK_UFS2 - secsize) / dev_bsize,
-             secsize) != 0) {
+           rdsize % secsize != 0 ||
+           (fsrbuf = Malloc(rdsize)) == NULL ||
+           blread(devfd, fsrbuf, (SBLOCK_UFS2 - rdsize) / dev_bsize,
+             rdsize) != 0) {
                free(fsrbuf);
                return (1);
        }
@@ -417,7 +419,7 @@ chkrecovery(int devfd)
         * Recovery material has already been created, so do not
         * need to create it again.
         */
-       fsr = (struct fsrecovery *)&fsrbuf[secsize - sizeof *fsr];
+       fsr = (struct fsrecovery *)&fsrbuf[rdsize - sizeof *fsr];
        if (fsr->fsr_magic == FS_UFS2_MAGIC) {
                free(fsrbuf);
                return (1);
@@ -430,8 +432,8 @@ chkrecovery(int devfd)
 }
 
 /*
- * Read the last sector of the boot block, replace the last
- * 20 bytes with the recovery information, then write it back.
+ * Read the last filesystem-size piece of the boot block, replace the
+ * last 20 bytes with the recovery information, then write it back.
  * The recovery information only works for UFS2 filesystems.
  */
 static void
@@ -439,24 +441,26 @@ saverecovery(int readfd, int writefd)
 {
        struct fsrecovery *fsr;
        char *fsrbuf;
-       u_int secsize;
+       u_int secsize, rdsize;
 
        fsrbuf = NULL;
+       rdsize = sblock.fs_fsize;
        if (sblock.fs_magic != FS_UFS2_MAGIC ||
            ioctl(readfd, DIOCGSECTORSIZE, &secsize) == -1 ||
-           (fsrbuf = Malloc(secsize)) == NULL ||
-           blread(readfd, fsrbuf, (SBLOCK_UFS2 - secsize) / dev_bsize,
-             secsize) != 0) {
+           rdsize % secsize != 0 ||
+           (fsrbuf = Malloc(rdsize)) == NULL ||
+           blread(readfd, fsrbuf, (SBLOCK_UFS2 - rdsize) / dev_bsize,
+             rdsize) != 0) {
                printf("RECOVERY DATA COULD NOT BE CREATED\n");
                free(fsrbuf);
                return;
        }
-       fsr = (struct fsrecovery *)&fsrbuf[secsize - sizeof *fsr];
+       fsr = (struct fsrecovery *)&fsrbuf[rdsize - sizeof *fsr];
        fsr->fsr_magic = sblock.fs_magic;
        fsr->fsr_fpg = sblock.fs_fpg;
        fsr->fsr_fsbtodb = sblock.fs_fsbtodb;
        fsr->fsr_sblkno = sblock.fs_sblkno;
        fsr->fsr_ncg = sblock.fs_ncg;
-       blwrite(writefd, fsrbuf, (SBLOCK_UFS2 - secsize) / secsize, secsize);
+       blwrite(writefd, fsrbuf, (SBLOCK_UFS2 - rdsize) / dev_bsize, rdsize);
        free(fsrbuf);
 }

Reply via email to