Index: stable/12/contrib/netbsd-tests/lib/libc/gen/t_ftok.c =================================================================== --- stable/12/contrib/netbsd-tests/lib/libc/gen/t_ftok.c (revision 350303) +++ stable/12/contrib/netbsd-tests/lib/libc/gen/t_ftok.c (revision 350304) @@ -1,108 +1,108 @@ /* $NetBSD: t_ftok.c,v 1.2 2017/01/10 15:19:52 christos Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Jukka Ruohonen. * * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 __RCSID("$NetBSD: t_ftok.c,v 1.2 2017/01/10 15:19:52 christos Exp $"); #include #include #include #include #include static const char *path = "ftok"; static const char *hlnk = "hlnk"; static const char *slnk = "slnk"; static const int key = 123456789; ATF_TC(ftok_err); ATF_TC_HEAD(ftok_err, tc) { atf_tc_set_md_var(tc, "descr", "Test errors from ftok(3)"); } ATF_TC_BODY(ftok_err, tc) { ATF_REQUIRE(ftok("/a/b/c/d/e/f/g/h/i", key) == -1); } ATF_TC_WITH_CLEANUP(ftok_link); ATF_TC_HEAD(ftok_link, tc) { atf_tc_set_md_var(tc, "descr", "Test that links return the same key"); } ATF_TC_BODY(ftok_link, tc) { key_t k1, k2, k3; int fd; - fd = open(path, O_RDONLY | O_CREAT); + fd = open(path, O_RDONLY | O_CREAT, 0600); ATF_REQUIRE(fd >= 0); (void)close(fd); ATF_REQUIRE(link(path, hlnk) == 0); ATF_REQUIRE(symlink(path, slnk) == 0); k1 = ftok(path, key); k2 = ftok(hlnk, key); k3 = ftok(slnk, key); ATF_REQUIRE(k1 != -1); ATF_REQUIRE(k2 != -1); ATF_REQUIRE(k3 != -1); if (k1 != k2) atf_tc_fail("ftok(3) gave different key for a hard link"); if (k1 != k3) atf_tc_fail("ftok(3) gave different key for a symbolic link"); ATF_REQUIRE(unlink(path) == 0); ATF_REQUIRE(unlink(hlnk) == 0); ATF_REQUIRE(unlink(slnk) == 0); } ATF_TC_CLEANUP(ftok_link, tc) { (void)unlink(path); (void)unlink(hlnk); (void)unlink(slnk); } ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, ftok_err); ATF_TP_ADD_TC(tp, ftok_link); return atf_no_error(); } Index: stable/12/contrib/netbsd-tests/lib/libc/stdio/t_fopen.c =================================================================== --- stable/12/contrib/netbsd-tests/lib/libc/stdio/t_fopen.c (revision 350303) +++ stable/12/contrib/netbsd-tests/lib/libc/stdio/t_fopen.c (revision 350304) @@ -1,446 +1,446 @@ /* $NetBSD: t_fopen.c,v 1.3 2011/09/14 14:34:37 martin Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Jukka Ruohonen. * * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 __RCSID("$NetBSD: t_fopen.c,v 1.3 2011/09/14 14:34:37 martin Exp $"); #include #include #include #include #include #include #include #include static const char *path = "fopen"; ATF_TC_WITH_CLEANUP(fdopen_close); ATF_TC_HEAD(fdopen_close, tc) { atf_tc_set_md_var(tc, "descr", "See that descriptors are closed"); } ATF_TC_BODY(fdopen_close, tc) { FILE *f; int fd; /* * Check that the file descriptor * used to fdopen(3) a stream is * closed once the stream is closed. */ - fd = open(path, O_RDWR | O_CREAT); + fd = open(path, O_RDWR | O_CREAT, 0600); ATF_REQUIRE(fd >= 0); f = fdopen(fd, "w+"); ATF_REQUIRE(f != NULL); ATF_REQUIRE(fclose(f) == 0); ATF_REQUIRE(close(fd) == -1); ATF_REQUIRE(unlink(path) == 0); } ATF_TC_CLEANUP(fdopen_close, tc) { (void)unlink(path); } ATF_TC_WITH_CLEANUP(fdopen_err); ATF_TC_HEAD(fdopen_err, tc) { atf_tc_set_md_var(tc, "descr", "Test errors from fdopen(3)"); } ATF_TC_BODY(fdopen_err, tc) { int fd; - fd = open(path, O_RDONLY | O_CREAT); + fd = open(path, O_RDONLY | O_CREAT, 0600); ATF_REQUIRE(fd >= 0); errno = 0; ATF_REQUIRE_ERRNO(EINVAL, fdopen(fd, "w") == NULL); errno = 0; ATF_REQUIRE_ERRNO(EINVAL, fdopen(fd, "a") == NULL); ATF_REQUIRE(close(fd) == 0); errno = 0; ATF_REQUIRE_ERRNO(EBADF, fdopen(fd, "r") == NULL); errno = 0; ATF_REQUIRE_ERRNO(EBADF, fdopen(-1, "w+") == NULL); (void)unlink(path); } ATF_TC_CLEANUP(fdopen_err, tc) { (void)unlink(path); } ATF_TC_WITH_CLEANUP(fdopen_seek); ATF_TC_HEAD(fdopen_seek, tc) { atf_tc_set_md_var(tc, "descr", "Test stream position with fdopen(3)"); } ATF_TC_BODY(fdopen_seek, tc) { FILE *f; int fd; /* * Verify that the file position associated * with the stream corresponds with the offset * set earlier for the file descriptor. */ - fd = open(path, O_RDWR | O_CREAT); + fd = open(path, O_RDWR | O_CREAT, 0600); ATF_REQUIRE(fd >= 0); ATF_REQUIRE(write(fd, "garbage", 7) == 7); ATF_REQUIRE(lseek(fd, 3, SEEK_SET) == 3); f = fdopen(fd, "r+"); ATF_REQUIRE(f != NULL); ATF_REQUIRE(ftell(f) == 3); ATF_REQUIRE(fclose(f) == 0); ATF_REQUIRE(unlink(path) == 0); } ATF_TC_CLEANUP(fdopen_seek, tc) { (void)unlink(path); } ATF_TC_WITH_CLEANUP(fopen_err); ATF_TC_HEAD(fopen_err, tc) { atf_tc_set_md_var(tc, "descr", "Test errors from fopen(3)"); } ATF_TC_BODY(fopen_err, tc) { static const char *mode[] = { "x", "xr", "xr", "+r+", "R", "W+", " aXX", "Xr", " r+", "" }; char buf[PATH_MAX + 1]; size_t i; FILE *f; f = fopen(path, "w+"); ATF_REQUIRE(f != NULL); ATF_REQUIRE(fclose(f) == 0); /* * Note that also "invalid" characters * may follow the mode-string whenever * the first character is valid. */ for (i = 0; i < __arraycount(mode); i++) { errno = 0; f = fopen(path, mode[i]); if (f == NULL && errno == EINVAL) continue; if (f != NULL) (void)fclose(f); atf_tc_fail_nonfatal("opened file as '%s'", mode[i]); } (void)unlink(path); (void)memset(buf, 'x', sizeof(buf)); errno = 0; ATF_REQUIRE_ERRNO(EISDIR, fopen("/usr/bin", "w") == NULL); errno = 0; ATF_REQUIRE_ERRNO(ENOENT, fopen("/a/b/c/d/e/f", "r") == NULL); errno = 0; ATF_REQUIRE_ERRNO(ENAMETOOLONG, fopen(buf, "r+") == NULL); } ATF_TC_CLEANUP(fopen_err, tc) { (void)unlink(path); } ATF_TC_WITH_CLEANUP(fopen_append); ATF_TC_HEAD(fopen_append, tc) { atf_tc_set_md_var(tc, "descr", "Test that append-mode works"); } ATF_TC_BODY(fopen_append, tc) { char buf[15]; FILE *f; (void)memset(buf, 'x', sizeof(buf)); f = fopen(path, "w+"); ATF_REQUIRE(f != NULL); ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7); ATF_REQUIRE(fclose(f) == 0); f = fopen(path, "a"); ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7); ATF_REQUIRE(fclose(f) == 0); f = fopen(path, "r"); ATF_REQUIRE(fread(buf, 1, sizeof(buf), f) == 14); ATF_REQUIRE(strncmp(buf, "garbagegarbage", 14) == 0); ATF_REQUIRE(fclose(f) == 0); ATF_REQUIRE(unlink(path) == 0); } ATF_TC_CLEANUP(fopen_append, tc) { (void)unlink(path); } ATF_TC_WITH_CLEANUP(fopen_mode); ATF_TC_HEAD(fopen_mode, tc) { atf_tc_set_md_var(tc, "descr", "Test fopen(3) modes"); } ATF_TC_BODY(fopen_mode, tc) { size_t i; FILE *f; static const char *mode[] = { "r", "r+", "w", "w+", "a", "a+", "rb", "r+b", "wb", "w+b", "ab", "a+b" "re", "r+e", "we", "w+e", "ae", "a+e" "rf", "r+f", "wf", "w+f", "af", "a+f" }; f = fopen(path, "w+"); ATF_REQUIRE(f != NULL); ATF_REQUIRE(fclose(f) == 0); /* * Verify that various modes work. */ for (i = 0; i < __arraycount(mode); i++) { f = fopen(path, mode[i]); if (f != NULL) { ATF_REQUIRE(fclose(f) == 0); continue; } atf_tc_fail_nonfatal("failed to open file as %s", mode[i]); } (void)unlink(path); } ATF_TC_CLEANUP(fopen_mode, tc) { (void)unlink(path); } ATF_TC(fopen_perm); ATF_TC_HEAD(fopen_perm, tc) { atf_tc_set_md_var(tc, "descr", "Test permissions with fopen(3)"); atf_tc_set_md_var(tc, "require.user", "unprivileged"); } ATF_TC_BODY(fopen_perm, tc) { errno = 0; ATF_REQUIRE_ERRNO(EACCES, fopen("/bin/ls", "a+") == NULL); errno = 0; ATF_REQUIRE_ERRNO(EACCES, fopen("/bin/ls", "w+") == NULL); } #ifdef __NetBSD__ ATF_TC(fopen_regular); ATF_TC_HEAD(fopen_regular, tc) { atf_tc_set_md_var(tc, "descr", "Test fopen(3) with 'f' mode"); } ATF_TC_BODY(fopen_regular, tc) { static const char *mode[] = { "rf", "r+f", "wf", "w+f", "af", "a+f" }; static const char *devs[] = { _PATH_DEVNULL }; size_t i, j; FILE *f; for (i = 0; i < __arraycount(devs); i++) { for (j = 0; j < __arraycount(mode); j++) { errno = 0; f = fopen(devs[i], mode[j]); if (f == NULL && errno == EFTYPE) continue; if (f != NULL) (void)fclose(f); atf_tc_fail_nonfatal("opened %s as %s", devs[i], mode[j]); } } } #endif ATF_TC_WITH_CLEANUP(fopen_seek); ATF_TC_HEAD(fopen_seek, tc) { atf_tc_set_md_var(tc, "descr", "Test initial stream position"); } ATF_TC_BODY(fopen_seek, tc) { FILE *f; f = fopen(path, "w+"); ATF_REQUIRE(f != NULL); ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7); ATF_REQUIRE(fclose(f) == 0); /* * The position of the stream should be * at the start, except for append-mode. */ f = fopen(path, "r"); ATF_REQUIRE(f != NULL); ATF_REQUIRE(ftello(f) == 0); ATF_REQUIRE(fclose(f) == 0); f = fopen(path, "a"); ATF_REQUIRE(f != NULL); ATF_REQUIRE(ftello(f) == 7); ATF_REQUIRE(fclose(f) == 0); ATF_REQUIRE(unlink(path) == 0); } ATF_TC_CLEANUP(fopen_seek, tc) { (void)unlink(path); } ATF_TC_WITH_CLEANUP(freopen_std); ATF_TC_HEAD(freopen_std, tc) { atf_tc_set_md_var(tc, "descr", "A basic test of freopen(3)"); } ATF_TC_BODY(freopen_std, tc) { FILE *std[2] = { stdin, stdout }; char buf[15]; size_t i; FILE *f; /* * Associate a standard stream with a custom stream. * Then write to the standard stream and verify that * the result now appears in the custom stream. */ for (i = 0; i < __arraycount(std); i++) { (void)memset(buf, 'x', sizeof(buf)); f = fopen(path, "w+"); ATF_REQUIRE(f != NULL); f = freopen(path, "w+", std[i]); ATF_REQUIRE(f != NULL); ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7); ATF_REQUIRE(fprintf(std[i], "garbage") == 7); ATF_REQUIRE(fclose(f) == 0); f = fopen(path, "r"); ATF_REQUIRE(f != NULL); ATF_REQUIRE(fread(buf, 1, sizeof(buf), f) == 14); ATF_REQUIRE(strncmp(buf, "garbagegarbage", 14) == 0); ATF_REQUIRE(fclose(f) == 0); } ATF_REQUIRE(unlink(path) == 0); } ATF_TC_CLEANUP(freopen_std, tc) { (void)unlink(path); } ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, fdopen_close); ATF_TP_ADD_TC(tp, fdopen_err); ATF_TP_ADD_TC(tp, fdopen_seek); ATF_TP_ADD_TC(tp, fopen_append); ATF_TP_ADD_TC(tp, fopen_err); ATF_TP_ADD_TC(tp, fopen_mode); ATF_TP_ADD_TC(tp, fopen_perm); #ifdef __NetBSD__ ATF_TP_ADD_TC(tp, fopen_regular); #endif ATF_TP_ADD_TC(tp, fopen_seek); ATF_TP_ADD_TC(tp, freopen_std); return atf_no_error(); } Index: stable/12/contrib/netbsd-tests/lib/libc/sys/t_access.c =================================================================== --- stable/12/contrib/netbsd-tests/lib/libc/sys/t_access.c (revision 350303) +++ stable/12/contrib/netbsd-tests/lib/libc/sys/t_access.c (revision 350304) @@ -1,220 +1,220 @@ /* $NetBSD: t_access.c,v 2.2 2017/01/10 22:36:29 christos Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Jukka Ruohonen. * * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 __RCSID("$NetBSD: t_access.c,v 1.2 2017/01/10 22:36:29 christos Exp $"); #ifdef __FreeBSD__ #include /* For __FreeBSD_version */ #endif #include #include #include #include #include #include #include #include static const char path[] = "access"; static const int mode[4] = { R_OK, W_OK, X_OK, F_OK }; ATF_TC_WITH_CLEANUP(access_access); ATF_TC_HEAD(access_access, tc) { atf_tc_set_md_var(tc, "descr", "Test access(2) for EACCES"); atf_tc_set_md_var(tc, "require.user", "unprivileged"); } ATF_TC_BODY(access_access, tc) { const int perm[3] = { 0200, 0400, 0000 }; size_t i; int fd; - fd = open(path, O_RDONLY | O_CREAT); + fd = open(path, O_RDONLY | O_CREAT, 0600); if (fd < 0) return; for (i = 0; i < __arraycount(mode) - 1; i++) { ATF_REQUIRE(fchmod(fd, perm[i]) == 0); errno = 0; ATF_REQUIRE(access(path, mode[i]) != 0); ATF_REQUIRE(errno == EACCES); } ATF_REQUIRE(close(fd) == 0); } ATF_TC_CLEANUP(access_access, tc) { (void)unlink(path); } ATF_TC(access_fault); ATF_TC_HEAD(access_fault, tc) { atf_tc_set_md_var(tc, "descr", "Test access(2) for EFAULT"); } ATF_TC_BODY(access_fault, tc) { size_t i; for (i = 0; i < __arraycount(mode); i++) { errno = 0; ATF_REQUIRE(access(NULL, mode[i]) != 0); ATF_REQUIRE(errno == EFAULT); errno = 0; ATF_REQUIRE(access((char *)-1, mode[i]) != 0); ATF_REQUIRE(errno == EFAULT); } } ATF_TC(access_inval); ATF_TC_HEAD(access_inval, tc) { atf_tc_set_md_var(tc, "descr", "Test access(2) for EINVAL"); } ATF_TC_BODY(access_inval, tc) { #if defined(__FreeBSD__) && __FreeBSD_version < 1100033 atf_tc_expect_fail("arguments to access aren't validated; see " "bug # 181155 for more details"); #endif errno = 0; ATF_REQUIRE(access("/usr", -1) != 0); ATF_REQUIRE(errno == EINVAL); } ATF_TC(access_notdir); ATF_TC_HEAD(access_notdir, tc) { atf_tc_set_md_var(tc, "descr", "Test access(2) for ENOTDIR"); } ATF_TC_BODY(access_notdir, tc) { size_t i; for (i = 0; i < __arraycount(mode); i++) { errno = 0; /* * IEEE Std 1003.1-2008 about ENOTDIR: * * "A component of the path prefix is not a directory, * or the path argument contains at least one non- * character and ends with one or more trailing * characters and the last pathname component names an * existing file that is neither a directory nor a symbolic * link to a directory." */ ATF_REQUIRE(access("/etc/passwd//", mode[i]) != 0); ATF_REQUIRE(errno == ENOTDIR); } } ATF_TC(access_notexist); ATF_TC_HEAD(access_notexist, tc) { atf_tc_set_md_var(tc, "descr", "Test access(2) for ENOENT"); } ATF_TC_BODY(access_notexist, tc) { size_t i; for (i = 0; i < __arraycount(mode); i++) { errno = 0; ATF_REQUIRE(access("", mode[i]) != 0); ATF_REQUIRE(errno == ENOENT); } } ATF_TC(access_toolong); ATF_TC_HEAD(access_toolong, tc) { atf_tc_set_md_var(tc, "descr", "Test access(2) for ENAMETOOLONG"); } ATF_TC_BODY(access_toolong, tc) { char *buf; size_t i; buf = malloc(PATH_MAX); if (buf == NULL) return; for (i = 0; i < PATH_MAX; i++) buf[i] = 'x'; for (i = 0; i < __arraycount(mode); i++) { errno = 0; ATF_REQUIRE(access(buf, mode[i]) != 0); ATF_REQUIRE(errno == ENAMETOOLONG); } free(buf); } ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, access_access); ATF_TP_ADD_TC(tp, access_fault); ATF_TP_ADD_TC(tp, access_inval); ATF_TP_ADD_TC(tp, access_notdir); ATF_TP_ADD_TC(tp, access_notexist); ATF_TP_ADD_TC(tp, access_toolong); return atf_no_error(); } Index: stable/12/contrib/netbsd-tests/lib/libc/sys/t_mprotect.c =================================================================== --- stable/12/contrib/netbsd-tests/lib/libc/sys/t_mprotect.c (revision 350303) +++ stable/12/contrib/netbsd-tests/lib/libc/sys/t_mprotect.c (revision 350304) @@ -1,368 +1,368 @@ /* $NetBSD: t_mprotect.c,v 1.4 2016/05/28 14:34:49 christos Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Jukka Ruohonen. * * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 __RCSID("$NetBSD: t_mprotect.c,v 1.4 2016/05/28 14:34:49 christos Exp $"); #include #include #include #include #include #include #include #include #include #include #ifdef __NetBSD__ #include "../common/exec_prot.h" #endif static long page = 0; static int pax_global = -1; static int pax_enabled = -1; static char path[] = "mmap"; static void sighandler(int); static bool paxinit(void); static bool paxset(int, int); static void sighandler(int signo) { _exit(signo); } static bool paxinit(void) { size_t len = sizeof(int); int rv; rv = sysctlbyname("security.pax.mprotect.global", &pax_global, &len, NULL, 0); if (rv != 0) return false; rv = sysctlbyname("security.pax.mprotect.enabled", &pax_enabled, &len, NULL, 0); return rv == 0; } static bool paxset(int global, int enabled) { size_t len = sizeof(int); int rv; rv = sysctlbyname("security.pax.mprotect.global", NULL, NULL, &global, len); if (rv != 0) return false; rv = sysctlbyname("security.pax.mprotect.enabled", NULL, NULL, &enabled, len); if (rv != 0) return false; return true; } ATF_TC_WITH_CLEANUP(mprotect_access); ATF_TC_HEAD(mprotect_access, tc) { atf_tc_set_md_var(tc, "descr", "Test for EACCES from mprotect(2)"); } ATF_TC_BODY(mprotect_access, tc) { int prot[2] = { PROT_NONE, PROT_READ }; void *map; size_t i; int fd; - fd = open(path, O_RDONLY | O_CREAT); + fd = open(path, O_RDONLY | O_CREAT, 0600); ATF_REQUIRE(fd >= 0); /* * The call should fail with EACCES if we try to mark * a PROT_NONE or PROT_READ file/section as PROT_WRITE. */ for (i = 0; i < __arraycount(prot); i++) { map = mmap(NULL, page, prot[i], MAP_SHARED, fd, 0); if (map == MAP_FAILED) continue; errno = 0; ATF_REQUIRE(mprotect(map, page, PROT_WRITE) != 0); ATF_REQUIRE(errno == EACCES); ATF_REQUIRE(munmap(map, page) == 0); } ATF_REQUIRE(close(fd) == 0); } ATF_TC_CLEANUP(mprotect_access, tc) { (void)unlink(path); } ATF_TC(mprotect_err); ATF_TC_HEAD(mprotect_err, tc) { atf_tc_set_md_var(tc, "descr", "Test error conditions of mprotect(2)"); } ATF_TC_BODY(mprotect_err, tc) { errno = 0; ATF_REQUIRE(mprotect((char *)-1, 1, PROT_READ) != 0); ATF_REQUIRE(errno == EINVAL); } #ifdef __NetBSD__ ATF_TC(mprotect_exec); ATF_TC_HEAD(mprotect_exec, tc) { atf_tc_set_md_var(tc, "descr", "Test mprotect(2) executable space protections"); } /* * Trivial function -- should fit into a page */ ATF_TC_BODY(mprotect_exec, tc) { pid_t pid; void *map; int sta, xp_support; xp_support = exec_prot_support(); switch (xp_support) { case NOTIMPL: atf_tc_skip( "Execute protection callback check not implemented"); break; case NO_XP: atf_tc_skip( "Host does not support executable space protection"); break; case PARTIAL_XP: case PERPAGE_XP: default: break; } if (!paxinit()) return; if (pax_enabled == 1 && pax_global == 1) atf_tc_skip("PaX MPROTECT restrictions enabled"); /* * Map a page read/write and copy a trivial assembly function inside. * We will then change the mapping rights: * - first by setting the execution right, and check that we can * call the code found in the allocated page. * - second by removing the execution right. This should generate * a SIGSEGV on architectures that can enforce --x permissions. */ map = mmap(NULL, page, PROT_WRITE|PROT_READ, MAP_ANON, -1, 0); ATF_REQUIRE(map != MAP_FAILED); memcpy(map, (void *)return_one, (uintptr_t)return_one_end - (uintptr_t)return_one); /* give r-x rights then call code in page */ ATF_REQUIRE(mprotect(map, page, PROT_EXEC|PROT_READ) == 0); ATF_REQUIRE(((int (*)(void))map)() == 1); /* remove --x right */ ATF_REQUIRE(mprotect(map, page, PROT_READ) == 0); pid = fork(); ATF_REQUIRE(pid >= 0); if (pid == 0) { ATF_REQUIRE(signal(SIGSEGV, sighandler) != SIG_ERR); ATF_CHECK(((int (*)(void))map)() == 1); _exit(0); } (void)wait(&sta); ATF_REQUIRE(munmap(map, page) == 0); ATF_REQUIRE(WIFEXITED(sta) != 0); switch (xp_support) { case PARTIAL_XP: /* Partial protection might fail; skip the test when it does */ if (WEXITSTATUS(sta) != SIGSEGV) { atf_tc_skip("Host only supports " "partial executable space protection"); } break; case PERPAGE_XP: default: /* Per-page --x protection should not fail */ ATF_REQUIRE(WEXITSTATUS(sta) == SIGSEGV); break; } } #endif ATF_TC(mprotect_pax); ATF_TC_HEAD(mprotect_pax, tc) { atf_tc_set_md_var(tc, "descr", "PaX restrictions and mprotect(2)"); atf_tc_set_md_var(tc, "require.user", "root"); } ATF_TC_BODY(mprotect_pax, tc) { const int prot[4] = { PROT_NONE, PROT_READ, PROT_WRITE }; const char *str = NULL; void *map; size_t i; int rv; if (!paxinit() || !paxset(1, 1)) return; /* * As noted in the original PaX documentation [1], * the following restrictions should apply: * * (1) creating executable anonymous mappings * * (2) creating executable/writable file mappings * * (3) making a non-executable mapping executable * * (4) making an executable/read-only file mapping * writable except for performing relocations * on an ET_DYN ELF file (non-PIC shared library) * * The following will test only the case (3). * * [1] http://pax.grsecurity.net/docs/mprotect.txt * * (Sun Apr 3 11:06:53 EEST 2011.) */ for (i = 0; i < __arraycount(prot); i++) { map = mmap(NULL, page, prot[i], MAP_ANON, -1, 0); if (map == MAP_FAILED) continue; rv = mprotect(map, 1, prot[i] | PROT_EXEC); (void)munmap(map, page); if (rv == 0) { str = "non-executable mapping made executable"; goto out; } } out: if (pax_global != -1 && pax_enabled != -1) (void)paxset(pax_global, pax_enabled); if (str != NULL) atf_tc_fail("%s", str); } ATF_TC(mprotect_write); ATF_TC_HEAD(mprotect_write, tc) { atf_tc_set_md_var(tc, "descr", "Test mprotect(2) write protections"); } ATF_TC_BODY(mprotect_write, tc) { pid_t pid; void *map; int sta; /* * Map a page read/write, change the protection * to read-only with mprotect(2), and try to write * to the page. This should generate a SIGSEGV. */ map = mmap(NULL, page, PROT_WRITE|PROT_READ, MAP_ANON, -1, 0); ATF_REQUIRE(map != MAP_FAILED); ATF_REQUIRE(strlcpy(map, "XXX", 3) == 3); ATF_REQUIRE(mprotect(map, page, PROT_READ) == 0); pid = fork(); ATF_REQUIRE(pid >= 0); if (pid == 0) { ATF_REQUIRE(signal(SIGSEGV, sighandler) != SIG_ERR); ATF_REQUIRE(strlcpy(map, "XXX", 3) == 0); } (void)wait(&sta); ATF_REQUIRE(WIFEXITED(sta) != 0); ATF_REQUIRE(WEXITSTATUS(sta) == SIGSEGV); ATF_REQUIRE(munmap(map, page) == 0); } ATF_TP_ADD_TCS(tp) { page = sysconf(_SC_PAGESIZE); ATF_REQUIRE(page >= 0); ATF_TP_ADD_TC(tp, mprotect_access); ATF_TP_ADD_TC(tp, mprotect_err); #ifdef __NetBSD__ ATF_TP_ADD_TC(tp, mprotect_exec); #endif ATF_TP_ADD_TC(tp, mprotect_pax); ATF_TP_ADD_TC(tp, mprotect_write); return atf_no_error(); } Index: stable/12/contrib/netbsd-tests/lib/libc/sys/t_stat.c =================================================================== --- stable/12/contrib/netbsd-tests/lib/libc/sys/t_stat.c (revision 350303) +++ stable/12/contrib/netbsd-tests/lib/libc/sys/t_stat.c (revision 350304) @@ -1,419 +1,419 @@ /* $NetBSD: t_stat.c,v 1.5 2017/01/13 20:06:50 christos Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Jukka Ruohonen. * * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 __RCSID("$NetBSD: t_stat.c,v 1.5 2017/01/13 20:06:50 christos Exp $"); #include #include #include #include #include #include #include #include #include #include #include #include #include static const char *path = "stat"; ATF_TC_WITH_CLEANUP(stat_chflags); ATF_TC_HEAD(stat_chflags, tc) { atf_tc_set_md_var(tc, "descr", "Test chflags(2) with stat(2)"); } ATF_TC_BODY(stat_chflags, tc) { struct stat sa, sb; int fd; (void)memset(&sa, 0, sizeof(struct stat)); (void)memset(&sb, 0, sizeof(struct stat)); - fd = open(path, O_RDONLY | O_CREAT); + fd = open(path, O_RDONLY | O_CREAT, 0600); ATF_REQUIRE(fd != -1); ATF_REQUIRE(stat(path, &sa) == 0); ATF_REQUIRE(chflags(path, UF_NODUMP) == 0); ATF_REQUIRE(stat(path, &sb) == 0); if (sa.st_flags == sb.st_flags) atf_tc_fail("stat(2) did not detect chflags(2)"); ATF_REQUIRE(close(fd) == 0); ATF_REQUIRE(unlink(path) == 0); } ATF_TC_CLEANUP(stat_chflags, tc) { (void)unlink(path); } ATF_TC(stat_dir); ATF_TC_HEAD(stat_dir, tc) { atf_tc_set_md_var(tc, "descr", "Test stat(2) with directories"); } ATF_TC_BODY(stat_dir, tc) { const short depth = 2; struct stat sa, sb; char *argv[2]; FTSENT *ftse; FTS *fts; int ops; argv[1] = NULL; argv[0] = __UNCONST("/"); ops = FTS_NOCHDIR; ops |= FTS_PHYSICAL; fts = fts_open(argv, ops, NULL); ATF_REQUIRE(fts != NULL); while ((ftse = fts_read(fts)) != NULL) { if (ftse->fts_level < 1) continue; if (ftse->fts_level > depth) { (void)fts_set(fts, ftse, FTS_SKIP); continue; } switch(ftse->fts_info) { case FTS_DP: (void)memset(&sa, 0, sizeof(struct stat)); (void)memset(&sb, 0, sizeof(struct stat)); ATF_REQUIRE(stat(ftse->fts_parent->fts_path,&sa) == 0); ATF_REQUIRE(chdir(ftse->fts_path) == 0); ATF_REQUIRE(stat(".", &sb) == 0); /* * The previous two stat(2) calls * should be for the same directory. */ if (sa.st_dev != sb.st_dev || sa.st_ino != sb.st_ino) atf_tc_fail("inconsistent stat(2)"); /* * Check that fts(3)'s stat(2) * call equals the manual one. */ if (sb.st_ino != ftse->fts_statp->st_ino) atf_tc_fail("stat(2) and fts(3) differ"); break; default: break; } } (void)fts_close(fts); } ATF_TC(stat_err); ATF_TC_HEAD(stat_err, tc) { atf_tc_set_md_var(tc, "descr", "Test errors from the stat(2) family"); } ATF_TC_BODY(stat_err, tc) { char buf[NAME_MAX + 1]; struct stat st; (void)memset(buf, 'x', sizeof(buf)); errno = 0; ATF_REQUIRE_ERRNO(EBADF, fstat(-1, &st) == -1); errno = 0; ATF_REQUIRE_ERRNO(ENAMETOOLONG, stat(buf, &st) == -1); errno = 0; ATF_REQUIRE_ERRNO(ENAMETOOLONG, lstat(buf, &st) == -1); errno = 0; ATF_REQUIRE_ERRNO(EFAULT, stat((void *)-1, &st) == -1); errno = 0; ATF_REQUIRE_ERRNO(EFAULT, lstat((void *)-1, &st) == -1); errno = 0; ATF_REQUIRE_ERRNO(EFAULT, stat("/etc/passwd", (void *)-1) == -1); errno = 0; ATF_REQUIRE_ERRNO(EFAULT, lstat("/etc/passwd", (void *)-1) == -1); errno = 0; ATF_REQUIRE_ERRNO(ENOENT, stat("/a/b/c/d/e/f/g/h/i/j/k", &st) == -1); errno = 0; ATF_REQUIRE_ERRNO(ENOENT, lstat("/a/b/c/d/e/f/g/h/i/j/k", &st) == -1); } ATF_TC_WITH_CLEANUP(stat_mtime); ATF_TC_HEAD(stat_mtime, tc) { atf_tc_set_md_var(tc, "descr", "Test modification times with stat(2)"); } ATF_TC_BODY(stat_mtime, tc) { struct stat sa, sb; int fd[3]; size_t i; for (i = 0; i < __arraycount(fd); i++) { (void)memset(&sa, 0, sizeof(struct stat)); (void)memset(&sb, 0, sizeof(struct stat)); - fd[i] = open(path, O_WRONLY | O_CREAT); + fd[i] = open(path, O_WRONLY | O_CREAT, 0600); ATF_REQUIRE(fd[i] != -1); ATF_REQUIRE(write(fd[i], "X", 1) == 1); ATF_REQUIRE(stat(path, &sa) == 0); (void)sleep(1); ATF_REQUIRE(write(fd[i], "X", 1) == 1); ATF_REQUIRE(stat(path, &sb) == 0); ATF_REQUIRE(close(fd[i]) == 0); ATF_REQUIRE(unlink(path) == 0); if (sa.st_mtime == sb.st_mtime) atf_tc_fail("mtimes did not change"); } } ATF_TC_CLEANUP(stat_mtime, tc) { (void)unlink(path); } ATF_TC_WITH_CLEANUP(stat_perm); ATF_TC_HEAD(stat_perm, tc) { atf_tc_set_md_var(tc, "descr", "Test permissions with stat(2)"); atf_tc_set_md_var(tc, "require.user", "root"); } ATF_TC_BODY(stat_perm, tc) { struct stat sa, sb; gid_t gid; uid_t uid; int fd; (void)memset(&sa, 0, sizeof(struct stat)); (void)memset(&sb, 0, sizeof(struct stat)); uid = getuid(); gid = getgid(); - fd = open(path, O_RDONLY | O_CREAT); + fd = open(path, O_RDONLY | O_CREAT, 0600); ATF_REQUIRE(fd != -1); ATF_REQUIRE(fstat(fd, &sa) == 0); ATF_REQUIRE(stat(path, &sb) == 0); if (gid != sa.st_gid || sa.st_gid != sb.st_gid) atf_tc_fail("invalid GID"); if (uid != sa.st_uid || sa.st_uid != sb.st_uid) atf_tc_fail("invalid UID"); ATF_REQUIRE(close(fd) == 0); ATF_REQUIRE(unlink(path) == 0); } ATF_TC_CLEANUP(stat_perm, tc) { (void)unlink(path); } ATF_TC_WITH_CLEANUP(stat_size); ATF_TC_HEAD(stat_size, tc) { atf_tc_set_md_var(tc, "descr", "Test file sizes with stat(2)"); } ATF_TC_BODY(stat_size, tc) { struct stat sa, sb, sc; const size_t n = 10; size_t i; int fd; - fd = open(path, O_WRONLY | O_CREAT); + fd = open(path, O_WRONLY | O_CREAT, 0600); ATF_REQUIRE(fd >= 0); for (i = 0; i < n; i++) { (void)memset(&sa, 0, sizeof(struct stat)); (void)memset(&sb, 0, sizeof(struct stat)); (void)memset(&sc, 0, sizeof(struct stat)); ATF_REQUIRE(fstat(fd, &sa) == 0); ATF_REQUIRE(write(fd, "X", 1) == 1); ATF_REQUIRE(fstat(fd, &sb) == 0); ATF_REQUIRE(stat(path, &sc) == 0); if (sa.st_size + 1 != sb.st_size) atf_tc_fail("invalid file size"); if (sb.st_size != sc.st_size) atf_tc_fail("stat(2) and fstat(2) mismatch"); } ATF_REQUIRE(close(fd) == 0); ATF_REQUIRE(unlink(path) == 0); } ATF_TC_CLEANUP(stat_size, tc) { (void)unlink(path); } ATF_TC(stat_socket); ATF_TC_HEAD(stat_socket, tc) { atf_tc_set_md_var(tc, "descr", "Test fstat(2) with " "a socket (PR kern/46077)"); } ATF_TC_BODY(stat_socket, tc) { struct sockaddr_in addr; struct stat st; uint32_t iaddr; int fd, flags; (void)memset(&st, 0, sizeof(struct stat)); (void)memset(&addr, 0, sizeof(struct sockaddr_in)); fd = socket(AF_INET, SOCK_STREAM, 0); ATF_REQUIRE(fd >= 0); flags = fcntl(fd, F_GETFL); ATF_REQUIRE(flags != -1); ATF_REQUIRE(fcntl(fd, F_SETFL, flags | O_NONBLOCK) != -1); ATF_REQUIRE(inet_pton(AF_INET, "127.0.0.1", &iaddr) == 1); addr.sin_port = htons(42); addr.sin_family = AF_INET; addr.sin_addr.s_addr = iaddr; errno = 0; ATF_REQUIRE_ERRNO(EINPROGRESS, connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) == -1); errno = 0; if (fstat(fd, &st) != 0 || errno != 0) atf_tc_fail("fstat(2) failed for a EINPROGRESS socket"); (void)close(fd); } ATF_TC_WITH_CLEANUP(stat_symlink); ATF_TC_HEAD(stat_symlink, tc) { atf_tc_set_md_var(tc, "descr", "Test symbolic links with stat(2)"); } ATF_TC_BODY(stat_symlink, tc) { const char *pathlink = "pathlink"; struct stat sa, sb; int fd; (void)memset(&sa, 0, sizeof(struct stat)); (void)memset(&sb, 0, sizeof(struct stat)); - fd = open(path, O_WRONLY | O_CREAT); + fd = open(path, O_WRONLY | O_CREAT, 0600); ATF_REQUIRE(fd >= 0); ATF_REQUIRE(symlink(path, pathlink) == 0); ATF_REQUIRE(stat(pathlink, &sa) == 0); ATF_REQUIRE(lstat(pathlink, &sb) == 0); if (S_ISLNK(sa.st_mode) != 0) atf_tc_fail("stat(2) detected symbolic link"); if (S_ISLNK(sb.st_mode) == 0) atf_tc_fail("lstat(2) did not detect symbolic link"); if (sa.st_mode == sb.st_mode) atf_tc_fail("inconsistencies between stat(2) and lstat(2)"); (void)close(fd); ATF_REQUIRE(unlink(path) == 0); ATF_REQUIRE(unlink(pathlink) == 0); } ATF_TC_CLEANUP(stat_symlink, tc) { (void)unlink(path); } ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, stat_chflags); ATF_TP_ADD_TC(tp, stat_dir); ATF_TP_ADD_TC(tp, stat_err); ATF_TP_ADD_TC(tp, stat_mtime); ATF_TP_ADD_TC(tp, stat_perm); ATF_TP_ADD_TC(tp, stat_size); ATF_TP_ADD_TC(tp, stat_socket); ATF_TP_ADD_TC(tp, stat_symlink); return atf_no_error(); } Index: stable/12/contrib/netbsd-tests/lib/libc/sys/t_write.c =================================================================== --- stable/12/contrib/netbsd-tests/lib/libc/sys/t_write.c (revision 350303) +++ stable/12/contrib/netbsd-tests/lib/libc/sys/t_write.c (revision 350304) @@ -1,226 +1,226 @@ /* $NetBSD: t_write.c,v 1.3 2017/01/13 19:27:23 christos Exp $ */ /*- * Copyright (c) 2001, 2008 The NetBSD Foundation, Inc. * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 __COPYRIGHT("@(#) Copyright (c) 2008\ The NetBSD Foundation, inc. All rights reserved."); __RCSID("$NetBSD: t_write.c,v 1.3 2017/01/13 19:27:23 christos Exp $"); #include #include #include #include #include #include #include #include #include #include static void sighandler(int); static bool fail = false; static const char *path = "write"; static void sighandler(int signo __unused) { fail = false; } ATF_TC_WITH_CLEANUP(write_err); ATF_TC_HEAD(write_err, tc) { atf_tc_set_md_var(tc, "descr", "Checks errors from write(2)"); } ATF_TC_BODY(write_err, tc) { char rbuf[3] = { 'a', 'b', 'c' }; char wbuf[3] = { 'x', 'y', 'z' }; int fd; errno = 0; ATF_REQUIRE_ERRNO(EBADF, write(-1, wbuf, sizeof(wbuf)) == -1); - fd = open(path, O_RDWR | O_CREAT); + fd = open(path, O_RDWR | O_CREAT, 0600); if (fd >= 0) { errno = 0; ATF_REQUIRE_ERRNO(0, write(fd, wbuf, 3) == 3); errno = 0; ATF_REQUIRE_ERRNO(EINVAL, write(fd, wbuf, SIZE_MAX) == -1); errno = 0; ATF_REQUIRE_ERRNO(EFAULT, write(fd, (void *)-1, 1) == -1); /* * Check that the above bogus write(2) * calls did not corrupt the file. */ ATF_REQUIRE(lseek(fd, 0, SEEK_SET) == 0); ATF_REQUIRE(read(fd, rbuf, 3) == 3); ATF_REQUIRE(memcmp(rbuf, wbuf, 3) == 0); (void)close(fd); (void)unlink(path); } } ATF_TC_CLEANUP(write_err, tc) { (void)unlink(path); } ATF_TC(write_pipe); ATF_TC_HEAD(write_pipe, tc) { atf_tc_set_md_var(tc, "descr", "Checks for EPIPE from write(2)"); } ATF_TC_BODY(write_pipe, tc) { int fds[2]; ATF_REQUIRE(pipe(fds) == 0); ATF_REQUIRE(signal(SIGPIPE, sighandler) == 0); ATF_REQUIRE(write(fds[1], "x", 1) != -1); ATF_REQUIRE(close(fds[0]) == 0); errno = 0; fail = true; if (write(fds[1], "x", 1) != -1 || errno != EPIPE) atf_tc_fail_nonfatal("expected EPIPE but write(2) succeeded"); ATF_REQUIRE(close(fds[1]) == 0); if (fail != false) atf_tc_fail_nonfatal("SIGPIPE was not raised"); } ATF_TC_WITH_CLEANUP(write_pos); ATF_TC_HEAD(write_pos, tc) { atf_tc_set_md_var(tc, "descr", "Checks that write(2) " "updates the file position"); } ATF_TC_BODY(write_pos, tc) { const size_t n = 123; size_t i; int fd; - fd = open(path, O_RDWR | O_CREAT); + fd = open(path, O_RDWR | O_CREAT, 0600); ATF_REQUIRE(fd >= 0); for (i = 0; i < n; i++) { ATF_REQUIRE(write(fd, "x", 1) == 1); ATF_REQUIRE(lseek(fd, 0, SEEK_CUR) == (off_t)(i + 1)); } ATF_REQUIRE(close(fd) == 0); ATF_REQUIRE(unlink(path) == 0); } ATF_TC_CLEANUP(write_pos, tc) { (void)unlink(path); } ATF_TC_WITH_CLEANUP(write_ret); ATF_TC_HEAD(write_ret, tc) { atf_tc_set_md_var(tc, "descr", "Checks return values from write(2)"); } ATF_TC_BODY(write_ret, tc) { const size_t n = 99; char buf[123]; size_t i, j; int fd; - fd = open(path, O_WRONLY | O_CREAT); + fd = open(path, O_WRONLY | O_CREAT, 0600); ATF_REQUIRE(fd >= 0); (void)memset(buf, 'x', sizeof(buf)); for (i = j = 0; i < n; i++) j += write(fd, buf, sizeof(buf)); if (j != n * 123) atf_tc_fail("inconsistent return values from write(2)"); (void)close(fd); (void)unlink(path); } ATF_TC_CLEANUP(write_ret, tc) { (void)unlink(path); } ATF_TC(writev_iovmax); ATF_TC_HEAD(writev_iovmax, tc) { atf_tc_set_md_var(tc, "timeout", "10"); atf_tc_set_md_var(tc, "descr", "Checks that file descriptor is properly FILE_UNUSE()d " "when iovcnt is greater than IOV_MAX"); } ATF_TC_BODY(writev_iovmax, tc) { ssize_t retval; (void)printf("Calling writev(2, NULL, IOV_MAX + 1)...\n"); errno = 0; retval = writev(2, NULL, IOV_MAX + 1); ATF_REQUIRE_EQ_MSG(retval, -1, "got: %zd", retval); ATF_REQUIRE_EQ_MSG(errno, EINVAL, "got: %s", strerror(errno)); } ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, write_err); ATF_TP_ADD_TC(tp, write_pipe); ATF_TP_ADD_TC(tp, write_pos); ATF_TP_ADD_TC(tp, write_ret); ATF_TP_ADD_TC(tp, writev_iovmax); return atf_no_error(); } Index: stable/12 =================================================================== --- stable/12 (revision 350303) +++ stable/12 (revision 350304) Property changes on: stable/12 ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head:r350067