svn commit: r307682 - in user/cperciva/freebsd-update-build/patches: 10.3-RELEASE 11.0-RELEASE

Gleb Smirnoff glebius at FreeBSD.org
Thu Oct 20 18:38:39 UTC 2016


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)) {


More information about the svn-src-user mailing list