Module Name: src Committed By: kamil Date: Wed Jun 27 01:14:48 UTC 2018
Modified Files: src/sbin/disklabel: main.c Log Message: 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> To generate a diff of this commit: cvs rdiff -u -r1.49 -r1.50 src/sbin/disklabel/main.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sbin/disklabel/main.c diff -u src/sbin/disklabel/main.c:1.49 src/sbin/disklabel/main.c:1.50 --- src/sbin/disklabel/main.c:1.49 Sun Apr 1 04:35:02 2018 +++ src/sbin/disklabel/main.c Wed Jun 27 01:14:48 2018 @@ -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 @@ __COPYRIGHT("@(#) Copyright (c) 1987, 19 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 @@ readlabel(int f) 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 @@ find_label(int f, u_int sector) /* 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 @@ find_label(int f, u_int sector) /* 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 @@ find_label(int f, u_int sector) 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; }