Module Name: src Committed By: kamil Date: Thu Nov 7 18:30:27 UTC 2019
Modified Files: src/sys/kern: subr_disk_mbr.c Log Message: 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> To generate a diff of this commit: cvs rdiff -u -r1.52 -r1.53 src/sys/kern/subr_disk_mbr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/subr_disk_mbr.c diff -u src/sys/kern/subr_disk_mbr.c:1.52 src/sys/kern/subr_disk_mbr.c:1.53 --- src/sys/kern/subr_disk_mbr.c:1.52 Wed Nov 6 13:07:32 2019 +++ src/sys/kern/subr_disk_mbr.c Thu Nov 7 18:30:27 2019 @@ -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 @@ check_label_magic(const struct disklabel 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 @@ validate_label(mbr_args_t *a, uint label 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 @@ validate_label(mbr_args_t *a, uint label #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 @@ corrupted: 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 @@ corrupted: #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;