Source-Changes-HG archive

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

[src/trunk]: src/sbin/disklabel Avoid misaligned access in disklabel(8) in fi...



details:   https://anonhg.NetBSD.org/src/rev/9c978dcc4d80
branches:  trunk
changeset: 362821:9c978dcc4d80
user:      kamil <kamil%NetBSD.org@localhost>
date:      Wed Jun 27 01:14:48 2018 +0000

description:
Avoid misaligned access in disklabel(8) in find_label()

Introduce a new helper variable tlp and use it for memory access.

Detected with MKSANITIZER/UBSan

A patch by <christos>

diffstat:

 sbin/disklabel/main.c |  34 ++++++++++++++++++----------------
 1 files changed, 18 insertions(+), 16 deletions(-)

diffs (89 lines):

diff -r 5fa638d015ca -r 9c978dcc4d80 sbin/disklabel/main.c
--- a/sbin/disklabel/main.c     Tue Jun 26 22:16:45 2018 +0000
+++ b/sbin/disklabel/main.c     Wed Jun 27 01:14:48 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: main.c,v 1.49 2018/04/01 04:35:02 ryo Exp $    */
+/*     $NetBSD: main.c,v 1.50 2018/06/27 01:14:48 kamil Exp $  */
 
 /*
  * Copyright (c) 2006 The NetBSD Foundation, Inc.
@@ -76,7 +76,7 @@
 static char sccsid[] = "@(#)disklabel.c        8.4 (Berkeley) 5/4/95";
 /* from static char sccsid[] = "@(#)disklabel.c        1.2 (Symmetric) 11/28/85"; */
 #else
-__RCSID("$NetBSD: main.c,v 1.49 2018/04/01 04:35:02 ryo Exp $");
+__RCSID("$NetBSD: main.c,v 1.50 2018/06/27 01:14:48 kamil Exp $");
 #endif
 #endif /* not lint */
 
@@ -1189,7 +1189,7 @@
 static struct disklabel *
 find_label(int f, u_int sector)
 {
-       struct disklabel *disk_lp, hlp;
+       struct disklabel *disk_lp, hlp, tlp;
        int i;
        off_t offset;
        const char *is_deleted;
@@ -1209,30 +1209,31 @@
        /* Check expected offset first */
        for (offset = LABEL_OFFSET, i = -4;; offset = i += 4) {
                is_deleted = "";
-               disk_lp = (void *)(bootarea + offset);
                if (i == LABEL_OFFSET)
                        continue;
+               disk_lp = (void *)(bootarea + offset);
+               memcpy(&tlp, disk_lp, sizeof(tlp));
                if ((char *)(disk_lp + 1) > bootarea + bootarea_len)
                        break;
-               if (disk_lp->d_magic2 != disk_lp->d_magic)
+               if (tlp.d_magic2 != tlp.d_magic)
                        continue;
-               if (read_all && (disk_lp->d_magic == DISKMAGIC_DELETED ||
-                   disk_lp->d_magic == DISKMAGIC_DELETED_REV)) {
-                       disk_lp->d_magic ^= ~0u;
-                       disk_lp->d_magic2 ^= ~0u;
+               if (read_all && (tlp.d_magic == DISKMAGIC_DELETED ||
+                   tlp.d_magic == DISKMAGIC_DELETED_REV)) {
+                       tlp.d_magic ^= ~0u;
+                       tlp.d_magic2 ^= ~0u;
                        is_deleted = "deleted ";
                }
-               if (target32toh(disk_lp->d_magic) != DISKMAGIC) {
+               if (target32toh(tlp.d_magic) != DISKMAGIC) {
                        /* XXX: Do something about byte-swapped labels ? */
-                       if (target32toh(disk_lp->d_magic) == DISKMAGIC_REV &&
-                           target32toh(disk_lp->d_magic2) == DISKMAGIC_REV)
+                       if (target32toh(tlp.d_magic) == DISKMAGIC_REV &&
+                           target32toh(tlp.d_magic2) == DISKMAGIC_REV)
                                warnx("ignoring %sbyteswapped label"
                                    " at offset %jd from sector %u",
                                    is_deleted, (intmax_t)offset, sector);
                        continue;
                }
-               if (target16toh(disk_lp->d_npartitions) > maxpartitions ||
-                   dkcksum_target(disk_lp) != 0) {
+               if (target16toh(tlp.d_npartitions) > maxpartitions ||
+                   dkcksum_target(&tlp) != 0) {
                        if (verbose > 0)
                                warnx("corrupt label found at offset %jd in "
                                    "sector %u", (intmax_t)offset, sector);
@@ -1246,7 +1247,7 @@
 
                /* To print all the labels we have to do it here */
                /* XXX: maybe we should compare them? */
-               targettohlabel(&hlp, disk_lp);
+               targettohlabel(&hlp, &tlp);
                printf("# %ssector %u offset %jd bytes\n",
                    is_deleted, sector, (intmax_t)offset);
                if (tflag)
@@ -1256,7 +1257,8 @@
                        showpartitions(stdout, &hlp, Cflag);
                }
                checklabel(&hlp);
-               htotargetlabel(disk_lp, &hlp);
+               htotargetlabel(&tlp, &hlp);
+               memcpy(disk_lp, &tlp, sizeof(tlp));
                /* Remember we've found a label */
                read_all = 2;
        }



Home | Main Index | Thread Index | Old Index