Date: Thu, 20 Oct 2016 18:38:38 +0000 (UTC) From: Gleb Smirnoff <glebius@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r307682 - in user/cperciva/freebsd-update-build/patches: 10.3-RELEASE 11.0-RELEASE Message-ID: <201610201838.u9KIccmJ035781@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: glebius Date: Thu Oct 20 18:38:37 2016 New Revision: 307682 URL: https://svnweb.freebsd.org/changeset/base/307682 Log: Add two upcoming errata notices and cleanup after SA-16:21 mispatch (r307329). Added: user/cperciva/freebsd-update-build/patches/10.3-RELEASE/11-EN-16:17.vm user/cperciva/freebsd-update-build/patches/10.3-RELEASE/11-SA-16:31.libarchive user/cperciva/freebsd-update-build/patches/11.0-RELEASE/2-EN-16:18.loader Added: user/cperciva/freebsd-update-build/patches/10.3-RELEASE/11-EN-16:17.vm ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ user/cperciva/freebsd-update-build/patches/10.3-RELEASE/11-EN-16:17.vm Thu Oct 20 18:38:37 2016 (r307682) @@ -0,0 +1,239 @@ +--- sys/kern/vfs_subr.c.orig ++++ sys/kern/vfs_subr.c +@@ -2934,7 +2934,13 @@ + TAILQ_EMPTY(&vp->v_bufobj.bo_clean.bv_hd) && + vp->v_bufobj.bo_clean.bv_cnt == 0, + ("vp %p bufobj not invalidated", vp)); +- vp->v_bufobj.bo_flag |= BO_DEAD; ++ ++ /* ++ * For VMIO bufobj, BO_DEAD is set in vm_object_terminate() ++ * after the object's page queue is flushed. ++ */ ++ if (vp->v_bufobj.bo_object == NULL) ++ vp->v_bufobj.bo_flag |= BO_DEAD; + BO_UNLOCK(&vp->v_bufobj); + + /* +--- sys/vm/vm_fault.c.orig ++++ sys/vm/vm_fault.c +@@ -286,7 +286,7 @@ + vm_prot_t prot; + long ahead, behind; + int alloc_req, era, faultcount, nera, reqpage, result; +- boolean_t growstack, is_first_object_locked, wired; ++ boolean_t dead, growstack, is_first_object_locked, wired; + int map_generation; + vm_object_t next_object; + vm_page_t marray[VM_FAULT_READ_MAX]; +@@ -423,11 +423,18 @@ + fs.pindex = fs.first_pindex; + while (TRUE) { + /* +- * If the object is dead, we stop here ++ * If the object is marked for imminent termination, ++ * we retry here, since the collapse pass has raced ++ * with us. Otherwise, if we see terminally dead ++ * object, return fail. + */ +- if (fs.object->flags & OBJ_DEAD) { ++ if ((fs.object->flags & OBJ_DEAD) != 0) { ++ dead = fs.object->type == OBJT_DEAD; + unlock_and_deallocate(&fs); +- return (KERN_PROTECTION_FAILURE); ++ if (dead) ++ return (KERN_PROTECTION_FAILURE); ++ pause("vmf_de", 1); ++ goto RetryFault; + } + + /* +--- sys/vm/vm_meter.c.orig ++++ sys/vm/vm_meter.c +@@ -93,30 +93,32 @@ + CTLFLAG_MPSAFE, NULL, 0, sysctl_vm_loadavg, "S,loadavg", + "Machine loadaverage history"); + ++/* ++ * This function aims to determine if the object is mapped, ++ * specifically, if it is referenced by a vm_map_entry. Because ++ * objects occasionally acquire transient references that do not ++ * represent a mapping, the method used here is inexact. However, it ++ * has very low overhead and is good enough for the advisory ++ * vm.vmtotal sysctl. ++ */ ++static bool ++is_object_active(vm_object_t obj) ++{ ++ ++ return (obj->ref_count > obj->shadow_count); ++} ++ + static int + vmtotal(SYSCTL_HANDLER_ARGS) + { +- struct proc *p; + struct vmtotal total; +- vm_map_entry_t entry; + vm_object_t object; +- vm_map_t map; +- int paging; ++ struct proc *p; + struct thread *td; +- struct vmspace *vm; + + bzero(&total, sizeof(total)); ++ + /* +- * Mark all objects as inactive. +- */ +- mtx_lock(&vm_object_list_mtx); +- TAILQ_FOREACH(object, &vm_object_list, object_list) { +- VM_OBJECT_WLOCK(object); +- vm_object_clear_flag(object, OBJ_ACTIVE); +- VM_OBJECT_WUNLOCK(object); +- } +- mtx_unlock(&vm_object_list_mtx); +- /* + * Calculate process statistics. + */ + sx_slock(&allproc_lock); +@@ -136,11 +138,15 @@ + case TDS_INHIBITED: + if (TD_IS_SWAPPED(td)) + total.t_sw++; +- else if (TD_IS_SLEEPING(td) && +- td->td_priority <= PZERO) +- total.t_dw++; +- else +- total.t_sl++; ++ else if (TD_IS_SLEEPING(td)) { ++ if (td->td_priority <= PZERO) ++ total.t_dw++; ++ else ++ total.t_sl++; ++ if (td->td_wchan == ++ &cnt.v_free_count) ++ total.t_pw++; ++ } + break; + + case TDS_CAN_RUN: +@@ -158,29 +164,6 @@ + } + } + PROC_UNLOCK(p); +- /* +- * Note active objects. +- */ +- paging = 0; +- vm = vmspace_acquire_ref(p); +- if (vm == NULL) +- continue; +- map = &vm->vm_map; +- vm_map_lock_read(map); +- for (entry = map->header.next; +- entry != &map->header; entry = entry->next) { +- if ((entry->eflags & MAP_ENTRY_IS_SUB_MAP) || +- (object = entry->object.vm_object) == NULL) +- continue; +- VM_OBJECT_WLOCK(object); +- vm_object_set_flag(object, OBJ_ACTIVE); +- paging |= object->paging_in_progress; +- VM_OBJECT_WUNLOCK(object); +- } +- vm_map_unlock_read(map); +- vmspace_free(vm); +- if (paging) +- total.t_pw++; + } + sx_sunlock(&allproc_lock); + /* +@@ -206,9 +189,18 @@ + */ + continue; + } ++ if (object->ref_count == 1 && ++ (object->flags & OBJ_NOSPLIT) != 0) { ++ /* ++ * Also skip otherwise unreferenced swap ++ * objects backing tmpfs vnodes, and POSIX or ++ * SysV shared memory. ++ */ ++ continue; ++ } + total.t_vm += object->size; + total.t_rm += object->resident_page_count; +- if (object->flags & OBJ_ACTIVE) { ++ if (is_object_active(object)) { + total.t_avm += object->size; + total.t_arm += object->resident_page_count; + } +@@ -216,7 +208,7 @@ + /* shared object */ + total.t_vmshr += object->size; + total.t_rmshr += object->resident_page_count; +- if (object->flags & OBJ_ACTIVE) { ++ if (is_object_active(object)) { + total.t_avmshr += object->size; + total.t_armshr += object->resident_page_count; + } +--- sys/vm/vm_object.c.orig ++++ sys/vm/vm_object.c +@@ -737,6 +737,10 @@ + + vinvalbuf(vp, V_SAVE, 0, 0); + ++ BO_LOCK(&vp->v_bufobj); ++ vp->v_bufobj.bo_flag |= BO_DEAD; ++ BO_UNLOCK(&vp->v_bufobj); ++ + VM_OBJECT_WLOCK(object); + } + +@@ -1722,6 +1726,9 @@ + * case. + */ + if (backing_object->ref_count == 1) { ++ vm_object_pip_add(object, 1); ++ vm_object_pip_add(backing_object, 1); ++ + /* + * If there is exactly one reference to the backing + * object, we can collapse it into the parent. +@@ -1793,11 +1800,13 @@ + KASSERT(backing_object->ref_count == 1, ( + "backing_object %p was somehow re-referenced during collapse!", + backing_object)); ++ vm_object_pip_wakeup(backing_object); + backing_object->type = OBJT_DEAD; + backing_object->ref_count = 0; + VM_OBJECT_WUNLOCK(backing_object); + vm_object_destroy(backing_object); + ++ vm_object_pip_wakeup(object); + object_collapses++; + } else { + vm_object_t new_backing_object; +@@ -2130,6 +2139,7 @@ + */ + if (!reserved && !swap_reserve_by_cred(ptoa(next_size), + prev_object->cred)) { ++ VM_OBJECT_WUNLOCK(prev_object); + return (FALSE); + } + prev_object->charge += ptoa(next_size); +--- sys/vm/vm_object.h.orig ++++ sys/vm/vm_object.h +@@ -181,7 +181,6 @@ + */ + #define OBJ_FICTITIOUS 0x0001 /* (c) contains fictitious pages */ + #define OBJ_UNMANAGED 0x0002 /* (c) contains unmanaged pages */ +-#define OBJ_ACTIVE 0x0004 /* active objects */ + #define OBJ_DEAD 0x0008 /* dead objects (during rundown) */ + #define OBJ_NOSPLIT 0x0010 /* dont split this object */ + #define OBJ_PIPWNT 0x0040 /* paging in progress wanted */ +--- ..orig ++++ . + Merged /head:r300758,300959,302063,302236,302317,302567,302580 + Merged /stable/10:r301184,301436,302243,302513,303291 Added: user/cperciva/freebsd-update-build/patches/10.3-RELEASE/11-SA-16:31.libarchive ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ user/cperciva/freebsd-update-build/patches/10.3-RELEASE/11-SA-16:31.libarchive Thu Oct 20 18:38:37 2016 (r307682) @@ -0,0 +1,321 @@ +--- contrib/libarchive/libarchive/test/test_write_disk_secure744.c.orig ++++ contrib/libarchive/libarchive/test/test_write_disk_secure744.c +@@ -93,98 +93,3 @@ + free(buff); + #endif + } +-/*- +- * Copyright (c) 2003-2007,2016 Tim Kientzle +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR +- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, +- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- */ +-#include "test.h" +-__FBSDID("$FreeBSD$"); +- +-#define UMASK 022 +- +-/* +- * Github Issue #744 describes a bug in the sandboxing code that +- * causes very long pathnames to not get checked for symlinks. +- */ +- +-DEFINE_TEST(test_write_disk_secure744) +-{ +-#if defined(_WIN32) && !defined(__CYGWIN__) +- skipping("archive_write_disk security checks not supported on Windows"); +-#else +- struct archive *a; +- struct archive_entry *ae; +- size_t buff_size = 8192; +- char *buff = malloc(buff_size); +- char *p = buff; +- int n = 0; +- int t; +- +- assert(buff != NULL); +- +- /* Start with a known umask. */ +- assertUmask(UMASK); +- +- /* Create an archive_write_disk object. */ +- assert((a = archive_write_disk_new()) != NULL); +- archive_write_disk_set_options(a, ARCHIVE_EXTRACT_SECURE_SYMLINKS); +- +- while (p + 500 < buff + buff_size) { +- memset(p, 'x', 100); +- p += 100; +- p[0] = '\0'; +- +- buff[0] = ((n / 1000) % 10) + '0'; +- buff[1] = ((n / 100) % 10)+ '0'; +- buff[2] = ((n / 10) % 10)+ '0'; +- buff[3] = ((n / 1) % 10)+ '0'; +- buff[4] = '_'; +- ++n; +- +- /* Create a symlink pointing to the testworkdir */ +- assert((ae = archive_entry_new()) != NULL); +- archive_entry_copy_pathname(ae, buff); +- archive_entry_set_mode(ae, S_IFREG | 0777); +- archive_entry_copy_symlink(ae, testworkdir); +- assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); +- archive_entry_free(ae); +- +- *p++ = '/'; +- sprintf(p, "target%d", n); +- +- /* Try to create a file through the symlink, should fail. */ +- assert((ae = archive_entry_new()) != NULL); +- archive_entry_copy_pathname(ae, buff); +- archive_entry_set_mode(ae, S_IFDIR | 0777); +- +- t = archive_write_header(a, ae); +- archive_entry_free(ae); +- failure("Attempt to create target%d via %d-character symlink should have failed", n, (int)strlen(buff)); +- if(!assertEqualInt(ARCHIVE_FAILED, t)) { +- break; +- } +- } +- archive_free(a); +- free(buff); +-#endif +-} +--- contrib/libarchive/libarchive/test/test_write_disk_secure745.c.orig ++++ contrib/libarchive/libarchive/test/test_write_disk_secure745.c +@@ -77,82 +77,3 @@ + archive_write_free(a); + #endif + } +-/*- +- * Copyright (c) 2003-2007,2016 Tim Kientzle +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR +- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, +- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- */ +-#include "test.h" +-__FBSDID("$FreeBSD$"); +- +-#define UMASK 022 +- +-/* +- * Github Issue #745 describes a bug in the sandboxing code that +- * allows one to use a symlink to edit the permissions on a file or +- * directory outside of the sandbox. +- */ +- +-DEFINE_TEST(test_write_disk_secure745) +-{ +-#if defined(_WIN32) && !defined(__CYGWIN__) +- skipping("archive_write_disk security checks not supported on Windows"); +-#else +- struct archive *a; +- struct archive_entry *ae; +- +- /* Start with a known umask. */ +- assertUmask(UMASK); +- +- /* Create an archive_write_disk object. */ +- assert((a = archive_write_disk_new()) != NULL); +- archive_write_disk_set_options(a, ARCHIVE_EXTRACT_SECURE_SYMLINKS); +- +- /* The target dir: The one we're going to try to change permission on */ +- assertMakeDir("target", 0700); +- +- /* The sandbox dir we're going to run inside of. */ +- assertMakeDir("sandbox", 0700); +- assertChdir("sandbox"); +- +- /* Create a symlink pointing to the target directory */ +- assert((ae = archive_entry_new()) != NULL); +- archive_entry_copy_pathname(ae, "sym"); +- archive_entry_set_mode(ae, AE_IFLNK | 0777); +- archive_entry_copy_symlink(ae, "../target"); +- assert(0 == archive_write_header(a, ae)); +- archive_entry_free(ae); +- +- /* Try to alter the target dir through the symlink; this should fail. */ +- assert((ae = archive_entry_new()) != NULL); +- archive_entry_copy_pathname(ae, "sym"); +- archive_entry_set_mode(ae, S_IFDIR | 0777); +- assert(0 == archive_write_header(a, ae)); +- archive_entry_free(ae); +- +- /* Permission of target dir should not have changed. */ +- assertFileMode("../target", 0700); +- +- assert(0 == archive_write_close(a)); +- archive_write_free(a); +-#endif +-} +--- contrib/libarchive/libarchive/test/test_write_disk_secure746.c.orig ++++ contrib/libarchive/libarchive/test/test_write_disk_secure746.c +@@ -127,132 +127,3 @@ + archive_write_free(a); + #endif + } +-/*- +- * Copyright (c) 2003-2007,2016 Tim Kientzle +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR +- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, +- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- */ +-#include "test.h" +-__FBSDID("$FreeBSD$"); +- +-#define UMASK 022 +- +-/* +- * Github Issue #746 describes a problem in which hardlink targets are +- * not adequately checked and can be used to modify entries outside of +- * the sandbox. +- */ +- +-/* +- * Verify that ARCHIVE_EXTRACT_SECURE_NODOTDOT disallows '..' in hardlink +- * targets. +- */ +-DEFINE_TEST(test_write_disk_secure746a) +-{ +-#if defined(_WIN32) && !defined(__CYGWIN__) +- skipping("archive_write_disk security checks not supported on Windows"); +-#else +- struct archive *a; +- struct archive_entry *ae; +- +- /* Start with a known umask. */ +- assertUmask(UMASK); +- +- /* The target directory we're going to try to affect. */ +- assertMakeDir("target", 0700); +- assertMakeFile("target/foo", 0700, "unmodified"); +- +- /* The sandbox dir we're going to work within. */ +- assertMakeDir("sandbox", 0700); +- assertChdir("sandbox"); +- +- /* Create an archive_write_disk object. */ +- assert((a = archive_write_disk_new()) != NULL); +- archive_write_disk_set_options(a, ARCHIVE_EXTRACT_SECURE_NODOTDOT); +- +- /* Attempt to hardlink to the target directory. */ +- assert((ae = archive_entry_new()) != NULL); +- archive_entry_copy_pathname(ae, "bar"); +- archive_entry_set_mode(ae, AE_IFREG | 0777); +- archive_entry_set_size(ae, 8); +- archive_entry_copy_hardlink(ae, "../target/foo"); +- assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae)); +- assertEqualInt(ARCHIVE_FATAL, archive_write_data(a, "modified", 8)); +- archive_entry_free(ae); +- +- /* Verify that target file contents are unchanged. */ +- assertTextFileContents("unmodified", "../target/foo"); +-#endif +-} +- +-/* +- * Verify that ARCHIVE_EXTRACT_SECURE_NOSYMLINK disallows symlinks in hardlink +- * targets. +- */ +-DEFINE_TEST(test_write_disk_secure746b) +-{ +-#if defined(_WIN32) && !defined(__CYGWIN__) +- skipping("archive_write_disk security checks not supported on Windows"); +-#else +- struct archive *a; +- struct archive_entry *ae; +- +- /* Start with a known umask. */ +- assertUmask(UMASK); +- +- /* The target directory we're going to try to affect. */ +- assertMakeDir("target", 0700); +- assertMakeFile("target/foo", 0700, "unmodified"); +- +- /* The sandbox dir we're going to work within. */ +- assertMakeDir("sandbox", 0700); +- assertChdir("sandbox"); +- +- /* Create an archive_write_disk object. */ +- assert((a = archive_write_disk_new()) != NULL); +- archive_write_disk_set_options(a, ARCHIVE_EXTRACT_SECURE_SYMLINKS); +- +- /* Create a symlink to the target directory. */ +- assert((ae = archive_entry_new()) != NULL); +- archive_entry_copy_pathname(ae, "symlink"); +- archive_entry_set_mode(ae, AE_IFLNK | 0777); +- archive_entry_copy_symlink(ae, "../target"); +- assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); +- archive_entry_free(ae); +- +- /* Attempt to hardlink to the target directory via the symlink. */ +- assert((ae = archive_entry_new()) != NULL); +- archive_entry_copy_pathname(ae, "bar"); +- archive_entry_set_mode(ae, AE_IFREG | 0777); +- archive_entry_set_size(ae, 8); +- archive_entry_copy_hardlink(ae, "symlink/foo"); +- assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae)); +- assertEqualIntA(a, ARCHIVE_FATAL, archive_write_data(a, "modified", 8)); +- archive_entry_free(ae); +- +- /* Verify that target file contents are unchanged. */ +- assertTextFileContents("unmodified", "../target/foo"); +- +- assertEqualIntA(a, ARCHIVE_FATAL, archive_write_close(a)); +- archive_write_free(a); +-#endif +-} Added: user/cperciva/freebsd-update-build/patches/11.0-RELEASE/2-EN-16:18.loader ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ user/cperciva/freebsd-update-build/patches/11.0-RELEASE/2-EN-16:18.loader Thu Oct 20 18:38:37 2016 (r307682) @@ -0,0 +1,34 @@ +--- sys/boot/geli/geliboot.c.orig ++++ sys/boot/geli/geliboot.c +@@ -77,17 +77,25 @@ + int error; + off_t alignsector; + +- alignsector = (lastsector * DEV_BSIZE) & +- ~(off_t)(DEV_GELIBOOT_BSIZE - 1); ++ alignsector = rounddown2(lastsector * DEV_BSIZE, DEV_GELIBOOT_BSIZE); ++ if (alignsector + DEV_GELIBOOT_BSIZE > ((lastsector + 1) * DEV_BSIZE)) { ++ /* Don't read past the end of the disk */ ++ alignsector = (lastsector * DEV_BSIZE) + DEV_BSIZE ++ - DEV_GELIBOOT_BSIZE; ++ } + error = read_func(NULL, dskp, alignsector, &buf, DEV_GELIBOOT_BSIZE); + if (error != 0) { + return (error); + } +- /* Extract the last DEV_BSIZE bytes from the block. */ +- error = eli_metadata_decode(buf + (DEV_GELIBOOT_BSIZE - DEV_BSIZE), +- &md); ++ /* Extract the last 4k sector of the disk. */ ++ error = eli_metadata_decode(buf, &md); + if (error != 0) { +- return (error); ++ /* Try the last 512 byte sector instead. */ ++ error = eli_metadata_decode(buf + ++ (DEV_GELIBOOT_BSIZE - DEV_BSIZE), &md); ++ if (error != 0) { ++ return (error); ++ } + } + + if (!(md.md_flags & G_ELI_FLAG_GELIBOOT)) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201610201838.u9KIccmJ035781>