svn commit: r334626 - in head: lib/libc/amd64 lib/libc/amd64/sys lib/libc/arm lib/libc/arm/sys lib/libc/i386 lib/libc/i386/sys lib/libc/mips lib/libc/mips/sys lib/libc/powerpc lib/libc/powerpc/sys ...

Mark Johnston markj at FreeBSD.org
Mon Jun 4 19:35:21 UTC 2018


Author: markj
Date: Mon Jun  4 19:35:15 2018
New Revision: 334626
URL: https://svnweb.freebsd.org/changeset/base/334626

Log:
  Reimplement brk() and sbrk() to avoid the use of _end.
  
  Previously, libc.so would initialize its notion of the break address
  using _end, a special symbol emitted by the static linker following
  the bss section.  Compatibility issues between lld and ld.bfd could
  cause the wrong definition of _end (libc.so's definition rather than
  that of the executable) to be used, breaking the brk()/sbrk()
  interface.
  
  Avoid this problem and future interoperability issues by simply not
  relying on _end.  Instead, modify the break() system call to return
  the kernel's view of the current break address, and have libc
  initialize its state using an extra syscall upon the first use of the
  interface.  As a side effect, this appears to fix brk()/sbrk() usage
  in executables run with rtld direct exec, since the kernel and libc.so
  no longer maintain separate views of the process' break address.
  
  PR:		228574
  Reviewed by:	kib (previous version)
  MFC after:	2 months
  Differential Revision:	https://reviews.freebsd.org/D15663

Added:
  head/lib/libc/sys/brk.c   (contents, props changed)
  head/lib/libc/tests/sys/brk_test.c   (contents, props changed)
Deleted:
  head/lib/libc/amd64/sys/brk.S
  head/lib/libc/amd64/sys/sbrk.S
  head/lib/libc/arm/sys/brk.S
  head/lib/libc/arm/sys/sbrk.S
  head/lib/libc/i386/sys/brk.S
  head/lib/libc/i386/sys/sbrk.S
  head/lib/libc/mips/sys/brk.S
  head/lib/libc/mips/sys/sbrk.S
  head/lib/libc/powerpc/sys/brk.S
  head/lib/libc/powerpc/sys/sbrk.S
  head/lib/libc/powerpc64/sys/brk.S
  head/lib/libc/powerpc64/sys/sbrk.S
  head/lib/libc/sparc64/sys/brk.S
  head/lib/libc/sparc64/sys/sbrk.S
Modified:
  head/lib/libc/amd64/Symbol.map
  head/lib/libc/amd64/sys/Makefile.inc
  head/lib/libc/arm/Symbol.map
  head/lib/libc/arm/sys/Makefile.inc
  head/lib/libc/i386/Symbol.map
  head/lib/libc/i386/sys/Makefile.inc
  head/lib/libc/mips/Symbol.map
  head/lib/libc/mips/sys/Makefile.inc
  head/lib/libc/powerpc/Symbol.map
  head/lib/libc/powerpc/sys/Makefile.inc
  head/lib/libc/powerpc64/Symbol.map
  head/lib/libc/powerpc64/sys/Makefile.inc
  head/lib/libc/riscv/sys/Makefile.inc
  head/lib/libc/sparc64/Symbol.map
  head/lib/libc/sparc64/sys/Makefile.inc
  head/lib/libc/sys/Makefile.inc
  head/lib/libc/sys/brk.2
  head/lib/libc/tests/sys/Makefile
  head/sys/compat/freebsd32/syscalls.master
  head/sys/kern/syscalls.master
  head/sys/vm/vm_unix.c

Modified: head/lib/libc/amd64/Symbol.map
==============================================================================
--- head/lib/libc/amd64/Symbol.map	Mon Jun  4 18:51:06 2018	(r334625)
+++ head/lib/libc/amd64/Symbol.map	Mon Jun  4 19:35:15 2018	(r334626)
@@ -63,7 +63,6 @@ FBSDprivate_1.0 {
 	signalcontext;
 	__siglongjmp;
 	_brk;
-	_end;
 	__sys_vfork;
 	_vfork;
 };

Modified: head/lib/libc/amd64/sys/Makefile.inc
==============================================================================
--- head/lib/libc/amd64/sys/Makefile.inc	Mon Jun  4 18:51:06 2018	(r334625)
+++ head/lib/libc/amd64/sys/Makefile.inc	Mon Jun  4 19:35:15 2018	(r334626)
@@ -8,7 +8,7 @@ SRCS+=	\
 	amd64_set_fsbase.c \
 	amd64_set_gsbase.c
 
-MDASM=	vfork.S brk.S cerror.S getcontext.S sbrk.S
+MDASM=	vfork.S cerror.S getcontext.S
 
 # Don't generate default code for these syscalls:
-NOASM+=	vfork.o
+NOASM+=	sbrk.o vfork.o

Modified: head/lib/libc/arm/Symbol.map
==============================================================================
--- head/lib/libc/arm/Symbol.map	Mon Jun  4 18:51:06 2018	(r334625)
+++ head/lib/libc/arm/Symbol.map	Mon Jun  4 19:35:15 2018	(r334626)
@@ -58,7 +58,6 @@ FBSDprivate_1.0 {
 	__sys_vfork;
 	_vfork;
 	_brk;
-	_end;
 	_sbrk;
 
 	_libc_arm_fpu_present;

Modified: head/lib/libc/arm/sys/Makefile.inc
==============================================================================
--- head/lib/libc/arm/sys/Makefile.inc	Mon Jun  4 18:51:06 2018	(r334625)
+++ head/lib/libc/arm/sys/Makefile.inc	Mon Jun  4 19:35:15 2018	(r334626)
@@ -2,7 +2,7 @@
 
 SRCS+=	__vdso_gettc.c
 
-MDASM= Ovfork.S brk.S cerror.S sbrk.S syscall.S
+MDASM= Ovfork.S cerror.S syscall.S
 
 # Don't generate default code for these syscalls:
-NOASM+=	vfork.o
+NOASM+=	sbrk.o vfork.o

Modified: head/lib/libc/i386/Symbol.map
==============================================================================
--- head/lib/libc/i386/Symbol.map	Mon Jun  4 18:51:06 2018	(r334625)
+++ head/lib/libc/i386/Symbol.map	Mon Jun  4 19:35:15 2018	(r334626)
@@ -61,6 +61,5 @@ FBSDprivate_1.0 {
 	__siglongjmp;
 	__sys_vfork;
 	_vfork;
-	_end;
 	_brk;
 };

Modified: head/lib/libc/i386/sys/Makefile.inc
==============================================================================
--- head/lib/libc/i386/sys/Makefile.inc	Mon Jun  4 18:51:06 2018	(r334625)
+++ head/lib/libc/i386/sys/Makefile.inc	Mon Jun  4 19:35:15 2018	(r334626)
@@ -7,9 +7,9 @@ SRCS+=	i386_clr_watch.c i386_set_watch.c i386_vm86.c
 SRCS+=	i386_get_fsbase.c i386_get_gsbase.c i386_get_ioperm.c i386_get_ldt.c \
 	i386_set_fsbase.c i386_set_gsbase.c i386_set_ioperm.c i386_set_ldt.c
 
-MDASM=	Ovfork.S brk.S cerror.S getcontext.S sbrk.S syscall.S
+MDASM=	Ovfork.S cerror.S getcontext.S syscall.S
 
-NOASM+=	vfork.o
+NOASM+=	sbrk.o vfork.o
 
 MAN+=	i386_get_ioperm.2 i386_get_ldt.2 i386_vm86.2
 MAN+=	i386_set_watch.3

Modified: head/lib/libc/mips/Symbol.map
==============================================================================
--- head/lib/libc/mips/Symbol.map	Mon Jun  4 18:51:06 2018	(r334625)
+++ head/lib/libc/mips/Symbol.map	Mon Jun  4 19:35:15 2018	(r334626)
@@ -50,7 +50,6 @@ FBSDprivate_1.0 {
 	__siglongjmp;
 	__sys_vfork;
 	_vfork;
-	_end;
 	_brk;
 	_sbrk;
 };

Modified: head/lib/libc/mips/sys/Makefile.inc
==============================================================================
--- head/lib/libc/mips/sys/Makefile.inc	Mon Jun  4 18:51:06 2018	(r334625)
+++ head/lib/libc/mips/sys/Makefile.inc	Mon Jun  4 19:35:15 2018	(r334626)
@@ -2,7 +2,7 @@
 
 SRCS+=	trivial-vdso_tc.c
 
-MDASM=  Ovfork.S brk.S cerror.S sbrk.S syscall.S
+MDASM=  Ovfork.S cerror.S syscall.S
 
 # Don't generate default code for these syscalls:
-NOASM+=	vfork.o
+NOASM+=	sbrk.o vfork.o

Modified: head/lib/libc/powerpc/Symbol.map
==============================================================================
--- head/lib/libc/powerpc/Symbol.map	Mon Jun  4 18:51:06 2018	(r334625)
+++ head/lib/libc/powerpc/Symbol.map	Mon Jun  4 19:35:15 2018	(r334626)
@@ -54,5 +54,4 @@ FBSDprivate_1.0 {
 	signalcontext;
 	__signalcontext;
 	__syncicache;
-	_end;
 };

Modified: head/lib/libc/powerpc/sys/Makefile.inc
==============================================================================
--- head/lib/libc/powerpc/sys/Makefile.inc	Mon Jun  4 18:51:06 2018	(r334625)
+++ head/lib/libc/powerpc/sys/Makefile.inc	Mon Jun  4 19:35:15 2018	(r334626)
@@ -1,3 +1,3 @@
 # $FreeBSD$
 
-MDASM+=	brk.S cerror.S sbrk.S
+MDASM+=	cerror.S

Modified: head/lib/libc/powerpc64/Symbol.map
==============================================================================
--- head/lib/libc/powerpc64/Symbol.map	Mon Jun  4 18:51:06 2018	(r334625)
+++ head/lib/libc/powerpc64/Symbol.map	Mon Jun  4 19:35:15 2018	(r334626)
@@ -50,5 +50,4 @@ FBSDprivate_1.0 {
 	signalcontext;
 	__signalcontext;
 	__syncicache;
-	_end;
 };

Modified: head/lib/libc/powerpc64/sys/Makefile.inc
==============================================================================
--- head/lib/libc/powerpc64/sys/Makefile.inc	Mon Jun  4 18:51:06 2018	(r334625)
+++ head/lib/libc/powerpc64/sys/Makefile.inc	Mon Jun  4 19:35:15 2018	(r334626)
@@ -1,3 +1,3 @@
 # $FreeBSD$
 
-MDASM+=	brk.S cerror.S sbrk.S
+MDASM+=	cerror.S

Modified: head/lib/libc/riscv/sys/Makefile.inc
==============================================================================
--- head/lib/libc/riscv/sys/Makefile.inc	Mon Jun  4 18:51:06 2018	(r334625)
+++ head/lib/libc/riscv/sys/Makefile.inc	Mon Jun  4 19:35:15 2018	(r334626)
@@ -7,4 +7,4 @@ MDASM=	cerror.S \
 	vfork.S
 
 # Don't generate default code for these syscalls:
-NOASM+=	vfork.o
+NOASM+=	sbrk.o vfork.o

Modified: head/lib/libc/sparc64/Symbol.map
==============================================================================
--- head/lib/libc/sparc64/Symbol.map	Mon Jun  4 18:51:06 2018	(r334625)
+++ head/lib/libc/sparc64/Symbol.map	Mon Jun  4 19:35:15 2018	(r334626)
@@ -81,7 +81,6 @@ FBSDprivate_1.0 {
 	__siglongjmp;
 	__sys_brk;
 	_brk;
-	_end;
 	__sys_sbrk;
 	_sbrk;
 	__sys_vfork;

Modified: head/lib/libc/sparc64/sys/Makefile.inc
==============================================================================
--- head/lib/libc/sparc64/sys/Makefile.inc	Mon Jun  4 18:51:06 2018	(r334625)
+++ head/lib/libc/sparc64/sys/Makefile.inc	Mon Jun  4 19:35:15 2018	(r334626)
@@ -12,4 +12,4 @@ SRCS+=	__sparc_sigtramp_setup.c \
 
 CFLAGS+= -I${LIBC_SRCTOP}/sparc64/fpu
 
-MDASM+=	brk.S cerror.S sbrk.S sigaction1.S
+MDASM+=	cerror.S sigaction1.S

Modified: head/lib/libc/sys/Makefile.inc
==============================================================================
--- head/lib/libc/sys/Makefile.inc	Mon Jun  4 18:51:06 2018	(r334625)
+++ head/lib/libc/sys/Makefile.inc	Mon Jun  4 19:35:15 2018	(r334626)
@@ -17,8 +17,7 @@
 # While historically machine dependent, all architectures have the following
 # declarations in common:
 #
-NOASM=	break.o \
-	exit.o \
+NOASM=	exit.o \
 	getlogin.o \
 	sstk.o \
 	yield.o
@@ -45,6 +44,7 @@ SRCS+= getdirentries.c
 NOASM+= getdirentries.o
 PSEUDO+= _getdirentries.o
 
+SRCS+= brk.c
 SRCS+= pipe.c
 SRCS+= vadvise.c
 

Modified: head/lib/libc/sys/brk.2
==============================================================================
--- head/lib/libc/sys/brk.2	Mon Jun  4 18:51:06 2018	(r334625)
+++ head/lib/libc/sys/brk.2	Mon Jun  4 19:35:15 2018	(r334626)
@@ -28,7 +28,7 @@
 .\"     @(#)brk.2	8.4 (Berkeley) 5/1/95
 .\" $FreeBSD$
 .\"
-.Dd May 24, 2018
+.Dd June 2, 2018
 .Dt BRK 2
 .Os
 .Sh NAME
@@ -183,3 +183,8 @@ is sometimes used to monitor heap use by calling with 
 The result is unlikely to reflect actual utilization in combination with an
 .Xr mmap 2
 based malloc.
+.Pp
+.Fn brk
+and
+.Fn sbrk
+are not thread-safe.

Added: head/lib/libc/sys/brk.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/libc/sys/brk.c	Mon Jun  4 19:35:15 2018	(r334626)
@@ -0,0 +1,107 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2018 Mark Johnston <markj at FreeBSD.org>
+ *
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+void *__sys_break(char *nsize);
+
+static uintptr_t curbrk, minbrk;
+static int curbrk_initted;
+
+static int
+initbrk(void)
+{
+	void *newbrk;
+
+	if (!curbrk_initted) {
+		newbrk = __sys_break(NULL);
+		if (newbrk == (void *)-1)
+			return (-1);
+		curbrk = minbrk = (uintptr_t)newbrk;
+		curbrk_initted = 1;
+	}
+	return (0);
+}
+
+static void *
+mvbrk(void *addr)
+{
+	uintptr_t oldbrk;
+
+	if ((uintptr_t)addr < minbrk) {
+		/* Emulate legacy error handling in the syscall. */
+		errno = EINVAL;
+		return ((void *)-1);
+	}
+	if (__sys_break(addr) == (void *)-1)
+		return ((void *)-1);
+	oldbrk = curbrk;
+	curbrk = (uintptr_t)addr;
+	return ((void *)oldbrk);
+}
+
+int
+brk(const void *addr)
+{
+
+	if (initbrk() == -1)
+		return (-1);
+	if ((uintptr_t)addr < minbrk)
+		addr = (void *)minbrk;
+	return (mvbrk(__DECONST(void *, addr)) == (void *)-1 ? -1 : 0);
+}
+
+int
+_brk(const void *addr)
+{
+
+	if (initbrk() == -1)
+		return (-1);
+	return (mvbrk(__DECONST(void *, addr)) == (void *)-1 ? -1 : 0);
+}
+
+void *
+sbrk(intptr_t incr)
+{
+
+	if (initbrk() == -1)
+		return ((void *)-1);
+	if ((incr > 0 && curbrk + incr < curbrk) ||
+	    (incr < 0 && curbrk + incr > curbrk)) {
+		/* Emulate legacy error handling in the syscall. */
+		errno = EINVAL;
+		return ((void *)-1);
+	}
+	return (mvbrk((void *)(curbrk + incr)));
+}

Modified: head/lib/libc/tests/sys/Makefile
==============================================================================
--- head/lib/libc/tests/sys/Makefile	Mon Jun  4 18:51:06 2018	(r334625)
+++ head/lib/libc/tests/sys/Makefile	Mon Jun  4 19:35:15 2018	(r334626)
@@ -4,6 +4,7 @@ PACKAGE=			tests
 
 .include <bsd.own.mk>
 
+ATF_TESTS_C+=			brk_test
 ATF_TESTS_C+=			queue_test
 
 # TODO: clone, lwp_create, lwp_ctl, posix_fadvise, recvmmsg,

Added: head/lib/libc/tests/sys/brk_test.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/libc/tests/sys/brk_test.c	Mon Jun  4 19:35:15 2018	(r334626)
@@ -0,0 +1,149 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2018 Mark Johnston <markj at FreeBSD.org>
+ *
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/mman.h>
+
+#include <errno.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+ATF_TC(brk_basic);
+ATF_TC_HEAD(brk_basic, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Verify basic brk() functionality");
+}
+ATF_TC_BODY(brk_basic, tc)
+{
+	void *oldbrk, *newbrk;
+	int error;
+
+	/* Reset the break. */
+	error = brk(0);
+	ATF_REQUIRE_MSG(error == 0, "brk: %s", strerror(errno));
+
+	oldbrk = sbrk(0);
+	ATF_REQUIRE(oldbrk != (void *)-1);
+
+	/* Try to allocate a page. */
+	error = brk((void *)((intptr_t)oldbrk + PAGE_SIZE * 2));
+	ATF_REQUIRE_MSG(error == 0, "brk: %s", strerror(errno));
+
+	/*
+	 * Attempt to set the break below minbrk.  This should have no effect.
+	 */
+	error = brk((void *)((intptr_t)oldbrk - 1));
+	ATF_REQUIRE_MSG(error == 0, "brk: %s", strerror(errno));
+	newbrk = sbrk(0);
+	ATF_REQUIRE_MSG(newbrk != (void *)-1, "sbrk: %s", strerror(errno));
+	ATF_REQUIRE(newbrk == oldbrk);
+}
+
+ATF_TC(sbrk_basic);
+ATF_TC_HEAD(sbrk_basic, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Verify basic sbrk() functionality");
+}
+ATF_TC_BODY(sbrk_basic, tc)
+{
+	void *newbrk, *oldbrk;
+	int *p;
+
+	oldbrk = sbrk(0);
+	ATF_REQUIRE_MSG(oldbrk != (void *)-1, "sbrk: %s", strerror(errno));
+	p = sbrk(sizeof(*p));
+	*p = 0;
+	ATF_REQUIRE(oldbrk == p);
+
+	newbrk = sbrk(-sizeof(*p));
+	ATF_REQUIRE_MSG(newbrk != (void *)-1, "sbrk: %s", strerror(errno));
+	ATF_REQUIRE(oldbrk == sbrk(0));
+
+	oldbrk = sbrk(PAGE_SIZE * 2 + 1);
+	ATF_REQUIRE_MSG(oldbrk != (void *)-1, "sbrk: %s", strerror(errno));
+	memset(oldbrk, 0, PAGE_SIZE * 2 + 1);
+	newbrk = sbrk(-(PAGE_SIZE * 2 + 1));
+	ATF_REQUIRE_MSG(newbrk != (void *)-1, "sbrk: %s", strerror(errno));
+	ATF_REQUIRE(sbrk(0) == oldbrk);
+}
+
+ATF_TC(mlockfuture);
+ATF_TC_HEAD(mlockfuture, tc)
+{
+	atf_tc_set_md_var(tc, "descr",
+	    "Verify that mlockall(MCL_FUTURE) applies to the data segment");
+}
+ATF_TC_BODY(mlockfuture, tc)
+{
+	void *oldbrk, *n, *newbrk;
+	int error;
+	char v;
+
+	error = mlockall(MCL_FUTURE);
+	ATF_REQUIRE_MSG(error == 0,
+	    "mlockall: %s", strerror(errno));
+
+	/*
+	 * Advance the break so that at least one page is added to the data
+	 * segment.  This page should be automatically faulted in to the address
+	 * space.
+	 */
+	oldbrk = sbrk(0);
+	ATF_REQUIRE(oldbrk != (void *)-1);
+	newbrk = sbrk(PAGE_SIZE * 2);
+	ATF_REQUIRE(newbrk != (void *)-1);
+
+	n = (void *)(((uintptr_t)oldbrk + PAGE_SIZE) & ~PAGE_SIZE);
+	v = 0;
+	error = mincore(n, PAGE_SIZE, &v);
+	ATF_REQUIRE_MSG(error == 0,
+	    "mincore: %s", strerror(errno));
+	ATF_REQUIRE_MSG((v & MINCORE_INCORE) != 0,
+	    "unexpected page flags %#x", v);
+
+	error = brk(oldbrk);
+	ATF_REQUIRE(error == 0);
+
+	error = munlockall();
+	ATF_REQUIRE_MSG(error == 0,
+	    "munlockall: %s", strerror(errno));
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+	ATF_TP_ADD_TC(tp, brk_basic);
+	ATF_TP_ADD_TC(tp, sbrk_basic);
+	ATF_TP_ADD_TC(tp, mlockfuture);
+
+	return (atf_no_error());
+}

Modified: head/sys/compat/freebsd32/syscalls.master
==============================================================================
--- head/sys/compat/freebsd32/syscalls.master	Mon Jun  4 18:51:06 2018	(r334625)
+++ head/sys/compat/freebsd32/syscalls.master	Mon Jun  4 19:35:15 2018	(r334626)
@@ -87,7 +87,7 @@
 					int mode, int dev); }
 15	AUE_CHMOD	NOPROTO	{ int chmod(char *path, int mode); }
 16	AUE_CHOWN	NOPROTO	{ int chown(char *path, int uid, int gid); }
-17	AUE_NULL	NOPROTO	{ int obreak(char *nsize); } break \
+17	AUE_NULL	NOPROTO	{ caddr_t obreak(char *nsize); } break \
 				    obreak_args int
 18	AUE_GETFSSTAT	COMPAT4	{ int freebsd32_getfsstat( \
 				    struct statfs32 *buf, long bufsize, \

Modified: head/sys/kern/syscalls.master
==============================================================================
--- head/sys/kern/syscalls.master	Mon Jun  4 18:51:06 2018	(r334625)
+++ head/sys/kern/syscalls.master	Mon Jun  4 19:35:15 2018	(r334626)
@@ -118,7 +118,7 @@
 15	AUE_CHMOD	STD	{ int chmod(_In_z_ char *path, int mode); }
 16	AUE_CHOWN	STD	{ int chown(_In_z_ char *path, \
 				    int uid, int gid); }
-17	AUE_NULL	STD	{ int obreak(_In_ char *nsize); } break \
+17	AUE_NULL	STD	{ caddr_t obreak(_In_ char *nsize); } break \
 				    obreak_args int
 18	AUE_GETFSSTAT	COMPAT4	{ int getfsstat( \
 				    _Out_writes_bytes_opt_(bufsize) \

Modified: head/sys/vm/vm_unix.c
==============================================================================
--- head/sys/vm/vm_unix.c	Mon Jun  4 18:51:06 2018	(r334625)
+++ head/sys/vm/vm_unix.c	Mon Jun  4 19:35:15 2018	(r334626)
@@ -102,13 +102,16 @@ sys_obreak(struct thread *td, struct obreak_args *uap)
 		}
 	} else if (new < base) {
 		/*
-		 * This is simply an invalid value.  If someone wants to
-		 * do fancy address space manipulations, mmap and munmap
-		 * can do most of what the user would want.
+		 * Simply return the current break address without
+		 * modifying any state.  This is an ad-hoc interface
+		 * used by libc to determine the initial break address,
+		 * avoiding a dependency on magic features in the system
+		 * linker.
 		 */
-		error = EINVAL;
+		new = old;
 		goto done;
 	}
+
 	if (new > old) {
 		if (!old_mlock && map->flags & MAP_WIREFUTURE) {
 			if (ptoa(pmap_wired_count(map->pmap)) +
@@ -224,6 +227,9 @@ done:
 	if (do_map_wirefuture)
 		(void) vm_map_wire(map, old, new,
 		    VM_MAP_WIRE_USER|VM_MAP_WIRE_NOHOLES);
+
+	if (error == 0)
+		td->td_retval[0] = new;
 
 	return (error);
 #else /* defined(__aarch64__) || defined(__riscv__) */


More information about the svn-src-all mailing list