Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern Ensure in validate_label() that struct disklabel po...



details:   https://anonhg.NetBSD.org/src/rev/5098472ab6b5
branches:  trunk
changeset: 966624:5098472ab6b5
user:      kamil <kamil%NetBSD.org@localhost>
date:      Thu Nov 07 18:30:27 2019 +0000

description:
Ensure in validate_label() that struct disklabel pointer is 8-byte aligned

The label is searched each 4 bytes and can be detected in an unaligned
location. Before any operations on it, copy it to promptly aligned local
copy on the stack.

This is a missing part of the following change:

revision 1.108
date: 2011-01-18 20:52:24 +0100;  author: matt;  state: Exp;  lines: +2 -1;
Make struct disklabel 8 byte aligned.  This increases its size by 4 bytes
on IPL32 platforms so add code in sys_ioctl (and netbsd32_ioctl) to deal
with the older/smaller diskabel size.  This change makes disklabel the
same for both IPL32 and LP64 platforms

OK by <martin>

diffstat:

 sys/kern/subr_disk_mbr.c |  33 ++++++++++++++++++---------------
 1 files changed, 18 insertions(+), 15 deletions(-)

diffs (98 lines):

diff -r 6626a33df973 -r 5098472ab6b5 sys/kern/subr_disk_mbr.c
--- a/sys/kern/subr_disk_mbr.c  Thu Nov 07 15:21:55 2019 +0000
+++ b/sys/kern/subr_disk_mbr.c  Thu Nov 07 18:30:27 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: subr_disk_mbr.c,v 1.52 2019/11/06 13:07:32 kamil Exp $ */
+/*     $NetBSD: subr_disk_mbr.c,v 1.53 2019/11/07 18:30:27 kamil Exp $ */
 
 /*
  * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
@@ -54,7 +54,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_disk_mbr.c,v 1.52 2019/11/06 13:07:32 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_disk_mbr.c,v 1.53 2019/11/07 18:30:27 kamil Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -588,7 +588,7 @@
 static int
 validate_label(mbr_args_t *a, uint label_sector)
 {
-       struct disklabel *dlp;
+       struct disklabel *dlp, tlp;
        char *dlp_lim, *dlp_byte;
        int error;
 #ifdef DISKLABEL_EI
@@ -624,21 +624,23 @@
                        else
                                dlp_byte += LABELSECTOR * a->lp->d_secsize;
                        dlp = (void *)dlp_byte;
+                       memcpy(&tlp, dlp, sizeof(tlp));
                        break;
                }
-               if (!check_label_magic(dlp, DISKMAGIC))
+               memcpy(&tlp, dlp, sizeof(tlp));
+               if (!check_label_magic(&tlp, DISKMAGIC))
 #ifdef DISKLABEL_EI
                {
-                       if (!check_label_magic(dlp, bswap32(DISKMAGIC)))
+                       if (!check_label_magic(&tlp, bswap32(DISKMAGIC)))
                                continue;
 
                        /*
                         * The label is in the other byte order. We need to
                         * checksum before swapping the byte order.
                         */
-                       npartitions = bswap16(dlp->d_npartitions);
+                       npartitions = bswap16(tlp.d_npartitions);
                        if (npartitions > MAXPARTITIONS ||
-                           dkcksum_sized(dlp, npartitions) != 0)
+                           dkcksum_sized(&tlp, npartitions) != 0)
                                goto corrupted;
 
                        swapped = 1;
@@ -646,8 +648,8 @@
 #else
                        continue;
 #endif
-               else if (dlp->d_npartitions > MAXPARTITIONS ||
-                        dkcksum(dlp) != 0) {
+               else if (tlp.d_npartitions > MAXPARTITIONS ||
+                        dkcksum(&tlp) != 0) {
 #ifdef DISKLABEL_EI
 corrupted:
 #endif
@@ -661,11 +663,11 @@
        case READ_LABEL:
 #ifdef DISKLABEL_EI
                if (swapped)
-                       swap_disklabel(a->lp, dlp);
+                       swap_disklabel(a->lp, &tlp);
                else
-                       *a->lp = *dlp;
+                       *a->lp = tlp;
 #else
-               *a->lp = *dlp;
+               *a->lp = tlp;
 #endif
                if ((a->msg = convertdisklabel(a->lp, a->strat, a->bp,
                                              a->secperunit)) != NULL)
@@ -677,12 +679,13 @@
 #ifdef DISKLABEL_EI
                /* DO NOT swap a->lp itself for later references. */
                if (swapped)
-                       swap_disklabel(dlp, a->lp);
+                       swap_disklabel(&tlp, a->lp);
                else
-                       *dlp = *a->lp;
+                       tlp = *a->lp;
 #else
-               *dlp = *a->lp;
+               tlp = *a->lp;
 #endif
+               memcpy(dlp, &tlp, sizeof(tlp));
                a->bp->b_oflags &= ~BO_DONE;
                a->bp->b_flags &= ~B_READ;
                a->bp->b_flags |= B_WRITE;



Home | Main Index | Thread Index | Old Index