From owner-svn-src-all@freebsd.org Mon Jan 22 21:45:55 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D2ABCED752A; Mon, 22 Jan 2018 21:45:55 +0000 (UTC) (envelope-from asomers@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id AD233707D6; Mon, 22 Jan 2018 21:45:55 +0000 (UTC) (envelope-from asomers@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id CCD341FE40; Mon, 22 Jan 2018 21:45:54 +0000 (UTC) (envelope-from asomers@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w0MLjs6a063502; Mon, 22 Jan 2018 21:45:54 GMT (envelope-from asomers@FreeBSD.org) Received: (from asomers@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w0MLjsAm063500; Mon, 22 Jan 2018 21:45:54 GMT (envelope-from asomers@FreeBSD.org) Message-Id: <201801222145.w0MLjsAm063500@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: asomers set sender to asomers@FreeBSD.org using -f From: Alan Somers Date: Mon, 22 Jan 2018 21:45:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r328266 - in head: contrib/netbsd-tests/lib/libc/sys lib/libc/sys X-SVN-Group: head X-SVN-Commit-Author: asomers X-SVN-Commit-Paths: in head: contrib/netbsd-tests/lib/libc/sys lib/libc/sys X-SVN-Commit-Revision: 328266 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 22 Jan 2018 21:45:55 -0000 Author: asomers Date: Mon Jan 22 21:45:54 2018 New Revision: 328266 URL: https://svnweb.freebsd.org/changeset/base/328266 Log: mlock(2): correct documentation for error conditions. The man page is years out of date regarding errors. Our implementation _does_ allow unaligned addresses, and it _does_not_ check for negative lengths, because the length is unsigned. It checks for overflow instead. Update the tests accordingly. Reviewed by: bcr MFC after: 3 weeks Differential Revision: https://reviews.freebsd.org/D13826 Modified: head/contrib/netbsd-tests/lib/libc/sys/t_mlock.c head/lib/libc/sys/mlock.2 Modified: head/contrib/netbsd-tests/lib/libc/sys/t_mlock.c ============================================================================== --- head/contrib/netbsd-tests/lib/libc/sys/t_mlock.c Mon Jan 22 20:56:21 2018 (r328265) +++ head/contrib/netbsd-tests/lib/libc/sys/t_mlock.c Mon Jan 22 21:45:54 2018 (r328266) @@ -133,38 +133,43 @@ ATF_TC_BODY(mlock_err, tc) ATF_REQUIRE_ERRNO(ENOMEM, mlock((char *)0, page) == -1); errno = 0; - ATF_REQUIRE_ERRNO(ENOMEM, mlock((char *)-1, page) == -1); - - errno = 0; ATF_REQUIRE_ERRNO(ENOMEM, munlock(NULL, page) == -1); errno = 0; ATF_REQUIRE_ERRNO(ENOMEM, munlock((char *)0, page) == -1); +#ifdef __FreeBSD__ + /* Wrap around should return EINVAL */ errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, mlock((char *)-1, page) == -1); + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, munlock((char *)-1, page) == -1); +#else + errno = 0; + ATF_REQUIRE_ERRNO(ENOMEM, mlock((char *)-1, page) == -1); + errno = 0; ATF_REQUIRE_ERRNO(ENOMEM, munlock((char *)-1, page) == -1); +#endif - buf = malloc(page); + buf = malloc(page); /* Get a valid address */ ATF_REQUIRE(buf != NULL); - - /* - * unlocking memory that is not locked is an error... - */ - +#ifdef __FreeBSD__ errno = 0; - ATF_REQUIRE_ERRNO(ENOMEM, munlock(buf, page) == -1); + /* Wrap around should return EINVAL */ + ATF_REQUIRE_ERRNO(EINVAL, mlock(buf, -page) == -1); + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, munlock(buf, -page) == -1); +#else + errno = 0; + ATF_REQUIRE_ERRNO(ENOMEM, mlock(buf, -page) == -1); + errno = 0; + ATF_REQUIRE_ERRNO(ENOMEM, munlock(buf, -page) == -1); +#endif + (void)free(buf); /* There is no sbrk on AArch64 and RISC-V */ #if !defined(__aarch64__) && !defined(__riscv) /* - * These are permitted to fail (EINVAL) but do not on NetBSD - */ - ATF_REQUIRE(mlock((void *)(((uintptr_t)buf) + page/3), page/5) == 0); - ATF_REQUIRE(munlock((void *)(((uintptr_t)buf) + page/3), page/5) == 0); - - (void)free(buf); - - /* * Try to create a pointer to an unmapped page - first after current * brk will likely do. */ @@ -360,6 +365,80 @@ ATF_TC_CLEANUP(mlock_nested, tc) } #endif +#ifdef __FreeBSD__ +ATF_TC_WITH_CLEANUP(mlock_unaligned); +#else +ATF_TC(mlock_unaligned); +#endif +ATF_TC_HEAD(mlock_unaligned, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that mlock(2) can lock page-unaligned memory"); +#ifdef __FreeBSD__ + atf_tc_set_md_var(tc, "require.config", "allow_sysctl_side_effects"); + atf_tc_set_md_var(tc, "require.user", "root"); +#endif +} + +ATF_TC_BODY(mlock_unaligned, tc) +{ + void *buf, *addr; + +#ifdef __FreeBSD__ + /* Set max_wired really really high to avoid EAGAIN */ + set_vm_max_wired(INT_MAX); +#endif + + buf = malloc(page); + ATF_REQUIRE(buf != NULL); + + if ((uintptr_t)buf & ((uintptr_t)page - 1)) + addr = buf; + else + addr = (void *)(((uintptr_t)buf) + page/3); + + ATF_REQUIRE_EQ(mlock(addr, page/5), 0); + ATF_REQUIRE_EQ(munlock(addr, page/5), 0); + + (void)free(buf); +} + +#ifdef __FreeBSD__ +ATF_TC_CLEANUP(mlock_unaligned, tc) +{ + + restore_vm_max_wired(); +} +#endif + +ATF_TC(munlock_unlocked); +ATF_TC_HEAD(munlock_unlocked, tc) +{ + atf_tc_set_md_var(tc, "descr", +#ifdef __FreeBSD__ + "munlock(2) accepts unlocked memory"); +#else + "munlock(2) of unlocked memory is an error"); +#endif + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(munlock_unlocked, tc) +{ + void *buf; + + buf = malloc(page); + ATF_REQUIRE(buf != NULL); + +#ifdef __FreeBSD__ + ATF_REQUIRE_EQ(munlock(buf, page), 0); +#else + errno = 0; + ATF_REQUIRE_ERRNO(ENOMEM, munlock(buf, page) == -1); +#endif + (void)free(buf); +} + ATF_TP_ADD_TCS(tp) { @@ -371,6 +450,8 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, mlock_limits); ATF_TP_ADD_TC(tp, mlock_mmap); ATF_TP_ADD_TC(tp, mlock_nested); + ATF_TP_ADD_TC(tp, mlock_unaligned); + ATF_TP_ADD_TC(tp, munlock_unlocked); return atf_no_error(); } Modified: head/lib/libc/sys/mlock.2 ============================================================================== --- head/lib/libc/sys/mlock.2 Mon Jan 22 20:56:21 2018 (r328265) +++ head/lib/libc/sys/mlock.2 Mon Jan 22 21:45:54 2018 (r328266) @@ -28,7 +28,7 @@ .\" @(#)mlock.2 8.2 (Berkeley) 12/11/93 .\" $FreeBSD$ .\" -.Dd May 17, 2014 +.Dd Jan 22, 2018 .Dt MLOCK 2 .Os .Sh NAME @@ -125,7 +125,7 @@ will fail if: .Va security.bsd.unprivileged_mlock is set to 0 and the caller is not the super-user. .It Bq Er EINVAL -The address given is not page aligned or the length is negative. +The address range given wraps around zero. .It Bq Er EAGAIN Locking the indicated range would exceed the system limit for locked memory. .It Bq Er ENOMEM @@ -143,7 +143,7 @@ will fail if: .Va security.bsd.unprivileged_mlock is set to 0 and the caller is not the super-user. .It Bq Er EINVAL -The address given is not page aligned or the length is negative. +The address range given wraps around zero. .It Bq Er ENOMEM Some or all of the address range specified by the addr and len arguments does not correspond to valid mapped pages in the address space