Date: Fri, 20 May 2016 01:41:47 +0000 (UTC) From: Allan Jude <allanjude@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r300257 - in head/sys/boot/i386: libi386 zfsboot Message-ID: <201605200141.u4K1flpV094958@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: allanjude Date: Fri May 20 01:41:47 2016 New Revision: 300257 URL: https://svnweb.freebsd.org/changeset/base/300257 Log: Fixup the geliboot sector rounding code Replace all rounding with the round{up,down}2 macros a missing set of braces caused the previous code to be incorrect replace alloca() with malloc() because alloca() can return an allocation that is actually invalid, causing boot to fail Reviewed by: emaste, ed Thanks To: peter Sponsored by: ScaleEngine Inc. Differential Revision: https://reviews.freebsd.org/D6213 Modified: head/sys/boot/i386/libi386/biosdisk.c head/sys/boot/i386/zfsboot/zfsboot.c Modified: head/sys/boot/i386/libi386/biosdisk.c ============================================================================== --- head/sys/boot/i386/libi386/biosdisk.c Fri May 20 01:38:31 2016 (r300256) +++ head/sys/boot/i386/libi386/biosdisk.c Fri May 20 01:41:47 2016 (r300257) @@ -749,21 +749,29 @@ bd_read(struct disk_devdesc *dev, daddr_ * sectors cannot be decrypted. Round the requested LBA down to * nearest multiple of DEV_GELIBOOT_BSIZE bytes. */ - alignlba = dblk & - ~(daddr_t)((DEV_GELIBOOT_BSIZE / BIOSDISK_SECSIZE) - 1); + alignlba = rounddown2(dblk * BD(dev).bd_sectorsize, + DEV_GELIBOOT_BSIZE) / BD(dev).bd_sectorsize; /* * Round number of blocks to read up to nearest multiple of * DEV_GELIBOOT_BSIZE */ - alignblks = blks + (dblk - alignlba) + - ((DEV_GELIBOOT_BSIZE / BIOSDISK_SECSIZE) - 1) & - ~(int)((DEV_GELIBOOT_BSIZE / BIOSDISK_SECSIZE) - 1); - diff = (dblk - alignlba) * BIOSDISK_SECSIZE; + diff = (dblk - alignlba) * BD(dev).bd_sectorsize; + alignblks = roundup2(blks * BD(dev).bd_sectorsize + diff, + DEV_GELIBOOT_BSIZE) / BD(dev).bd_sectorsize; + /* - * Use a temporary buffer here because the buffer provided by - * the caller may be too small. + * If the read is rounded up to a larger size, use a temporary + * buffer here because the buffer provided by the caller may be + * too small. */ - tmpbuf = alloca(alignblks * BIOSDISK_SECSIZE); + if (diff == 0) { + tmpbuf = dest; + } else { + tmpbuf = malloc(alignblks * BD(dev).bd_sectorsize); + if (tmpbuf == NULL) { + return (-1); + } + } err = bd_io(dev, alignlba, alignblks, tmpbuf, 0); if (err) @@ -779,12 +787,15 @@ bd_read(struct disk_devdesc *dev, daddr_ /* GELI needs the offset relative to the partition start */ p_off = alignlba - dskp.start; - err = geli_read(&dskp, p_off * BIOSDISK_SECSIZE, tmpbuf, - alignblks * BIOSDISK_SECSIZE); + err = geli_read(&dskp, p_off * BD(dev).bd_sectorsize, tmpbuf, + alignblks * BD(dev).bd_sectorsize); if (err) return (err); - bcopy(tmpbuf + diff, dest, blks * BIOSDISK_SECSIZE); + if (tmpbuf != dest) { + bcopy(tmpbuf + diff, dest, blks * BD(dev).bd_sectorsize); + free(tmpbuf); + } return (0); } #endif /* LOADER_GELI_SUPPORT */ @@ -898,10 +909,10 @@ bios_read(void *vdev __unused, struct ds dev.d_partition = priv->part; dev.d_offset = priv->start; - off = off / BIOSDISK_SECSIZE; + off = off / BD(&dev).bd_sectorsize; /* GELI gives us the offset relative to the partition start */ off += dev.d_offset; - bytes = bytes / BIOSDISK_SECSIZE; + bytes = bytes / BD(&dev).bd_sectorsize; return (bd_io(&dev, off, bytes, buf, 0)); } Modified: head/sys/boot/i386/zfsboot/zfsboot.c ============================================================================== --- head/sys/boot/i386/zfsboot/zfsboot.c Fri May 20 01:38:31 2016 (r300256) +++ head/sys/boot/i386/zfsboot/zfsboot.c Fri May 20 01:41:47 2016 (r300257) @@ -200,7 +200,7 @@ vdev_read(vdev_t *vdev, void *priv, off_ { char *p; daddr_t lba, alignlba; - off_t alignoff, diff; + off_t diff; unsigned int nb, alignnb; struct dsk *dsk = (struct dsk *) priv; @@ -210,10 +210,11 @@ vdev_read(vdev_t *vdev, void *priv, off_ p = buf; lba = off / DEV_BSIZE; lba += dsk->start; - /* Align reads to 4k else 4k sector GELIs will not decrypt. */ - alignoff = off & ~ (off_t)(DEV_GELIBOOT_BSIZE - 1); - /* Round LBA down to nearest multiple of DEV_GELIBOOT_BSIZE bytes. */ - alignlba = alignoff / DEV_BSIZE; + /* + * Align reads to 4k else 4k sector GELIs will not decrypt. + * Round LBA down to nearest multiple of DEV_GELIBOOT_BSIZE bytes. + */ + alignlba = rounddown2(off, DEV_GELIBOOT_BSIZE) / DEV_BSIZE; /* * The read must be aligned to DEV_GELIBOOT_BSIZE bytes relative to the * start of the GELI partition, not the start of the actual disk.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201605200141.u4K1flpV094958>