summaryrefslogtreecommitdiff
path: root/src/regress/lib/libc/sys
diff options
context:
space:
mode:
authorbluhm <>2019-11-19 19:57:04 +0000
committerbluhm <>2019-11-19 19:57:04 +0000
commit9185f840eda265016178aeb0dcdba964f8f6f3e2 (patch)
treeda100b3712514c566fe948116f7926ad7f725401 /src/regress/lib/libc/sys
parent6a6fe688152b422f3d65c970dad56e7d9d28b1ee (diff)
downloadopenbsd-9185f840eda265016178aeb0dcdba964f8f6f3e2.tar.gz
openbsd-9185f840eda265016178aeb0dcdba964f8f6f3e2.tar.bz2
openbsd-9185f840eda265016178aeb0dcdba964f8f6f3e2.zip
Import NetBSD system call regression tests. They were written with
ATF (Automated Testing Framework), so we use a small wrapper to map it to our bsd.regress.mk framework. Only half of the 80 NetBSD tests have been taken, the others need more work to adapt. Of them 34 syscall tests pass. Moritz Buhl ported the tests to OpenBSD.
Diffstat (limited to 'src/regress/lib/libc/sys')
-rw-r--r--src/regress/lib/libc/sys/Makefile104
-rw-r--r--src/regress/lib/libc/sys/README68
-rw-r--r--src/regress/lib/libc/sys/atf-c.c113
-rw-r--r--src/regress/lib/libc/sys/atf-c.h100
-rw-r--r--src/regress/lib/libc/sys/h_macros.h87
-rw-r--r--src/regress/lib/libc/sys/macros.h55
-rw-r--r--src/regress/lib/libc/sys/t_access.c216
-rw-r--r--src/regress/lib/libc/sys/t_bind.c81
-rw-r--r--src/regress/lib/libc/sys/t_chroot.c321
-rw-r--r--src/regress/lib/libc/sys/t_clock_gettime.c215
-rw-r--r--src/regress/lib/libc/sys/t_dup.c395
-rw-r--r--src/regress/lib/libc/sys/t_fsync.c125
-rw-r--r--src/regress/lib/libc/sys/t_getgroups.c175
-rw-r--r--src/regress/lib/libc/sys/t_getitimer.c215
-rw-r--r--src/regress/lib/libc/sys/t_getlogin.c241
-rw-r--r--src/regress/lib/libc/sys/t_getpid.c138
-rw-r--r--src/regress/lib/libc/sys/t_getrusage.c269
-rw-r--r--src/regress/lib/libc/sys/t_getsid.c123
-rw-r--r--src/regress/lib/libc/sys/t_getsockname.c85
-rw-r--r--src/regress/lib/libc/sys/t_gettimeofday.c90
-rw-r--r--src/regress/lib/libc/sys/t_kill.c316
-rw-r--r--src/regress/lib/libc/sys/t_link.c234
-rw-r--r--src/regress/lib/libc/sys/t_listen.c139
-rw-r--r--src/regress/lib/libc/sys/t_mkdir.c213
-rw-r--r--src/regress/lib/libc/sys/t_mkfifo.c309
-rw-r--r--src/regress/lib/libc/sys/t_mknod.c199
-rw-r--r--src/regress/lib/libc/sys/t_mlock.c325
-rw-r--r--src/regress/lib/libc/sys/t_mmap.c584
-rw-r--r--src/regress/lib/libc/sys/t_msgctl.c405
-rw-r--r--src/regress/lib/libc/sys/t_msgget.c339
-rw-r--r--src/regress/lib/libc/sys/t_msgrcv.c388
-rw-r--r--src/regress/lib/libc/sys/t_msgsnd.c384
-rw-r--r--src/regress/lib/libc/sys/t_msync.c228
-rw-r--r--src/regress/lib/libc/sys/t_pipe.c168
-rw-r--r--src/regress/lib/libc/sys/t_pipe2.c203
-rw-r--r--src/regress/lib/libc/sys/t_poll.c398
-rw-r--r--src/regress/lib/libc/sys/t_ptrace.c231
-rw-r--r--src/regress/lib/libc/sys/t_revoke.c198
-rw-r--r--src/regress/lib/libc/sys/t_select.c219
-rw-r--r--src/regress/lib/libc/sys/t_sendrecv.c186
-rw-r--r--src/regress/lib/libc/sys/t_setuid.c126
-rw-r--r--src/regress/lib/libc/sys/t_sigaction.c156
-rw-r--r--src/regress/lib/libc/sys/t_socketpair.c141
-rw-r--r--src/regress/lib/libc/sys/t_stat.c423
-rw-r--r--src/regress/lib/libc/sys/t_syscall.c122
-rw-r--r--src/regress/lib/libc/sys/t_truncate.c183
-rw-r--r--src/regress/lib/libc/sys/t_umask.c210
-rw-r--r--src/regress/lib/libc/sys/t_unlink.c162
-rw-r--r--src/regress/lib/libc/sys/t_write.c287
49 files changed, 10692 insertions, 0 deletions
diff --git a/src/regress/lib/libc/sys/Makefile b/src/regress/lib/libc/sys/Makefile
new file mode 100644
index 0000000000..e8c06d0fb2
--- /dev/null
+++ b/src/regress/lib/libc/sys/Makefile
@@ -0,0 +1,104 @@
1# $OpenBSD: Makefile,v 1.1.1.1 2019/11/19 19:57:03 bluhm Exp $
2
3# Copyright (c) 2019 Moritz Buhl <openbsd@moritzbuhl.de>
4# Copyright (c) 2019 Alexander Bluhm <bluhm@openbsd.org>
5#
6# Permission to use, copy, modify, and distribute this software for any
7# purpose with or without fee is hereby granted, provided that the above
8# copyright notice and this permission notice appear in all copies.
9#
10# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18# Each test program in PROGS may define several numbered subtests.
19# In a first step compile all programs and extract their parameters.
20# For each PROG define new regression subtests based on the test number.
21
22.if defined(NUMBERS)
23REGRESS_TARGETS = ${NUMBERS:S/^/run-${PROG}-/}
24.else
25REGRESS_TARGETS = ${PROGS:S/^/run-/}
26.endif
27
28PROGS =
29PROGS += t_access t_bind t_chroot t_clock_gettime t_dup t_fsync
30PROGS += t_getgroups t_getitimer t_getlogin t_getpid t_getrusage
31PROGS += t_getsid t_getsockname t_gettimeofday t_kill t_link t_listen
32PROGS += t_mkdir t_mknod t_msgctl t_msgget t_msgsnd t_msync t_pipe
33PROGS += t_poll t_revoke t_select t_sendrecv t_setuid t_socketpair
34PROGS += t_sigaction t_truncate t_umask t_write
35
36# failing tests
37.if 0
38PROGS += t_mkfifo
39PROGS += t_mlock
40PROGS += t_mmap
41PROGS += t_msgrcv
42PROGS += t_pipe2
43PROGS += t_ptrace
44PROGS += t_stat
45PROGS += t_syscall
46PROGS += t_unlink
47.endif
48
49. for p in ${PROGS}
50SRCS_$p = $p.c atf-c.c
51. endfor
52
53LDADD_t_getpid = -lpthread
54
55run-t_truncate: setup-t_truncate
56setup-t_truncate:
57 ${SUDO} touch truncate_test.root_owned
58 ${SUDO} chown root:wheel truncate_test.root_owned
59
60run-t_chroot: cleanup-t_chroot
61cleanup-t_chroot:
62 ${SUDO} rm -rf dir
63
64CLEANFILES = access dummy mmap truncate_test.root_owned
65
66.for p in ${PROGS}
67run-$p: $p
68 @echo "\n======== $@ ========"
69 ntests="`./$p -n`" && \
70 echo "1..$$ntests" && \
71 tnumbers="`jot -ns' ' - 1 $$ntests`" && \
72 ${.MAKE} -C ${.CURDIR} PROG=$p NUMBERS="$$tnumbers" regress
73.endfor
74
75.if defined(NUMBERS)
76CUR_USER != id -g
77
78. for n in ${NUMBERS}
79DESCR_$n != eval `./${PROG} -i $n` && echo $$DESCR
80REQ_USER_$n != eval `./${PROG} -i $n` && echo $$REQ_USER
81
82. if ${REQ_USER_$n} == "root"
83REGRESS_ROOT_TARGETS += run-${PROG}-$n
84. endif
85
86run-${PROG}-$n:
87 @echo "$n ${DESCR_$n}"
88. if ${REQ_USER_$n} == "root"
89 ${SUDO} ./${PROG} -r $n
90. elif ${REQ_USER_$n} == "unprivileged" && ${CUR_USER} == 0
91 ${SUDO} su ${BUILDUSER} -c exec ./${PROG} -r $n
92. elif ${REQ_USER_$n} == "unprivileged" || ${REQ_USER_$n} == ""
93 ./${PROG} -r $n
94. else
95 # bad REQ_USER: ${REQ_USER_$n}
96 false
97. endif
98
99. endfor
100.endif
101
102.include <bsd.regress.mk>
103
104clean: cleanup-t_chroot
diff --git a/src/regress/lib/libc/sys/README b/src/regress/lib/libc/sys/README
new file mode 100644
index 0000000000..979f3bde4a
--- /dev/null
+++ b/src/regress/lib/libc/sys/README
@@ -0,0 +1,68 @@
1Regression tests for system calls ported from NetBSD.
2
3Reimplement ATF with many hacks to adjust the tests as little as possible.
4
5Tests passing without source file adjustments:
6t_access t_getpid t_kill t_msgsnd t_sigaction
7t_bind t_link t_msync t_socketpair t_getgroups
8t_getsid t_listen t_pipe t_truncate t_getitimer
9t_getsockname t_mkdir t_sendrecv t_umask t_getlogin
10t_gettimeofday t_msgctl t_setuid t_write
11
12Tests passing after adjustments:
13t_chroot - fchroot is not implemented
14t_clock_gettime - requires sysctlbyname
15t_dup - OpenBSD dup3 is similar to Linux dup3
16t_fsync - replace mkstemp
17t_getrusage - no expected fail, PR kern/30115 is NetBSD, work more
18t_mknod - remove tests for unsupported file types
19t_msgget - remove msgget_limit test
20t_poll - remove pollts_* tests
21t_revoke - remove basic tests, revoke only on ttys supported
22t_select - remove sigset_t struct as it is int on OpenBSD
23
24Failing tests:
25t_mkfifo - every test case fails now
26t_mlock - wrong errno, succeeds where not expected, POSIX imprecise
27t_mmap - ENOTBLK on test NetBSD is skipping, remove mmap_va0 test
28t_msgrcv - msgrcv(id, &r, 3 - 1, 0x41, 004000) != -1
29t_pipe2 - closefrom(4) == -1, remove F_GETNOSIGPIPE and nosigpipe test
30t_ptrace - ptrace(0, 0, ((void *)0), 0) != -1
31t_stat - invalid GID with doas
32t_syscall - SIGSEGV
33t_unlink - wrong errno according to POSIX
34
35Excluded tests:
36t_clock_nanosleep - not available
37t_clone - not available
38t_connect -
39t_fork -
40t_getcontext -
41t_issetugid -
42t_kevent -
43t_lwp_create - not available
44t_lwp_ctl - not available
45t_mincore - removed
46t_minherit -
47t_mprotect -
48t_nanosleep - not available
49t_posix_fadvise -
50t_posix_fallocate -
51t_ptrace_wait -
52t_ptrace_wait3 -
53t_ptrace_wait4 -
54t_ptrace_wait6 - not implemented
55t_ptrace_waitid -
56t_ptrace_waitpid -
57t_recvmmsg -
58t_sendmmsg -
59t_setrlimit -
60t_sigqueue -
61t_sigtimedwait -
62t_swapcontext -
63t_timer_create -
64t_ucontext -
65t_vfork -
66t_wait -
67t_wait_noproc -
68t_wait_noproc_wnohang -
diff --git a/src/regress/lib/libc/sys/atf-c.c b/src/regress/lib/libc/sys/atf-c.c
new file mode 100644
index 0000000000..45181c7353
--- /dev/null
+++ b/src/regress/lib/libc/sys/atf-c.c
@@ -0,0 +1,113 @@
1/* $OpenBSD: atf-c.c,v 1.1.1.1 2019/11/19 19:57:03 bluhm Exp $ */
2
3#include <sys/wait.h>
4
5#include <err.h>
6#include <errno.h>
7#include <limits.h>
8#include <stdarg.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <pwd.h>
12#include <unistd.h>
13
14#include "atf-c.h"
15
16void usage(void);
17
18int cleanup;
19int count;
20int inspect;
21int run;
22int test;
23
24int
25main(int argc, char *argv[])
26{
27 int ch, test;
28 const char *errstr, *num;
29
30 while ((ch = getopt(argc, argv, "c:i:nr:")) != -1) {
31 switch(ch) {
32 case 'c':
33 cleanup = 1;
34 num = optarg;
35 break;
36 case 'i':
37 inspect = 1;
38 num = optarg;
39 break;
40 case 'n':
41 count = 1;
42 break;
43 case 'r':
44 run = 1;
45 num = optarg;
46 break;
47 default:
48 usage();
49 }
50 }
51 argc -= optind;
52 argv += optind;
53
54 if (cleanup + count + inspect + run > 1)
55 usage();
56
57 if (cleanup || inspect || run) {
58 test = strtonum(num, 1, INT_MAX, &errstr);
59 if (errstr != NULL)
60 errx(1, "test # is %s: %s", errstr, argv[1]);
61 }
62 if (count)
63 printf("%d\n", atf_test(0, 0));
64 else if (cleanup)
65 ATF_CLEANUP(test);
66 else if (run)
67 ATF_RUN(test);
68 else if (inspect)
69 ATF_INSPECT(test);
70 else
71 usage();
72
73 return 0;
74}
75
76void
77usage(void)
78{
79 fprintf(stderr, "usage: %s [-n] [-c|i|r test#]\n", getprogname());
80 exit(1);
81}
82
83void
84atf_require(int exp, int expected_errno, const char *expstr, const char *src,
85 const int lineno, char *fmt, ...)
86{
87 va_list args;
88 if (!(exp)) {
89 fprintf(stderr, "\n%s:%d: ", src, lineno);
90 if (fmt != NULL) {
91 va_start(args, fmt);
92 vfprintf(stderr, fmt, args);
93 va_end(args);
94 } else {
95 fprintf(stderr, "'%s' evaluated to false\n", expstr);
96 }
97 exit(1);
98 } else if (expected_errno >= 0 && errno != expected_errno) {
99 fprintf(stderr, "\n%s:%d: ", src, lineno);
100 fprintf(stderr, "expected errno %d but got %d instead\n",
101 expected_errno, errno);
102 exit(1);
103 }
104 return;
105}
106
107void
108atf_tc_fail(char *fmt, ...)
109{
110 va_list args;
111 va_start(args, fmt);
112 verrx(1, fmt, args);
113}
diff --git a/src/regress/lib/libc/sys/atf-c.h b/src/regress/lib/libc/sys/atf-c.h
new file mode 100644
index 0000000000..740881485d
--- /dev/null
+++ b/src/regress/lib/libc/sys/atf-c.h
@@ -0,0 +1,100 @@
1/* $OpenBSD: atf-c.h,v 1.1.1.1 2019/11/19 19:57:03 bluhm Exp $ */
2/*
3 * Copyright (c) 2019 Moritz Buhl <openbsd@moritzbuhl.de>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#if !defined(ATF_C_H)
19#define ATF_C_H
20
21#include <pwd.h>
22#include <stdio.h>
23#include <string.h>
24#include <unistd.h>
25
26
27int atf_test(int, int);
28void atf_require(int, int, const char *, const char *, const int, char *, ...);
29void atf_tc_fail(char *, ...)
30 __attribute__((__noreturn__, __format__ (printf, 1, 2)));
31
32#define ATF_INSPECT_TEST 1
33#define ATF_RUN_TEST 2
34#define ATF_CLEANUP_TEST 3
35
36#define ATF_TC_FUNCTIONS(fn) \
37void atf_head_##fn(void); \
38void atf_body_##fn(void); \
39void atf_cleanup_##fn(void);
40
41#define ATF_TC(fn) \
42ATF_TC_FUNCTIONS(fn) \
43void atf_cleanup_##fn(void) { return; }
44
45#define ATF_TC_WITH_CLEANUP(fn) \
46ATF_TC_FUNCTIONS(fn)
47
48#define ATF_TC_HEAD(fn, tc) void atf_head_##fn(void)
49#define ATF_TC_BODY(fn, tc) void atf_body_##fn(void)
50#define ATF_TC_CLEANUP(fn, tc) void atf_cleanup_##fn(void)
51
52#define ATF_TP_ADD_TCS(tp) int atf_test(int tst, int what)
53#define ATF_TP_ADD_TC(tp, fn) tst--; \
54 if (tst == 0) { \
55 if (what == ATF_INSPECT_TEST) \
56 atf_head_##fn(); \
57 else if (what == ATF_RUN_TEST) \
58 atf_body_##fn(); \
59 else if (what == ATF_CLEANUP_TEST) \
60 atf_cleanup_##fn(); \
61 return 0; \
62 }
63
64#define atf_no_error() (-tst)
65
66#define ATF_INSPECT(i) atf_test(i, ATF_INSPECT_TEST)
67#define ATF_RUN(i) atf_test(i, ATF_RUN_TEST)
68#define ATF_CLEANUP(i) atf_test(i, ATF_CLEANUP_TEST)
69
70#define atf_tc_set_md_var(tc, attr, fmt, ...) \
71 if (strcmp(attr, "descr") == 0) \
72 printf("DESCR=\"" fmt "\"\n", ##__VA_ARGS__); \
73 else if (strcmp(attr, "require.user") == 0) \
74 printf("REQ_USER=" fmt "\n", ##__VA_ARGS__);
75
76#define ATF_CHECK ATF_REQUIRE
77#define ATF_CHECK_MSG ATF_REQUIRE_MSG
78#define ATF_CHECK_EQ ATF_REQUIRE_EQ
79
80#define atf_req(exp, err, msg, ...) \
81 atf_require(exp, err, #exp, __FILE__, __LINE__, NULL)
82#define ATF_REQUIRE(exp) atf_req(exp, -1, NULL)
83#define ATF_REQUIRE_ERRNO(no, exp) atf_req(exp, no, NULL)
84#define ATF_REQUIRE_MSG(exp, fmt, ...) atf_req(exp, -1, fmt, ##__VA_ARGS__)
85#define ATF_REQUIRE_EQ(a, b) atf_req((a) == (b), -1, NULL)
86#define ATF_REQUIRE_EQ_MSG(a, b, fmt, ...) \
87 atf_req((a) == (b), -1, fmt, ##__VA_ARGS__)
88
89#define atf_tc_fail_nonfatal(fmt, ...) atf_tc_fail(fmt, ##__VA_ARGS__)
90#define atf_tc_expect_fail(fmt, ...) \
91 atf_tc_fail(fmt "\nEXPECTED_FAIL", ##__VA_ARGS__)
92#define atf_tc_skip(fmt, ...) \
93 atf_tc_fail(fmt "\nSKIPPING", ##__VA_ARGS__)
94#define atf_tc_pass() exit(0)
95
96#define atf_tc_get_config_var(a, b) "."
97
98#define atf_utils_fork() fork()
99
100#endif /* !defined(ATF_C_H) */
diff --git a/src/regress/lib/libc/sys/h_macros.h b/src/regress/lib/libc/sys/h_macros.h
new file mode 100644
index 0000000000..227db0f31b
--- /dev/null
+++ b/src/regress/lib/libc/sys/h_macros.h
@@ -0,0 +1,87 @@
1/* $NetBSD: h_macros.h,v 1.13 2016/08/20 15:49:08 christos Exp $ */
2
3/*-
4 * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef SRC_TESTS_H_MACROS_H_
30#define SRC_TESTS_H_MACROS_H_
31
32#include <sys/types.h>
33#include <errno.h>
34#include <stdarg.h>
35#include <stdio.h>
36#include <stdlib.h>
37#include <string.h>
38
39#include "atf-c.h"
40
41#define REQUIRE_LIBC(x, v) \
42 ATF_REQUIRE_MSG((x) != (v), "%s: %s", #x, strerror(errno))
43
44#define CHECK_LIBC(x, v) \
45 ATF_CHECK_MSG((x) != (v), "%s: %s", #x, strerror(errno))
46
47#define RL(x) REQUIRE_LIBC(x, -1)
48#define RLF(x, fmt, arg) \
49 ATF_CHECK_MSG((x) != -1, "%s [" fmt "]: %s", #x, arg, strerror(errno))
50#define RZ(x) \
51do { \
52 int RZ_rv = x; \
53 ATF_REQUIRE_MSG(RZ_rv == 0, "%s: %s", #x, strerror(RZ_rv)); \
54} while (/*CONSTCOND*/0)
55
56__dead static __inline __attribute__((__format__(__printf__,1,2))) void
57atf_tc_fail_errno(const char *fmt, ...)
58{
59 va_list ap;
60 char buf[1024];
61 int sverrno = errno;
62
63 va_start(ap, fmt);
64 vsnprintf(buf, sizeof(buf), fmt, ap);
65 va_end(ap);
66
67 strlcat(buf, ": ", sizeof(buf));
68 strlcat(buf, strerror(sverrno), sizeof(buf));
69
70 atf_tc_fail("%s", buf);
71}
72
73static __inline void
74tests_makegarbage(void *space, size_t len)
75{
76 uint16_t *sb = space;
77 uint16_t randval;
78
79 while (len >= sizeof(randval)) {
80 *sb++ = (uint16_t)random();
81 len -= sizeof(*sb);
82 }
83 randval = (uint16_t)random();
84 memcpy(sb, &randval, len);
85}
86
87#endif
diff --git a/src/regress/lib/libc/sys/macros.h b/src/regress/lib/libc/sys/macros.h
new file mode 100644
index 0000000000..932f230c03
--- /dev/null
+++ b/src/regress/lib/libc/sys/macros.h
@@ -0,0 +1,55 @@
1/* $OpenBSD: macros.h,v 1.1.1.1 2019/11/19 19:57:03 bluhm Exp $ */
2/* Public domain - Moritz Buhl */
3
4#include <sys/param.h>
5#include <sys/socket.h>
6#include <sys/stdint.h>
7#include <sys/sysctl.h>
8#include <sys/types.h>
9
10#include <stdbool.h>
11#include <string.h>
12
13#define __RCSID(str)
14#define __COPYRIGHT(str)
15
16#define __arraycount(_a) nitems(_a)
17#define __unreachable() atf_tc_fail("unreachable")
18#define __UNCONST(a) (a)
19
20/* t_chroot.c */
21#define fchroot(fd) 0
22
23/* t_clock_gettime.c */
24int sysctlbyname(char *, void *, size_t *, void *, size_t);
25
26int
27sysctlbyname(char* s, void *oldp, size_t *oldlenp, void *newp, size_t newlen)
28{
29 int ktc;
30 if (strcmp(s, "kern.timecounter.hardware") == 0)
31 ktc = KERN_TIMECOUNTER_HARDWARE;
32 else if (strcmp(s, "kern.timecounter.choice") == 0)
33 ktc = KERN_TIMECOUNTER_CHOICE;
34
35 int mib[3];
36 mib[0] = CTL_KERN;
37 mib[1] = KERN_TIMECOUNTER;
38 mib[2] = ktc;
39 return sysctl(mib, 3, oldp, oldlenp, newp, newlen);
40}
41
42/* t_mlock.c */
43#define MAP_WIRED __MAP_NOREPLACE
44
45/* t_pipe2.c */
46#define O_NOSIGPIPE 0
47
48/* t_poll.c */
49#define pollts(a, b, c, e) 0
50
51/* t_sendrecv.c */
52#define SO_RERROR SO_DEBUG
53
54/* t_write.c */
55#define _PATH_DEVZERO "/dev/zero"
diff --git a/src/regress/lib/libc/sys/t_access.c b/src/regress/lib/libc/sys/t_access.c
new file mode 100644
index 0000000000..33888c7039
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_access.c
@@ -0,0 +1,216 @@
1/* $OpenBSD: t_access.c,v 1.1.1.1 2019/11/19 19:57:03 bluhm Exp $ */
2/* $NetBSD: t_access.c,v 1.2 2017/01/10 22:36:29 christos Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_access.c,v 1.2 2017/01/10 22:36:29 christos Exp $");
37
38#include "atf-c.h"
39
40#include <sys/stat.h>
41
42#include <errno.h>
43#include <fcntl.h>
44#include <limits.h>
45#include <stdint.h>
46#include <stdlib.h>
47#include <unistd.h>
48
49static const char path[] = "access";
50static const int mode[4] = { R_OK, W_OK, X_OK, F_OK };
51
52ATF_TC_WITH_CLEANUP(access_access);
53ATF_TC_HEAD(access_access, tc)
54{
55 atf_tc_set_md_var(tc, "descr", "Test access(2) for EACCES");
56 atf_tc_set_md_var(tc, "require.user", "unprivileged");
57}
58
59ATF_TC_BODY(access_access, tc)
60{
61 const int perm[3] = { 0200, 0400, 0000 };
62 size_t i;
63 int fd;
64
65 fd = open(path, O_RDONLY | O_CREAT);
66
67 if (fd < 0)
68 return;
69
70 for (i = 0; i < __arraycount(mode) - 1; i++) {
71
72 ATF_REQUIRE(fchmod(fd, perm[i]) == 0);
73
74 errno = 0;
75
76 ATF_REQUIRE(access(path, mode[i]) != 0);
77 ATF_REQUIRE(errno == EACCES);
78 }
79
80 ATF_REQUIRE(close(fd) == 0);
81}
82
83ATF_TC_CLEANUP(access_access, tc)
84{
85 (void)unlink(path);
86}
87
88ATF_TC(access_fault);
89ATF_TC_HEAD(access_fault, tc)
90{
91 atf_tc_set_md_var(tc, "descr", "Test access(2) for EFAULT");
92}
93
94ATF_TC_BODY(access_fault, tc)
95{
96 size_t i;
97
98 for (i = 0; i < __arraycount(mode); i++) {
99
100 errno = 0;
101
102 ATF_REQUIRE(access(NULL, mode[i]) != 0);
103 ATF_REQUIRE(errno == EFAULT);
104
105 errno = 0;
106
107 ATF_REQUIRE(access((char *)-1, mode[i]) != 0);
108 ATF_REQUIRE(errno == EFAULT);
109 }
110}
111
112ATF_TC(access_inval);
113ATF_TC_HEAD(access_inval, tc)
114{
115 atf_tc_set_md_var(tc, "descr", "Test access(2) for EINVAL");
116}
117
118ATF_TC_BODY(access_inval, tc)
119{
120
121 errno = 0;
122
123 ATF_REQUIRE(access("/usr", -1) != 0);
124 ATF_REQUIRE(errno == EINVAL);
125}
126
127ATF_TC(access_notdir);
128ATF_TC_HEAD(access_notdir, tc)
129{
130 atf_tc_set_md_var(tc, "descr", "Test access(2) for ENOTDIR");
131}
132
133ATF_TC_BODY(access_notdir, tc)
134{
135 size_t i;
136
137 for (i = 0; i < __arraycount(mode); i++) {
138
139 errno = 0;
140
141 /*
142 * IEEE Std 1003.1-2008 about ENOTDIR:
143 *
144 * "A component of the path prefix is not a directory,
145 * or the path argument contains at least one non-<slash>
146 * character and ends with one or more trailing <slash>
147 * characters and the last pathname component names an
148 * existing file that is neither a directory nor a symbolic
149 * link to a directory."
150 */
151 ATF_REQUIRE(access("/etc/passwd//", mode[i]) != 0);
152 ATF_REQUIRE(errno == ENOTDIR);
153 }
154}
155
156ATF_TC(access_notexist);
157ATF_TC_HEAD(access_notexist, tc)
158{
159 atf_tc_set_md_var(tc, "descr", "Test access(2) for ENOENT");
160}
161
162ATF_TC_BODY(access_notexist, tc)
163{
164 size_t i;
165
166 for (i = 0; i < __arraycount(mode); i++) {
167
168 errno = 0;
169
170 ATF_REQUIRE(access("", mode[i]) != 0);
171 ATF_REQUIRE(errno == ENOENT);
172 }
173}
174
175ATF_TC(access_toolong);
176ATF_TC_HEAD(access_toolong, tc)
177{
178 atf_tc_set_md_var(tc, "descr", "Test access(2) for ENAMETOOLONG");
179}
180
181ATF_TC_BODY(access_toolong, tc)
182{
183 char *buf;
184 size_t i;
185
186 buf = malloc(PATH_MAX);
187
188 if (buf == NULL)
189 return;
190
191 for (i = 0; i < PATH_MAX; i++)
192 buf[i] = 'x';
193
194 for (i = 0; i < __arraycount(mode); i++) {
195
196 errno = 0;
197
198 ATF_REQUIRE(access(buf, mode[i]) != 0);
199 ATF_REQUIRE(errno == ENAMETOOLONG);
200 }
201
202 free(buf);
203}
204
205ATF_TP_ADD_TCS(tp)
206{
207
208 ATF_TP_ADD_TC(tp, access_access);
209 ATF_TP_ADD_TC(tp, access_fault);
210 ATF_TP_ADD_TC(tp, access_inval);
211 ATF_TP_ADD_TC(tp, access_notdir);
212 ATF_TP_ADD_TC(tp, access_notexist);
213 ATF_TP_ADD_TC(tp, access_toolong);
214
215 return atf_no_error();
216}
diff --git a/src/regress/lib/libc/sys/t_bind.c b/src/regress/lib/libc/sys/t_bind.c
new file mode 100644
index 0000000000..7989c7c229
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_bind.c
@@ -0,0 +1,81 @@
1/* $OpenBSD: t_bind.c,v 1.1.1.1 2019/11/19 19:57:03 bluhm Exp $ */
2/* $NetBSD: t_bind.c,v 1.3 2015/04/05 23:28:10 rtr Exp $ */
3/*
4 * Copyright (c) 2015 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "macros.h"
31
32#include <errno.h>
33#include <stdlib.h>
34#include <string.h>
35
36#include <unistd.h>
37
38#include <sys/socket.h>
39#include <arpa/inet.h>
40#include <netinet/in.h>
41
42#include "atf-c.h"
43
44ATF_TC(bind_foreign_family);
45
46ATF_TC_HEAD(bind_foreign_family, tc)
47{
48 atf_tc_set_md_var(tc, "descr", "Checks that binding a socket "
49 "with a different address family fails");
50}
51
52ATF_TC_BODY(bind_foreign_family, tc)
53{
54 struct sockaddr_in addr;
55
56 /* addr.sin_family = AF_UNSPEC = 0 */
57 memset(&addr, 0, sizeof(addr));
58
59 /*
60 * it is not necessary to initialize sin_{addr,port} since
61 * those structure members shall not be accessed if bind
62 * fails correctly.
63 */
64
65 int sock = socket(AF_LOCAL, SOCK_STREAM, 0);
66 ATF_REQUIRE(sock != -1);
67
68 /* should fail but currently doesn't */
69 ATF_REQUIRE(-1 == bind(sock, (struct sockaddr *)&addr, sizeof(addr)));
70 ATF_REQUIRE(EAFNOSUPPORT == errno);
71
72 close(sock);
73}
74
75ATF_TP_ADD_TCS(tp)
76{
77
78 ATF_TP_ADD_TC(tp, bind_foreign_family);
79
80 return atf_no_error();
81}
diff --git a/src/regress/lib/libc/sys/t_chroot.c b/src/regress/lib/libc/sys/t_chroot.c
new file mode 100644
index 0000000000..1fbe392a88
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_chroot.c
@@ -0,0 +1,321 @@
1/* $OpenBSD: t_chroot.c,v 1.1.1.1 2019/11/19 19:57:03 bluhm Exp $ */
2/* $NetBSD: t_chroot.c,v 1.2 2017/01/10 22:36:29 christos Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_chroot.c,v 1.2 2017/01/10 22:36:29 christos Exp $");
37
38#include <sys/wait.h>
39#include <sys/stat.h>
40
41#include "atf-c.h"
42#include <errno.h>
43#include <fcntl.h>
44#include <limits.h>
45#include <pwd.h>
46#include <stdlib.h>
47#include <string.h>
48#include <unistd.h>
49
50ATF_TC(chroot_basic);
51ATF_TC_HEAD(chroot_basic, tc)
52{
53 atf_tc_set_md_var(tc, "descr", "A basic test of chroot(2)");
54 atf_tc_set_md_var(tc, "require.user", "root");
55}
56
57ATF_TC_BODY(chroot_basic, tc)
58{
59 char buf[PATH_MAX];
60 int fd, sta;
61 pid_t pid;
62
63 (void)memset(buf, '\0', sizeof(buf));
64 (void)getcwd(buf, sizeof(buf));
65 (void)strlcat(buf, "/dir", sizeof(buf));
66
67 ATF_REQUIRE(mkdir(buf, 0500) == 0);
68 ATF_REQUIRE(chdir(buf) == 0);
69
70 pid = fork();
71 ATF_REQUIRE(pid >= 0);
72
73 if (pid == 0) {
74
75 if (chroot(buf) != 0)
76 _exit(EXIT_FAILURE);
77
78 errno = 0;
79
80 if (chroot("/root") != -1)
81 _exit(EXIT_FAILURE);
82
83 if (errno != ENOENT)
84 _exit(EXIT_FAILURE);
85
86 fd = open("file", O_RDONLY | O_CREAT, 0600);
87
88 if (fd < 0)
89 _exit(EXIT_FAILURE);
90
91 if (close(fd) != 0)
92 _exit(EXIT_FAILURE);
93
94 _exit(EXIT_SUCCESS);
95 }
96
97 (void)wait(&sta);
98
99 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
100 atf_tc_fail("chroot(2) failed");
101
102 (void)chdir("/");
103 (void)strlcat(buf, "/file", sizeof(buf));
104
105 fd = open(buf, O_RDONLY);
106
107 if (fd < 0)
108 atf_tc_fail("chroot(2) did not change the root directory");
109
110 ATF_REQUIRE(close(fd) == 0);
111 ATF_REQUIRE(unlink(buf) == 0);
112}
113
114ATF_TC(chroot_err);
115ATF_TC_HEAD(chroot_err, tc)
116{
117 atf_tc_set_md_var(tc, "descr", "Test error conditions of chroot(2)");
118 atf_tc_set_md_var(tc, "require.user", "root");
119}
120
121ATF_TC_BODY(chroot_err, tc)
122{
123 char buf[PATH_MAX + 1];
124
125 (void)memset(buf, 'x', sizeof(buf));
126
127 errno = 0;
128 ATF_REQUIRE_ERRNO(ENAMETOOLONG, chroot(buf) == -1);
129
130 errno = 0;
131 ATF_REQUIRE_ERRNO(EFAULT, chroot((void *)-1) == -1);
132
133 errno = 0;
134 ATF_REQUIRE_ERRNO(ENOENT, chroot("/a/b/c/d/e/f/g/h/i/j") == -1);
135}
136
137ATF_TC(chroot_perm);
138ATF_TC_HEAD(chroot_perm, tc)
139{
140 atf_tc_set_md_var(tc, "descr", "Test permissions with chroot(2)");
141 atf_tc_set_md_var(tc, "require.user", "unprivileged");
142}
143
144ATF_TC_BODY(chroot_perm, tc)
145{
146 static char buf[LINE_MAX];
147 pid_t pid;
148 int sta;
149
150 (void)memset(buf, '\0', sizeof(buf));
151 ATF_REQUIRE(getcwd(buf, sizeof(buf)) != NULL);
152
153 pid = fork();
154 ATF_REQUIRE(pid >= 0);
155
156 if (pid == 0) {
157
158 errno = 0;
159
160 if (chroot(buf) != -1)
161 _exit(EXIT_FAILURE);
162
163 if (errno != EPERM)
164 _exit(EXIT_FAILURE);
165
166 _exit(EXIT_SUCCESS);
167 }
168
169 (void)wait(&sta);
170
171 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
172 atf_tc_fail("chroot(2) succeeded as unprivileged user");
173}
174
175ATF_TC(fchroot_basic);
176ATF_TC_HEAD(fchroot_basic, tc)
177{
178 atf_tc_set_md_var(tc, "descr", "A basic test of fchroot(2)");
179 atf_tc_set_md_var(tc, "require.user", "root");
180}
181
182ATF_TC_BODY(fchroot_basic, tc)
183{
184 char buf[PATH_MAX];
185 int fd, sta;
186 pid_t pid;
187
188 (void)memset(buf, '\0', sizeof(buf));
189 (void)getcwd(buf, sizeof(buf));
190 (void)strlcat(buf, "/dir", sizeof(buf));
191
192 ATF_REQUIRE(mkdir(buf, 0500) == 0);
193 ATF_REQUIRE(chdir(buf) == 0);
194
195 fd = open(buf, O_RDONLY);
196 ATF_REQUIRE(fd >= 0);
197
198 pid = fork();
199 ATF_REQUIRE(pid >= 0);
200
201 if (pid == 0) {
202
203 if (fchroot(fd) != 0)
204 _exit(EXIT_FAILURE);
205
206 if (close(fd) != 0)
207 _exit(EXIT_FAILURE);
208
209 fd = open("file", O_RDONLY | O_CREAT, 0600);
210
211 if (fd < 0)
212 _exit(EXIT_FAILURE);
213
214 if (close(fd) != 0)
215 _exit(EXIT_FAILURE);
216
217 _exit(EXIT_SUCCESS);
218 }
219
220 (void)wait(&sta);
221
222 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
223 atf_tc_fail("fchroot(2) failed");
224
225 (void)chdir("/");
226 (void)strlcat(buf, "/file", sizeof(buf));
227
228 fd = open(buf, O_RDONLY);
229
230 if (fd < 0)
231 atf_tc_fail("fchroot(2) did not change the root directory");
232
233 ATF_REQUIRE(close(fd) == 0);
234 ATF_REQUIRE(unlink(buf) == 0);
235}
236
237ATF_TC(fchroot_err);
238ATF_TC_HEAD(fchroot_err, tc)
239{
240 atf_tc_set_md_var(tc, "descr", "Test error conditions of fchroot(2)");
241 atf_tc_set_md_var(tc, "require.user", "root");
242}
243
244ATF_TC_BODY(fchroot_err, tc)
245{
246 int fd;
247
248 fd = open("/etc/passwd", O_RDONLY);
249 ATF_REQUIRE(fd >= 0);
250
251 errno = 0;
252 ATF_REQUIRE_ERRNO(EBADF, fchroot(-1) == -1);
253
254 errno = 0;
255 ATF_REQUIRE_ERRNO(ENOTDIR, fchroot(fd) == -1);
256
257 ATF_REQUIRE(close(fd) == 0);
258}
259
260ATF_TC(fchroot_perm);
261ATF_TC_HEAD(fchroot_perm, tc)
262{
263 atf_tc_set_md_var(tc, "descr", "Test permissions with fchroot(2)");
264 atf_tc_set_md_var(tc, "require.user", "root");
265}
266
267ATF_TC_BODY(fchroot_perm, tc)
268{
269 static char buf[LINE_MAX];
270 struct passwd *pw;
271 int fd, sta;
272 pid_t pid;
273
274 (void)memset(buf, '\0', sizeof(buf));
275 ATF_REQUIRE(getcwd(buf, sizeof(buf)) != NULL);
276
277 pw = getpwnam("nobody");
278 fd = open(buf, O_RDONLY);
279
280 ATF_REQUIRE(fd >= 0);
281 ATF_REQUIRE(pw != NULL);
282
283 pid = fork();
284 ATF_REQUIRE(pid >= 0);
285
286 if (pid == 0) {
287
288 (void)setuid(pw->pw_uid);
289
290 errno = 0;
291
292 if (fchroot(fd) != -1)
293 _exit(EXIT_FAILURE);
294
295 if (errno != EPERM)
296 _exit(EXIT_FAILURE);
297
298 _exit(EXIT_SUCCESS);
299 }
300
301 (void)wait(&sta);
302
303 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
304 atf_tc_fail("fchroot(2) succeeded as unprivileged user");
305}
306
307ATF_TP_ADD_TCS(tp)
308{
309
310 ATF_TP_ADD_TC(tp, chroot_basic);
311 ATF_TP_ADD_TC(tp, chroot_err);
312 ATF_TP_ADD_TC(tp, chroot_perm);
313/*
314 * Not available on OpenBSD
315 * ATF_TP_ADD_TC(tp, fchroot_basic);
316 * ATF_TP_ADD_TC(tp, fchroot_err);
317 * ATF_TP_ADD_TC(tp, fchroot_perm);
318 */
319
320 return atf_no_error();
321}
diff --git a/src/regress/lib/libc/sys/t_clock_gettime.c b/src/regress/lib/libc/sys/t_clock_gettime.c
new file mode 100644
index 0000000000..206710799e
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_clock_gettime.c
@@ -0,0 +1,215 @@
1/* $NetBSD: t_clock_gettime.c,v 1.3 2017/01/13 21:30:41 christos Exp $ */
2
3/*-
4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Frank Kardel.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32/*-
33 * Copyright (c) 2006 Frank Kardel
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 *
45 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
46 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
47 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
48 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
49 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
50 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
51 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
52 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
53 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
54 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
55 * POSSIBILITY OF SUCH DAMAGE.
56 */
57
58#include "macros.h"
59
60#include <sys/cdefs.h>
61__COPYRIGHT("@(#) Copyright (c) 2008\
62 The NetBSD Foundation, inc. All rights reserved.");
63__RCSID("$NetBSD: t_clock_gettime.c,v 1.3 2017/01/13 21:30:41 christos Exp $");
64
65#include <sys/param.h>
66#include <sys/sysctl.h>
67
68
69#include "atf-c.h"
70#include <errno.h>
71#include <limits.h>
72#include <stdio.h>
73#include <stdint.h>
74#include <stdlib.h>
75#include <string.h>
76#include <time.h>
77#include <unistd.h>
78
79#include "h_macros.h"
80
81#define MINPOSDIFF 15000000 /* 15 ms for now */
82#define TIMEOUT 5
83
84#define TC_HARDWARE "kern.timecounter.hardware"
85#define TC_CHOICE "kern.timecounter.choice"
86
87static void
88check_timecounter(void)
89{
90 struct timespec tsa, tsb, tsl, res;
91 long long mindiff = INTMAX_MAX;
92 time_t endlimit;
93
94#define CL(x) \
95 do { \
96 if ((x) != -1) \
97 break; \
98 atf_tc_fail_nonfatal("%s: %s", #x, strerror(errno)); \
99 return; \
100 } while (0)
101
102 CL(clock_gettime(CLOCK_REALTIME, &tsa));
103 tsl = tsa;
104
105 CL(time(&endlimit));
106 endlimit += TIMEOUT + 1;
107
108 while ((time_t)tsa.tv_sec < endlimit) {
109 long long diff;
110
111 CL(clock_gettime(CLOCK_REALTIME, &tsb));
112 diff = 1000000000LL * (tsb.tv_sec - tsa.tv_sec)
113 + tsb.tv_nsec - tsa.tv_nsec;
114
115 if (diff > 0 && mindiff > diff)
116 mindiff = diff;
117
118 if (diff < 0 || diff > MINPOSDIFF) {
119 long long elapsed;
120 (void)printf("%stime TSA: 0x%jx.%08jx, TSB: 0x%jx.%08jx, "
121 "diff = %lld nsec, ", (diff < 0) ? "BAD " : "",
122 (uintmax_t)tsa.tv_sec, (uintmax_t)tsa.tv_nsec,
123 (uintmax_t)tsb.tv_sec, (uintmax_t)tsb.tv_nsec, diff);
124
125 elapsed = 1000000000LL * (tsb.tv_sec - tsl.tv_sec)
126 + tsb.tv_nsec - tsl.tv_nsec;
127
128
129 (void)printf("%lld nsec\n", elapsed);
130 tsl = tsb;
131
132 ATF_CHECK(diff >= 0);
133 if (diff < 0)
134 return;
135 }
136
137 tsa.tv_sec = tsb.tv_sec;
138 tsa.tv_nsec = tsb.tv_nsec;
139 }
140
141 if (clock_getres(CLOCK_REALTIME, &res) == 0) {
142 long long r = res.tv_sec * 1000000000 + res.tv_nsec;
143
144 (void)printf("Claimed resolution: %lld nsec (%f Hz) or "
145 "better\n", r, 1.0 / r * 1e9);
146 (void)printf("Observed minimum non zero delta: %lld "
147 "nsec\n", mindiff);
148 }
149
150#undef CL
151}
152
153ATF_TC(clock_gettime_real);
154ATF_TC_HEAD(clock_gettime_real, tc)
155{
156 atf_tc_set_md_var(tc, "require.user", "root");
157 atf_tc_set_md_var(tc, "descr",
158 "Checks the monotonicity of the CLOCK_REALTIME implementation");
159 atf_tc_set_md_var(tc, "timeout", "300");
160}
161
162ATF_TC_BODY(clock_gettime_real, tc)
163{
164 char name[128], cbuf[512], ctrbuf[10240];
165 size_t cbufsiz = sizeof(cbuf);
166 size_t ctrbufsiz = sizeof(ctrbuf);
167 const char *p;
168 char *save;
169 int quality, n;
170
171 if (sysctlbyname(TC_HARDWARE, cbuf, &cbufsiz, NULL, 0) != 0) {
172 (void)printf("\nChecking legacy time implementation "
173 "for %d seconds\n", TIMEOUT);
174 check_timecounter();
175 return;
176 /* NOTREACHED */
177 }
178 (void)printf("%s = %s\n", TC_HARDWARE, cbuf);
179 REQUIRE_LIBC(save = strdup(cbuf), NULL);
180
181 RL(sysctlbyname(TC_CHOICE, ctrbuf, &ctrbufsiz, NULL, 0));
182 (void)printf("%s = %s\n", TC_CHOICE, ctrbuf);
183
184 for (p = ctrbuf, n = 0; sscanf(p, "%127[^(](q=%d, f=%*u Hz)%*[ ]%n",
185 name, &quality, &n) == 2; p += n) {
186 struct timespec ts;
187 int ret;
188
189 if (quality < 0)
190 continue;
191
192 (void)printf("\nChecking %s for %d seconds\n", name, TIMEOUT);
193 CHECK_LIBC(ret = sysctlbyname(TC_HARDWARE, NULL, 0,
194 name, strlen(name)), -1);
195 if (ret == -1)
196 continue;
197
198 /* wait a bit to select new counter in clockinterrupt */
199 ts.tv_sec = 0;
200 ts.tv_nsec = 100000000;
201 (void)nanosleep(&ts, NULL);
202
203 check_timecounter();
204 }
205
206 RL(sysctlbyname(TC_HARDWARE, NULL, 0, save, strlen(save)));
207}
208
209ATF_TP_ADD_TCS(tp)
210{
211
212 ATF_TP_ADD_TC(tp, clock_gettime_real);
213
214 return atf_no_error();
215}
diff --git a/src/regress/lib/libc/sys/t_dup.c b/src/regress/lib/libc/sys/t_dup.c
new file mode 100644
index 0000000000..4021a4f6e4
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_dup.c
@@ -0,0 +1,395 @@
1/* $OpenBSD: t_dup.c,v 1.1.1.1 2019/11/19 19:57:03 bluhm Exp $ */
2/* $NetBSD: t_dup.c,v 1.9 2017/01/13 20:31:53 christos Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_dup.c,v 1.9 2017/01/13 20:31:53 christos Exp $");
37
38#include <sys/resource.h>
39#include <sys/stat.h>
40#include <sys/wait.h>
41
42#include "atf-c.h"
43#include <errno.h>
44#include <fcntl.h>
45#include <limits.h>
46#include <stdbool.h>
47#include <stdio.h>
48#include <stdlib.h>
49#include <string.h>
50#include <unistd.h>
51#include <sysexits.h>
52
53static char path[] = "dup";
54static void check_mode(bool, bool, bool);
55
56static void
57check_mode(bool _dup, bool _dup2, bool _dup3)
58{
59 int mode[3] = { O_RDONLY, O_WRONLY, O_RDWR };
60 int perm[5] = { 0700, 0400, 0600, 0444, 0666 };
61 struct stat st, st1;
62 int fd, fd1, fd2;
63 size_t i, j;
64
65 /*
66 * Check that a duplicated descriptor
67 * retains the mode of the original file.
68 */
69 for (i = 0; i < __arraycount(mode); i++) {
70
71 for (j = 0; j < __arraycount(perm); j++) {
72
73 fd1 = open(path, mode[i] | O_CREAT, perm[j]);
74 fd2 = open("/etc/passwd", O_RDONLY);
75
76 ATF_REQUIRE(fd1 >= 0);
77 ATF_REQUIRE(fd2 >= 0);
78
79 if (_dup != false)
80 fd = dup(fd1);
81 else if (_dup2 != false)
82 fd = dup2(fd1, fd2);
83 else if (_dup3 != false)
84 fd = dup3(fd1, fd2, O_CLOEXEC);
85 else {
86 fd = -1;
87 }
88
89 ATF_REQUIRE(fd >= 0);
90
91 (void)memset(&st, 0, sizeof(struct stat));
92 (void)memset(&st1, 0, sizeof(struct stat));
93
94 ATF_REQUIRE(fstat(fd, &st) == 0);
95 ATF_REQUIRE(fstat(fd1, &st1) == 0);
96
97 if (st.st_mode != st1.st_mode)
98 atf_tc_fail("invalid mode");
99
100 (void)close(fd);
101 (void)close(fd1);
102 (void)close(fd2);
103 (void)unlink(path);
104 }
105 }
106}
107
108ATF_TC(dup2_basic);
109ATF_TC_HEAD(dup2_basic, tc)
110{
111 atf_tc_set_md_var(tc, "descr", "A basic test of dup2(2)");
112}
113
114ATF_TC_BODY(dup2_basic, tc)
115{
116 int fd, fd1, fd2;
117
118 fd1 = open("/etc/passwd", O_RDONLY);
119 fd2 = open("/etc/passwd", O_RDONLY);
120
121 ATF_REQUIRE(fd1 >= 0);
122 ATF_REQUIRE(fd2 >= 0);
123
124 fd = dup2(fd1, fd2);
125 ATF_REQUIRE(fd >= 0);
126
127 if (fd != fd2)
128 atf_tc_fail("invalid descriptor");
129
130 (void)close(fd);
131 (void)close(fd1);
132
133 ATF_REQUIRE(close(fd2) != 0);
134}
135
136ATF_TC(dup2_err);
137ATF_TC_HEAD(dup2_err, tc)
138{
139 atf_tc_set_md_var(tc, "descr", "Test error conditions of dup2(2)");
140}
141
142ATF_TC_BODY(dup2_err, tc)
143{
144 int fd;
145
146 fd = open("/etc/passwd", O_RDONLY);
147 ATF_REQUIRE(fd >= 0);
148
149 errno = 0;
150 ATF_REQUIRE_ERRNO(EBADF, dup2(-1, -1) == -1);
151
152 errno = 0;
153 ATF_REQUIRE_ERRNO(EBADF, dup2(fd, -1) == -1);
154
155 errno = 0;
156 ATF_REQUIRE_ERRNO(EBADF, dup2(-1, fd) == -1);
157
158 /*
159 * Note that this should not fail with EINVAL.
160 */
161 ATF_REQUIRE(dup2(fd, fd) != -1);
162
163 (void)close(fd);
164}
165
166ATF_TC(dup2_max);
167ATF_TC_HEAD(dup2_max, tc)
168{
169 atf_tc_set_md_var(tc, "descr", "Test dup2(2) against limits");
170}
171
172ATF_TC_BODY(dup2_max, tc)
173{
174 struct rlimit res;
175
176 (void)memset(&res, 0, sizeof(struct rlimit));
177 (void)getrlimit(RLIMIT_NOFILE, &res);
178
179 errno = 0;
180 ATF_REQUIRE_ERRNO(EBADF, dup2(STDERR_FILENO, res.rlim_cur + 1) == -1);
181}
182
183ATF_TC_WITH_CLEANUP(dup2_mode);
184ATF_TC_HEAD(dup2_mode, tc)
185{
186 atf_tc_set_md_var(tc, "descr", "A basic test of dup2(2)");
187}
188
189ATF_TC_BODY(dup2_mode, tc)
190{
191 check_mode(false, true, false);
192}
193
194ATF_TC_CLEANUP(dup2_mode, tc)
195{
196 (void)unlink(path);
197}
198
199
200ATF_TC(dup3_err);
201ATF_TC_HEAD(dup3_err, tc)
202{
203 atf_tc_set_md_var(tc, "descr",
204 "Test error conditions of dup3(2) (PR lib/45148)");
205}
206
207ATF_TC_BODY(dup3_err, tc)
208{
209 int fd;
210
211 fd = open("/etc/passwd", O_RDONLY);
212 ATF_REQUIRE(fd >= 0);
213
214 errno = 0;
215 /* Adjusted for OpenBSD, initially != -1 */
216 ATF_REQUIRE(dup3(fd, fd, O_CLOEXEC) == -1);
217
218 errno = 0;
219 /* Adjusted for OpenBSD, initially EBADF */
220 ATF_REQUIRE_ERRNO(EINVAL, dup3(-1, -1, O_CLOEXEC) == -1);
221
222 errno = 0;
223 ATF_REQUIRE_ERRNO(EBADF, dup3(fd, -1, O_CLOEXEC) == -1);
224
225 errno = 0;
226 ATF_REQUIRE_ERRNO(EBADF, dup3(-1, fd, O_CLOEXEC) == -1);
227
228 errno = 0;
229 ATF_REQUIRE_ERRNO(EINVAL, dup3(fd, 1, O_NOFOLLOW) == -1);
230
231 (void)close(fd);
232}
233
234ATF_TC(dup3_max);
235ATF_TC_HEAD(dup3_max, tc)
236{
237 atf_tc_set_md_var(tc, "descr", "Test dup3(2) against limits");
238}
239
240ATF_TC_BODY(dup3_max, tc)
241{
242 struct rlimit res;
243
244 (void)memset(&res, 0, sizeof(struct rlimit));
245 (void)getrlimit(RLIMIT_NOFILE, &res);
246
247 errno = 0;
248 ATF_REQUIRE_ERRNO(EBADF, dup3(STDERR_FILENO,
249 res.rlim_cur + 1, O_CLOEXEC) == -1);
250}
251
252ATF_TC_WITH_CLEANUP(dup3_mode);
253ATF_TC_HEAD(dup3_mode, tc)
254{
255 atf_tc_set_md_var(tc, "descr", "A basic test of dup3(2)");
256}
257
258ATF_TC_BODY(dup3_mode, tc)
259{
260 check_mode(false, false, true);
261}
262
263ATF_TC_CLEANUP(dup3_mode, tc)
264{
265 (void)unlink(path);
266}
267
268ATF_TC(dup_err);
269ATF_TC_HEAD(dup_err, tc)
270{
271 atf_tc_set_md_var(tc, "descr", "Test error conditions of dup(2)");
272}
273
274ATF_TC_BODY(dup_err, tc)
275{
276
277 errno = 0;
278 ATF_REQUIRE_ERRNO(EBADF, dup(-1) == -1);
279}
280
281ATF_TC_WITH_CLEANUP(dup_max);
282ATF_TC_HEAD(dup_max, tc)
283{
284 atf_tc_set_md_var(tc, "descr", "Test dup(2) against limits");
285}
286
287ATF_TC_BODY(dup_max, tc)
288{
289 struct rlimit res;
290 int *buf, fd, sta;
291 size_t i, n;
292 pid_t pid;
293
294 pid = fork();
295 ATF_REQUIRE(pid >= 0);
296
297 if (pid == 0) {
298
299 /*
300 * Open a temporary file until the
301 * maximum number of open files is
302 * reached. Ater that dup(2) family
303 * should fail with EMFILE.
304 */
305 /* Adjusted for OpenBSD, initially 0 */
306 (void)closefrom(STDERR_FILENO + 1);
307 (void)memset(&res, 0, sizeof(struct rlimit));
308
309 n = 10;
310 res.rlim_cur = res.rlim_max = n;
311 if (setrlimit(RLIMIT_NOFILE, &res) != 0)
312 _exit(EX_OSERR);
313
314 buf = calloc(n, sizeof(int));
315
316 if (buf == NULL)
317 _exit(EX_OSERR);
318
319 /* Adjusted for OpenBSD, initially mkstemp(path) */
320 buf[0] = open(path, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR);
321
322 if (buf[0] < 0)
323 _exit(EX_OSERR);
324
325 /* Adjusted for OpenBSD, initially i < n */
326 for (i = 1; i < n - (STDERR_FILENO + 1); i++) {
327
328 buf[i] = open(path, O_RDONLY);
329
330 if (buf[i] < 0)
331 _exit(EX_OSERR);
332 }
333
334 errno = 0;
335 fd = dup(buf[0]);
336
337 if (fd != -1 || errno != EMFILE)
338 _exit(EX_DATAERR);
339
340 _exit(EXIT_SUCCESS);
341 }
342
343 (void)wait(&sta);
344
345 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) {
346
347 if (WEXITSTATUS(sta) == EX_OSERR)
348 atf_tc_fail("system call error");
349
350 if (WEXITSTATUS(sta) == EX_DATAERR)
351 atf_tc_fail("dup(2) dupped more than RLIMIT_NOFILE");
352
353 atf_tc_fail("unknown error");
354 }
355
356 (void)unlink(path);
357}
358
359ATF_TC_CLEANUP(dup_max, tc)
360{
361 (void)unlink(path);
362}
363
364ATF_TC_WITH_CLEANUP(dup_mode);
365ATF_TC_HEAD(dup_mode, tc)
366{
367 atf_tc_set_md_var(tc, "descr", "A basic test of dup(2)");
368}
369
370ATF_TC_BODY(dup_mode, tc)
371{
372 check_mode(true, false, false);
373}
374
375ATF_TC_CLEANUP(dup_mode, tc)
376{
377 (void)unlink(path);
378}
379
380ATF_TP_ADD_TCS(tp)
381{
382
383 ATF_TP_ADD_TC(tp, dup2_basic);
384 ATF_TP_ADD_TC(tp, dup2_err);
385 ATF_TP_ADD_TC(tp, dup2_max);
386 ATF_TP_ADD_TC(tp, dup2_mode);
387 ATF_TP_ADD_TC(tp, dup3_err);
388 ATF_TP_ADD_TC(tp, dup3_max);
389 ATF_TP_ADD_TC(tp, dup3_mode);
390 ATF_TP_ADD_TC(tp, dup_err);
391 ATF_TP_ADD_TC(tp, dup_max);
392 ATF_TP_ADD_TC(tp, dup_mode);
393
394 return atf_no_error();
395}
diff --git a/src/regress/lib/libc/sys/t_fsync.c b/src/regress/lib/libc/sys/t_fsync.c
new file mode 100644
index 0000000000..c6f24c0e85
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_fsync.c
@@ -0,0 +1,125 @@
1/* $OpenBSD: t_fsync.c,v 1.1.1.1 2019/11/19 19:57:03 bluhm Exp $ */
2/* $NetBSD: t_fsync.c,v 1.2 2012/03/18 07:00:52 jruoho Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_fsync.c,v 1.2 2012/03/18 07:00:52 jruoho Exp $");
37
38#include <errno.h>
39#include <fcntl.h>
40#include <stdio.h>
41#include <stdlib.h>
42#include <string.h>
43#include <unistd.h>
44
45#include "atf-c.h"
46
47ATF_TC(fsync_err);
48ATF_TC_HEAD(fsync_err, tc)
49{
50 atf_tc_set_md_var(tc, "descr",
51 "Test error conditions of fsync(2) (PR kern/30)");
52}
53
54ATF_TC_BODY(fsync_err, tc)
55{
56 int i, fd[2];
57
58 /*
59 * The fsync(2) call should fail with EBADF
60 * when the 'fd' is not a valid descriptor.
61 */
62 for (i = 1; i < 1024; i = i + 128) {
63
64 errno = 0;
65
66 ATF_REQUIRE(fsync(-i) == -1);
67 ATF_REQUIRE(errno == EBADF);
68 }
69
70 /*
71 * On the other hand, EINVAL should follow
72 * if the operation is not possible with
73 * the file descriptor.
74 */
75 ATF_REQUIRE(pipe(fd) == 0);
76
77 errno = 0;
78
79 ATF_REQUIRE(fsync(fd[0]) == -1);
80 ATF_REQUIRE(errno == EINVAL);
81
82 errno = 0;
83
84 ATF_REQUIRE(fsync(fd[1]) == -1);
85 ATF_REQUIRE(errno == EINVAL);
86
87 ATF_REQUIRE(close(fd[0]) == 0);
88 ATF_REQUIRE(close(fd[1]) == 0);
89}
90
91ATF_TC(fsync_sync);
92ATF_TC_HEAD(fsync_sync, tc)
93{
94 atf_tc_set_md_var(tc, "descr", "A basic test of fsync(2)");
95}
96
97ATF_TC_BODY(fsync_sync, tc)
98{
99 char buf[128];
100 int fd, i;
101
102 for (i = 0; i < 10; i++) {
103
104 (void)snprintf(buf, sizeof(buf), "t_fsync-%d", i);
105
106 /* Adjusted for OpenBSD, initially mkstemp(buf) */
107 fd = open(buf, O_CREAT|O_EXCL|O_RDWR, 0600);
108
109 ATF_REQUIRE(fd != -1);
110 ATF_REQUIRE(write(fd, "0", 1) == 1);
111 ATF_REQUIRE(fsync(fd) == 0);
112
113 ATF_REQUIRE(unlink(buf) == 0);
114 ATF_REQUIRE(close(fd) == 0);
115 }
116}
117
118ATF_TP_ADD_TCS(tp)
119{
120
121 ATF_TP_ADD_TC(tp, fsync_err);
122 ATF_TP_ADD_TC(tp, fsync_sync);
123
124 return atf_no_error();
125}
diff --git a/src/regress/lib/libc/sys/t_getgroups.c b/src/regress/lib/libc/sys/t_getgroups.c
new file mode 100644
index 0000000000..dcef3c16f5
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_getgroups.c
@@ -0,0 +1,175 @@
1/* $OpenBSD: t_getgroups.c,v 1.1.1.1 2019/11/19 19:57:03 bluhm Exp $ */
2/* $NetBSD: t_getgroups.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_getgroups.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $");
37
38#include <sys/wait.h>
39
40#include "atf-c.h"
41#include <errno.h>
42#include <limits.h>
43#include <stdlib.h>
44#include <string.h>
45#include <unistd.h>
46
47ATF_TC(getgroups_err);
48ATF_TC_HEAD(getgroups_err, tc)
49{
50 atf_tc_set_md_var(tc, "descr", "Test errors in getgroups(2)");
51}
52
53ATF_TC_BODY(getgroups_err, tc)
54{
55 gid_t gidset[NGROUPS_MAX];
56
57 errno = 0;
58
59 ATF_REQUIRE(getgroups(NGROUPS_MAX, (gid_t *)-1) == -1);
60 ATF_REQUIRE(errno == EFAULT);
61
62 errno = 0;
63
64 ATF_REQUIRE(getgroups(-1, gidset) == -1);
65 ATF_REQUIRE(errno == EINVAL);
66}
67
68ATF_TC(getgroups_getgid);
69ATF_TC_HEAD(getgroups_getgid, tc)
70{
71 atf_tc_set_md_var(tc, "descr", "Test getgid(2) from getgroups(2)");
72}
73
74ATF_TC_BODY(getgroups_getgid, tc)
75{
76 gid_t gidset[NGROUPS_MAX];
77 gid_t gid = getgid();
78 int i, n;
79
80 /*
81 * Check that getgid(2) is found from
82 * the GIDs returned by getgroups(2).
83 */
84 n = getgroups(NGROUPS_MAX, gidset);
85
86 for (i = 0; i < n; i++) {
87
88 if (gidset[i] == gid)
89 return;
90 }
91
92 atf_tc_fail("getgid(2) not found from getgroups(2)");
93}
94
95ATF_TC(getgroups_setgid);
96ATF_TC_HEAD(getgroups_setgid, tc)
97{
98 atf_tc_set_md_var(tc, "descr", "Test setgid(2) from getgroups(2)");
99 atf_tc_set_md_var(tc, "require.user", "root");
100}
101
102ATF_TC_BODY(getgroups_setgid, tc)
103{
104 gid_t gidset[NGROUPS_MAX];
105 int i, n, rv, sta;
106 pid_t pid;
107
108 /*
109 * Check that we can setgid(2)
110 * to the returned group IDs.
111 */
112 n = getgroups(NGROUPS_MAX, gidset);
113 ATF_REQUIRE(n >= 0);
114
115 for (i = 0; i < n; i++) {
116
117 pid = fork();
118 ATF_REQUIRE(pid >= 0);
119
120 if (pid == 0) {
121
122 rv = setgid(gidset[i]);
123
124 if (rv != 0)
125 _exit(EXIT_FAILURE);
126
127 _exit(EXIT_SUCCESS);
128 }
129
130 (void)wait(&sta);
131
132 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
133 atf_tc_fail("getgroups(2) is inconsistent");
134 }
135}
136
137ATF_TC(getgroups_zero);
138ATF_TC_HEAD(getgroups_zero, tc)
139{
140 atf_tc_set_md_var(tc, "descr", "Test getgroups(2) with zero param");
141}
142
143ATF_TC_BODY(getgroups_zero, tc)
144{
145 const gid_t val = 123456789;
146 gid_t gidset[NGROUPS_MAX];
147 size_t i;
148
149 /*
150 * If the first parameter is zero, the number
151 * of groups should be returned but the supplied
152 * buffer should remain intact.
153 */
154 for (i = 0; i < __arraycount(gidset); i++)
155 gidset[i] = val;
156
157 ATF_REQUIRE(getgroups(0, gidset) >= 0);
158
159 for (i = 0; i < __arraycount(gidset); i++) {
160
161 if (gidset[i] != val)
162 atf_tc_fail("getgroups(2) modified the buffer");
163 }
164}
165
166ATF_TP_ADD_TCS(tp)
167{
168
169 ATF_TP_ADD_TC(tp, getgroups_err);
170 ATF_TP_ADD_TC(tp, getgroups_getgid);
171 ATF_TP_ADD_TC(tp, getgroups_setgid);
172 ATF_TP_ADD_TC(tp, getgroups_zero);
173
174 return atf_no_error();
175}
diff --git a/src/regress/lib/libc/sys/t_getitimer.c b/src/regress/lib/libc/sys/t_getitimer.c
new file mode 100644
index 0000000000..b6cc4102bb
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_getitimer.c
@@ -0,0 +1,215 @@
1/* $OpenBSD: t_getitimer.c,v 1.1.1.1 2019/11/19 19:57:03 bluhm Exp $ */
2/* $NetBSD: t_getitimer.c,v 1.2 2012/03/22 18:20:46 christos Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_getitimer.c,v 1.2 2012/03/22 18:20:46 christos Exp $");
37
38#include <sys/time.h>
39
40#include "atf-c.h"
41#include <errno.h>
42#include <limits.h>
43#include <signal.h>
44#include <string.h>
45#include <unistd.h>
46
47static bool fail;
48static void sighandler(int);
49
50static void
51sighandler(int signo)
52{
53
54 if (signo == SIGALRM || signo == SIGVTALRM)
55 fail = false;
56}
57
58ATF_TC(getitimer_empty);
59ATF_TC_HEAD(getitimer_empty, tc)
60{
61 atf_tc_set_md_var(tc, "descr", "getitimer(2) before setitimer(2)");
62}
63
64ATF_TC_BODY(getitimer_empty, tc)
65{
66 struct itimerval it;
67
68 /*
69 * Verify that the passed structure remains
70 * empty after calling getitimer(2) but before
71 * actually arming the timer with setitimer(2).
72 */
73 (void)memset(&it, 0, sizeof(struct itimerval));
74
75 ATF_REQUIRE(getitimer(ITIMER_REAL, &it) == 0);
76
77 if (it.it_value.tv_sec != 0 || it.it_value.tv_usec != 0)
78 goto fail;
79
80 ATF_REQUIRE(getitimer(ITIMER_VIRTUAL, &it) == 0);
81
82 if (it.it_value.tv_sec != 0 || it.it_value.tv_usec != 0)
83 goto fail;
84
85 ATF_REQUIRE(getitimer(ITIMER_PROF, &it) == 0);
86
87 if (it.it_value.tv_sec != 0 || it.it_value.tv_usec != 0)
88 goto fail;
89
90 return;
91
92fail:
93 atf_tc_fail("getitimer(2) modfied the timer before it was armed");
94}
95
96ATF_TC(getitimer_err);
97ATF_TC_HEAD(getitimer_err, tc)
98{
99 atf_tc_set_md_var(tc, "descr", "Test errors from getitimer(2)");
100}
101
102ATF_TC_BODY(getitimer_err, tc)
103{
104 struct itimerval it;
105
106 errno = 0;
107 ATF_REQUIRE_ERRNO(EINVAL, getitimer(-1, &it) == -1);
108
109 errno = 0;
110 ATF_REQUIRE_ERRNO(EINVAL, getitimer(INT_MAX, &it) == -1);
111
112 errno = 0;
113 ATF_REQUIRE_ERRNO(EFAULT, getitimer(ITIMER_REAL, (void *)-1) == -1);
114}
115
116ATF_TC(setitimer_basic);
117ATF_TC_HEAD(setitimer_basic, tc)
118{
119 atf_tc_set_md_var(tc, "descr", "A basic test of setitimer(2)");
120}
121
122ATF_TC_BODY(setitimer_basic, tc)
123{
124 struct itimerval it;
125
126 it.it_value.tv_sec = 0;
127 it.it_value.tv_usec = 100;
128
129 it.it_interval.tv_sec = 0;
130 it.it_interval.tv_usec = 0;
131
132 fail = true;
133
134 ATF_REQUIRE(signal(SIGALRM, sighandler) != SIG_ERR);
135 ATF_REQUIRE(setitimer(ITIMER_REAL, &it, NULL) == 0);
136
137 /*
138 * Although the interaction between
139 * setitimer(2) and sleep(3) can be
140 * unspecified, it is assumed that one
141 * second suspension will be enough for
142 * the timer to fire.
143 */
144 (void)sleep(1);
145
146 if (fail != false)
147 atf_tc_fail("timer did not fire");
148}
149
150ATF_TC(setitimer_err);
151ATF_TC_HEAD(setitimer_err, tc)
152{
153 atf_tc_set_md_var(tc, "descr", "Test errors from setitimer(2)"
154 " (PR standards/44927)");
155}
156
157ATF_TC_BODY(setitimer_err, tc)
158{
159 struct itimerval it, ot;
160
161 errno = 0;
162 ATF_REQUIRE_ERRNO(EINVAL, setitimer(-1, &it, &ot) == -1);
163
164 errno = 0;
165 ATF_REQUIRE_ERRNO(EINVAL, setitimer(INT_MAX, &it, &ot) == -1);
166
167 errno = 0;
168 ATF_REQUIRE_ERRNO(EFAULT, setitimer(ITIMER_REAL,(void*)-1, &ot) == -1);
169}
170
171ATF_TC(setitimer_old);
172ATF_TC_HEAD(setitimer_old, tc)
173{
174 atf_tc_set_md_var(tc, "descr", "Test old values from setitimer(2)");
175}
176
177ATF_TC_BODY(setitimer_old, tc)
178{
179 struct itimerval it, ot;
180
181 /*
182 * Make two calls; the second one
183 * should store the old values.
184 */
185 it.it_value.tv_sec = 4;
186 it.it_value.tv_usec = 3;
187
188 it.it_interval.tv_sec = 0;
189 it.it_interval.tv_usec = 0;
190
191 ATF_REQUIRE(setitimer(ITIMER_REAL, &it, &ot) == 0);
192
193 it.it_value.tv_sec = 2;
194 it.it_value.tv_usec = 1;
195
196 it.it_interval.tv_sec = 0;
197 it.it_interval.tv_usec = 0;
198
199 ATF_REQUIRE(setitimer(ITIMER_REAL, &it, &ot) == 0);
200
201 if (ot.it_value.tv_sec != 4 || ot.it_value.tv_usec != 3)
202 atf_tc_fail("setitimer(2) did not store old values");
203}
204
205ATF_TP_ADD_TCS(tp)
206{
207
208 ATF_TP_ADD_TC(tp, getitimer_empty);
209 ATF_TP_ADD_TC(tp, getitimer_err);
210 ATF_TP_ADD_TC(tp, setitimer_basic);
211 ATF_TP_ADD_TC(tp, setitimer_err);
212 ATF_TP_ADD_TC(tp, setitimer_old);
213
214 return atf_no_error();
215}
diff --git a/src/regress/lib/libc/sys/t_getlogin.c b/src/regress/lib/libc/sys/t_getlogin.c
new file mode 100644
index 0000000000..3c98cd7de8
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_getlogin.c
@@ -0,0 +1,241 @@
1/* $OpenBSD: t_getlogin.c,v 1.1.1.1 2019/11/19 19:57:03 bluhm Exp $ */
2/* $NetBSD: t_getlogin.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_getlogin.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $");
37
38#include <sys/param.h>
39#include <sys/wait.h>
40
41#include "atf-c.h"
42#include <errno.h>
43#include <stdlib.h>
44#include <string.h>
45#include <unistd.h>
46
47ATF_TC(getlogin_r_err);
48ATF_TC_HEAD(getlogin_r_err, tc)
49{
50 atf_tc_set_md_var(tc, "descr", "Test errors from getlogin_r(2)");
51}
52
53ATF_TC_BODY(getlogin_r_err, tc)
54{
55 char small[0];
56
57 ATF_REQUIRE(getlogin_r(small, sizeof(small)) == ERANGE);
58}
59
60ATF_TC(getlogin_same);
61ATF_TC_HEAD(getlogin_same, tc)
62{
63 atf_tc_set_md_var(tc, "descr", "getlogin(2) vs. getlogin_r(2)");
64}
65
66ATF_TC_BODY(getlogin_same, tc)
67{
68 char buf[MAXLOGNAME];
69 char *str;
70
71 str = getlogin();
72
73 if (str == NULL)
74 return;
75
76 ATF_REQUIRE(getlogin_r(buf, sizeof(buf)) == 0);
77
78 if (strcmp(str, buf) != 0)
79 atf_tc_fail("getlogin(2) and getlogin_r(2) differ");
80}
81
82ATF_TC(setlogin_basic);
83ATF_TC_HEAD(setlogin_basic, tc)
84{
85 atf_tc_set_md_var(tc, "descr", "Test that setlogin(2) works");
86 atf_tc_set_md_var(tc, "require.user", "root");
87}
88
89ATF_TC_BODY(setlogin_basic, tc)
90{
91 char *name;
92 pid_t pid;
93 int sta;
94
95 pid = fork();
96 ATF_REQUIRE(pid >= 0);
97
98 if (pid == 0) {
99
100 (void)setsid();
101
102 if (setlogin("foobar") != 0)
103 _exit(EXIT_FAILURE);
104
105 name = getlogin();
106
107 if (name == NULL)
108 _exit(EXIT_FAILURE);
109
110 if (strcmp(name, "foobar") != 0)
111 _exit(EXIT_FAILURE);
112
113 _exit(EXIT_SUCCESS);
114 }
115
116 (void)wait(&sta);
117
118 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
119 atf_tc_fail("setlogin(2) failed to set login name");
120}
121
122ATF_TC(setlogin_err);
123ATF_TC_HEAD(setlogin_err, tc)
124{
125 atf_tc_set_md_var(tc, "descr", "Test errors from setlogin(2)");
126 atf_tc_set_md_var(tc, "require.user", "root");
127}
128
129ATF_TC_BODY(setlogin_err, tc)
130{
131 char buf[MAXLOGNAME + 1];
132 char *name;
133 pid_t pid;
134 int sta;
135
136 pid = fork();
137 ATF_REQUIRE(pid >= 0);
138
139 (void)memset(buf, 'x', sizeof(buf));
140
141 if (pid == 0) {
142
143 (void)setsid();
144
145 errno = 0;
146
147 if (setlogin(buf) != -1)
148 _exit(EINVAL);
149
150 if (errno != EINVAL)
151 _exit(EINVAL);
152
153 errno = 0;
154
155 if (setlogin((void *)-1) != -1)
156 _exit(EFAULT);
157
158 if (errno != EFAULT)
159 _exit(EFAULT);
160
161 name = getlogin();
162
163 if (name == NULL)
164 _exit(EXIT_FAILURE);
165
166 if (strcmp(name, "foobar") == 0)
167 _exit(EXIT_FAILURE);
168
169 _exit(EXIT_SUCCESS);
170 }
171
172 (void)wait(&sta);
173
174 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) {
175
176 if (WEXITSTATUS(sta) == EFAULT)
177 atf_tc_fail("expected EFAULT, but the call succeeded");
178
179 if (WEXITSTATUS(sta) == EINVAL)
180 atf_tc_fail("expected EINVAL, but the call succeeded");
181
182 atf_tc_fail("setlogin(2) failed, but login name was set");
183 }
184}
185
186ATF_TC(setlogin_perm);
187ATF_TC_HEAD(setlogin_perm, tc)
188{
189 atf_tc_set_md_var(tc, "descr", "Test setlogin(2) as normal user");
190 atf_tc_set_md_var(tc, "require.user", "unprivileged");
191}
192
193ATF_TC_BODY(setlogin_perm, tc)
194{
195 char *name;
196 pid_t pid;
197 int sta;
198
199 pid = fork();
200 ATF_REQUIRE(pid >= 0);
201
202 if (pid == 0) {
203
204 (void)setsid();
205
206 errno = 0;
207
208 if (setlogin("foobar") != -1)
209 _exit(EXIT_FAILURE);
210
211 if (errno != EPERM)
212 _exit(EXIT_FAILURE);
213
214 name = getlogin();
215
216 if (name == NULL)
217 _exit(EXIT_FAILURE);
218
219 if (strcmp(name, "foobar") == 0)
220 _exit(EXIT_FAILURE);
221
222 _exit(EXIT_SUCCESS);
223 }
224
225 (void)wait(&sta);
226
227 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
228 atf_tc_fail("login name was set as an unprivileged user");
229}
230
231ATF_TP_ADD_TCS(tp)
232{
233
234 ATF_TP_ADD_TC(tp, getlogin_r_err);
235 ATF_TP_ADD_TC(tp, getlogin_same);
236 ATF_TP_ADD_TC(tp, setlogin_basic);
237 ATF_TP_ADD_TC(tp, setlogin_err);
238 ATF_TP_ADD_TC(tp, setlogin_perm);
239
240 return atf_no_error();
241}
diff --git a/src/regress/lib/libc/sys/t_getpid.c b/src/regress/lib/libc/sys/t_getpid.c
new file mode 100644
index 0000000000..0dbf7f43fe
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_getpid.c
@@ -0,0 +1,138 @@
1/* $OpenBSD: t_getpid.c,v 1.1.1.1 2019/11/19 19:57:03 bluhm Exp $ */
2/* $NetBSD: t_getpid.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_getpid.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $");
37
38#include <sys/wait.h>
39
40#include <stdlib.h>
41#include <pthread.h>
42#include <unistd.h>
43
44#include "atf-c.h"
45
46static int maxiter = 10;
47static void *threadfunc(void *);
48
49static void *
50threadfunc(void *arg)
51{
52 *(pid_t *)arg = getpid();
53
54 return NULL;
55}
56
57ATF_TC(getpid_process);
58ATF_TC_HEAD(getpid_process, tc)
59{
60 atf_tc_set_md_var(tc, "descr", "Test getpid(2) with processes");
61}
62
63ATF_TC_BODY(getpid_process, tc)
64{
65 pid_t ppid, fpid, cpid, tpid, wpid;
66 int i, sta;
67
68 for (i = 0; i < maxiter; i++) {
69
70 tpid = getpid();
71 fpid = fork();
72
73 ATF_REQUIRE(fpid >= 0);
74
75 if (fpid == 0) {
76
77 cpid = getpid();
78 ppid = getppid();
79
80 if (tpid != ppid)
81 _exit(EXIT_FAILURE);
82
83 if (cpid == ppid)
84 _exit(EXIT_FAILURE);
85
86 if (tpid == fpid)
87 _exit(EXIT_FAILURE);
88
89 _exit(EXIT_SUCCESS);
90 }
91
92 wpid = wait(&sta);
93
94 if (wpid != fpid)
95 atf_tc_fail("PID mismatch");
96
97 ATF_REQUIRE(WIFEXITED(sta) != 0);
98
99 if (WEXITSTATUS(sta) != EXIT_SUCCESS)
100 atf_tc_fail("PID mismatch");
101 }
102}
103
104ATF_TC(getpid_thread);
105ATF_TC_HEAD(getpid_thread, tc)
106{
107 atf_tc_set_md_var(tc, "descr", "Test getpid(2) with threads");
108}
109
110ATF_TC_BODY(getpid_thread, tc)
111{
112 pid_t pid, tpid;
113 pthread_t tid;
114 int i, rv;
115
116 for (i = 0; i < maxiter; i++) {
117
118 pid = getpid();
119
120 rv = pthread_create(&tid, NULL, threadfunc, &tpid);
121 ATF_REQUIRE(rv == 0);
122
123 rv = pthread_join(tid, NULL);
124 ATF_REQUIRE(rv == 0);
125
126 if (pid != tpid)
127 atf_tc_fail("Unequal PIDs");
128 }
129}
130
131ATF_TP_ADD_TCS(tp)
132{
133
134 ATF_TP_ADD_TC(tp, getpid_process);
135 ATF_TP_ADD_TC(tp, getpid_thread);
136
137 return atf_no_error();
138}
diff --git a/src/regress/lib/libc/sys/t_getrusage.c b/src/regress/lib/libc/sys/t_getrusage.c
new file mode 100644
index 0000000000..481d73431b
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_getrusage.c
@@ -0,0 +1,269 @@
1/* $OpenBSD: t_getrusage.c,v 1.1.1.1 2019/11/19 19:57:03 bluhm Exp $ */
2/* $NetBSD: t_getrusage.c,v 1.8 2018/05/09 08:45:03 mrg Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_getrusage.c,v 1.8 2018/05/09 08:45:03 mrg Exp $");
37
38#include <sys/resource.h>
39#include <sys/time.h>
40
41#include "atf-c.h"
42#include <stdio.h>
43#include <errno.h>
44#include <limits.h>
45#include <signal.h>
46#include <stdint.h>
47#include <stdlib.h>
48#include <string.h>
49#include <fcntl.h>
50#include <sys/socket.h>
51#include <netinet/in.h>
52
53static void work(void);
54static void sighandler(int);
55
56static const size_t maxiter = 2000;
57
58static void
59sighandler(int signo __unused)
60{
61 /* Nothing. */
62}
63
64static void
65work(void)
66{
67 size_t n = UINT16_MAX * 10;
68
69 while (n > 0) {
70#ifdef __or1k__
71 asm volatile("l.nop"); /* Do something. */
72#elif defined(__ia64__)
73 asm volatile("nop 0"); /* Do something. */
74#else
75 asm volatile("nop"); /* Do something. */
76#endif
77 n--;
78 }
79}
80
81ATF_TC(getrusage_err);
82ATF_TC_HEAD(getrusage_err, tc)
83{
84 atf_tc_set_md_var(tc, "descr", "Test error conditions");
85}
86
87ATF_TC_BODY(getrusage_err, tc)
88{
89 struct rusage ru;
90
91 errno = 0;
92
93 ATF_REQUIRE(getrusage(INT_MAX, &ru) != 0);
94 ATF_REQUIRE(errno == EINVAL);
95
96 errno = 0;
97
98 ATF_REQUIRE(getrusage(RUSAGE_SELF, (void *)0) != 0);
99 ATF_REQUIRE(errno == EFAULT);
100}
101
102ATF_TC(getrusage_sig);
103ATF_TC_HEAD(getrusage_sig, tc)
104{
105 atf_tc_set_md_var(tc, "descr", "Test signal count with getrusage(2)");
106}
107
108ATF_TC_BODY(getrusage_sig, tc)
109{
110 struct rusage ru;
111 const long n = 5;
112 int i;
113
114 /*
115 * Test that signals are recorded.
116 */
117 ATF_REQUIRE(signal(SIGUSR1, sighandler) != SIG_ERR);
118
119 for (i = 0; i < n; i++)
120 ATF_REQUIRE(raise(SIGUSR1) == 0);
121
122 (void)memset(&ru, 0, sizeof(struct rusage));
123 ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru) == 0);
124
125 if (n != ru.ru_nsignals)
126 atf_tc_fail("getrusage(2) did not record signals");
127}
128
129ATF_TC(getrusage_maxrss);
130ATF_TC_HEAD(getrusage_maxrss, tc)
131{
132 atf_tc_set_md_var(tc, "descr", "Test maxrss growing with getrusage(2)");
133}
134
135ATF_TC_BODY(getrusage_maxrss, tc)
136{
137 struct rusage ru;
138 long maxrss;
139 int i, fd;
140
141#define DUMP_FILE "dump"
142
143 fd = open(DUMP_FILE, O_WRONLY|O_CREAT|O_TRUNC, 0222);
144 ATF_REQUIRE(fd != -1);
145
146 (void)memset(&ru, 0, sizeof(struct rusage));
147 ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru) == 0);
148 maxrss = ru.ru_maxrss;
149
150#define CHUNK (1024 * 1024)
151 for (i = 0; i < 40; i++) {
152 void *p = malloc(CHUNK);
153 memset(p, 0, CHUNK);
154 write(fd, p, CHUNK);
155 }
156 close(fd);
157 unlink(DUMP_FILE);
158
159 ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru) == 0);
160 ATF_REQUIRE_MSG(maxrss < ru.ru_maxrss,
161 "maxrss: %ld, ru.ru_maxrss: %ld", maxrss, ru.ru_maxrss);
162}
163
164ATF_TC(getrusage_msgsnd);
165ATF_TC_HEAD(getrusage_msgsnd, tc)
166{
167 atf_tc_set_md_var(tc, "descr", "Test send growing with getrusage(2)");
168}
169
170ATF_TC_BODY(getrusage_msgsnd, tc)
171{
172 struct rusage ru;
173 long msgsnd;
174 int s, i;
175 struct sockaddr_in sin;
176
177 ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru) == 0);
178 msgsnd = ru.ru_msgsnd;
179
180 s = socket(AF_INET, SOCK_DGRAM, 0);
181 ATF_REQUIRE(s >= 0);
182 memset(&sin, 0, sizeof(sin));
183 sin.sin_family = AF_INET;
184 sin.sin_len = sizeof(sin);
185 sin.sin_addr.s_addr = ntohl(INADDR_LOOPBACK);
186 sin.sin_port = htons(3333);
187
188 for (i = 0; i < 10; i++)
189 ATF_REQUIRE(sendto(s, &sin, sizeof(sin), 0, (void *)&sin,
190 (socklen_t)sizeof(sin)) != -1);
191
192 ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru) == 0);
193 ATF_REQUIRE(msgsnd + 10 == ru.ru_msgsnd);
194 close(s);
195}
196
197ATF_TC(getrusage_utime_back);
198ATF_TC_HEAD(getrusage_utime_back, tc)
199{
200 atf_tc_set_md_var(tc, "descr", "Test bogus values from getrusage(2)");
201}
202
203ATF_TC_BODY(getrusage_utime_back, tc)
204{
205 struct rusage ru1, ru2;
206 size_t i;
207
208 /*
209 * Test that two consecutive calls are sane.
210 */
211
212 for (i = 0; i < maxiter; i++) {
213
214 (void)memset(&ru1, 0, sizeof(struct rusage));
215 (void)memset(&ru2, 0, sizeof(struct rusage));
216
217 work();
218
219 ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru1) == 0);
220
221 work();
222
223 ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru2) == 0);
224
225 if (timercmp(&ru2.ru_utime, &ru1.ru_utime, <) != 0)
226 atf_tc_fail("user time went backwards");
227 }
228}
229
230ATF_TC(getrusage_utime_zero);
231ATF_TC_HEAD(getrusage_utime_zero, tc)
232{
233 atf_tc_set_md_var(tc, "descr", "Test zero utime from getrusage(2)");
234}
235
236ATF_TC_BODY(getrusage_utime_zero, tc)
237{
238 struct rusage ru;
239 size_t i;
240
241 /*
242 * Test that getrusage(2) does not return
243 * zero user time for the calling process.
244 */
245
246 for (i = 0; i < maxiter; i++) {
247 work();
248 }
249
250 (void)memset(&ru, 0, sizeof(struct rusage));
251
252 ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru) == 0);
253
254 if (ru.ru_utime.tv_sec == 0 && ru.ru_utime.tv_usec == 0)
255 atf_tc_fail("zero user time from getrusage(2)");
256}
257
258ATF_TP_ADD_TCS(tp)
259{
260
261 ATF_TP_ADD_TC(tp, getrusage_err);
262 ATF_TP_ADD_TC(tp, getrusage_sig);
263 ATF_TP_ADD_TC(tp, getrusage_maxrss);
264 ATF_TP_ADD_TC(tp, getrusage_msgsnd);
265 ATF_TP_ADD_TC(tp, getrusage_utime_back);
266 ATF_TP_ADD_TC(tp, getrusage_utime_zero);
267
268 return atf_no_error();
269}
diff --git a/src/regress/lib/libc/sys/t_getsid.c b/src/regress/lib/libc/sys/t_getsid.c
new file mode 100644
index 0000000000..5ccc2ca1a1
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_getsid.c
@@ -0,0 +1,123 @@
1/* $OpenBSD: t_getsid.c,v 1.1.1.1 2019/11/19 19:57:03 bluhm Exp $ */
2/* $NetBSD: t_getsid.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_getsid.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $");
37
38#include <sys/wait.h>
39
40#include <errno.h>
41#include <stdlib.h>
42#include <unistd.h>
43
44#include "atf-c.h"
45
46ATF_TC(getsid_current);
47ATF_TC_HEAD(getsid_current, tc)
48{
49 atf_tc_set_md_var(tc, "descr", "Test getsid(0)");
50}
51
52ATF_TC_BODY(getsid_current, tc)
53{
54 pid_t sid;
55
56 sid = getsid(0);
57 ATF_REQUIRE(sid != -1);
58
59 if (sid != getsid(getpid()))
60 atf_tc_fail("getsid(0) did not match the calling process");
61}
62
63ATF_TC(getsid_err);
64ATF_TC_HEAD(getsid_err, tc)
65{
66 atf_tc_set_md_var(tc, "descr", "Test error conditions in getsid(2)");
67}
68
69ATF_TC_BODY(getsid_err, tc)
70{
71
72 errno = 0;
73
74 ATF_REQUIRE(getsid(-1) == -1);
75 ATF_REQUIRE(errno == ESRCH);
76}
77
78ATF_TC(getsid_process);
79ATF_TC_HEAD(getsid_process, tc)
80{
81 atf_tc_set_md_var(tc, "descr", "Test getsid(2) with processes");
82}
83
84ATF_TC_BODY(getsid_process, tc)
85{
86 pid_t csid, pid, ppid, sid;
87 int sta;
88
89 sid = getsid(0);
90 pid = fork();
91
92 ATF_REQUIRE(pid >= 0);
93 ATF_REQUIRE(sid != -1);
94
95 if (pid == 0) {
96
97 csid = getsid(0);
98 ppid = getppid();
99
100 if (sid != csid)
101 _exit(EXIT_FAILURE);
102
103 if (getsid(ppid) != csid)
104 _exit(EXIT_FAILURE);
105
106 _exit(EXIT_SUCCESS);
107 }
108
109 (void)wait(&sta);
110
111 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
112 atf_tc_fail("invalid session ID");
113}
114
115ATF_TP_ADD_TCS(tp)
116{
117
118 ATF_TP_ADD_TC(tp, getsid_current);
119 ATF_TP_ADD_TC(tp, getsid_err);
120 ATF_TP_ADD_TC(tp, getsid_process);
121
122 return atf_no_error();
123}
diff --git a/src/regress/lib/libc/sys/t_getsockname.c b/src/regress/lib/libc/sys/t_getsockname.c
new file mode 100644
index 0000000000..8b0accd7a0
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_getsockname.c
@@ -0,0 +1,85 @@
1/* $OpenBSD: t_getsockname.c,v 1.1.1.1 2019/11/19 19:57:03 bluhm Exp $ */
2/* $NetBSD: t_getsockname.c,v 1.1 2016/07/30 11:03:54 njoly Exp $ */
3/*
4 * Copyright (c) 2016 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "macros.h"
31
32#include <sys/socket.h>
33#include <sys/un.h>
34
35#include <string.h>
36#include <unistd.h>
37
38#include "atf-c.h"
39
40ATF_TC(getsockname_unix);
41
42ATF_TC_HEAD(getsockname_unix, tc)
43{
44 atf_tc_set_md_var(tc, "descr", "Checks getsockname with UNIX domain");
45}
46
47ATF_TC_BODY(getsockname_unix, tc)
48{
49 const char *path = "sock.unix";
50 int sd;
51 socklen_t len;
52 struct sockaddr_un sun;
53
54 sd = socket(AF_UNIX, SOCK_STREAM, 0);
55 ATF_REQUIRE(sd != -1);
56
57 len = sizeof(sun);
58 memset(&sun, 0, sizeof(sun));
59 ATF_REQUIRE(getsockname(sd, (struct sockaddr *)&sun, &len) != -1);
60 ATF_CHECK(sun.sun_family == AF_UNIX);
61 ATF_CHECK(strcmp(sun.sun_path, "") == 0);
62
63 len = sizeof(sun);
64 memset(&sun, 0, sizeof(sun));
65 sun.sun_family = AF_UNIX;
66 strcpy(sun.sun_path, path);
67 ATF_REQUIRE(bind(sd, (struct sockaddr *)&sun, len) != -1);
68
69 len = sizeof(sun);
70 memset(&sun, 0, sizeof(sun));
71 ATF_REQUIRE(getsockname(sd, (struct sockaddr *)&sun, &len) != -1);
72 ATF_CHECK(sun.sun_family == AF_UNIX);
73 ATF_CHECK(strcmp(sun.sun_path, path) == 0);
74
75 ATF_REQUIRE(close(sd) != -1);
76 ATF_REQUIRE(unlink(path) != -1);
77}
78
79ATF_TP_ADD_TCS(tp)
80{
81
82 ATF_TP_ADD_TC(tp, getsockname_unix);
83
84 return atf_no_error();
85}
diff --git a/src/regress/lib/libc/sys/t_gettimeofday.c b/src/regress/lib/libc/sys/t_gettimeofday.c
new file mode 100644
index 0000000000..de768b023a
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_gettimeofday.c
@@ -0,0 +1,90 @@
1/* $OpenBSD: t_gettimeofday.c,v 1.1.1.1 2019/11/19 19:57:03 bluhm Exp $ */
2/* $NetBSD: t_gettimeofday.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_gettimeofday.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $");
37
38#include <sys/time.h>
39
40#include "atf-c.h"
41#include <errno.h>
42#include <string.h>
43
44ATF_TC(gettimeofday_err);
45ATF_TC_HEAD(gettimeofday_err, tc)
46{
47 atf_tc_set_md_var(tc, "descr", "Test errors from gettimeofday(2)");
48}
49
50ATF_TC_BODY(gettimeofday_err, tc)
51{
52
53 errno = 0;
54
55 ATF_REQUIRE_ERRNO(EFAULT, gettimeofday((void *)-1, NULL) != 0);
56}
57
58ATF_TC(gettimeofday_mono);
59ATF_TC_HEAD(gettimeofday_mono, tc)
60{
61 atf_tc_set_md_var(tc, "descr", "Test monotonicity of gettimeofday(2)");
62}
63
64ATF_TC_BODY(gettimeofday_mono, tc)
65{
66 static const size_t maxiter = 100;
67 struct timeval tv1, tv2;
68 size_t i;
69
70 for (i = 0; i < maxiter; i++) {
71
72 (void)memset(&tv1, 0, sizeof(struct timeval));
73 (void)memset(&tv2, 0, sizeof(struct timeval));
74
75 ATF_REQUIRE(gettimeofday(&tv1, NULL) == 0);
76 ATF_REQUIRE(gettimeofday(&tv2, NULL) == 0);
77
78 if (timercmp(&tv2, &tv1, <) != 0)
79 atf_tc_fail("time went backwards");
80 }
81}
82
83ATF_TP_ADD_TCS(tp)
84{
85
86 ATF_TP_ADD_TC(tp, gettimeofday_err);
87 ATF_TP_ADD_TC(tp, gettimeofday_mono);
88
89 return atf_no_error();
90}
diff --git a/src/regress/lib/libc/sys/t_kill.c b/src/regress/lib/libc/sys/t_kill.c
new file mode 100644
index 0000000000..c92bbdd18b
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_kill.c
@@ -0,0 +1,316 @@
1/* $OpenBSD: t_kill.c,v 1.1.1.1 2019/11/19 19:57:03 bluhm Exp $ */
2/* $NetBSD: t_kill.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_kill.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $");
37
38#include <sys/wait.h>
39
40#include <errno.h>
41#include <limits.h>
42#include <pwd.h>
43#include <signal.h>
44#include <stdlib.h>
45#include <unistd.h>
46
47#include "atf-c.h"
48
49ATF_TC(kill_basic);
50ATF_TC_HEAD(kill_basic, tc)
51{
52 atf_tc_set_md_var(tc, "descr", "Test that kill(2) works");
53}
54
55ATF_TC_BODY(kill_basic, tc)
56{
57 const int sig[] = { SIGHUP, SIGINT, SIGKILL, SIGTERM };
58 pid_t pid;
59 size_t i;
60 int sta;
61
62 for (i = 0; i < __arraycount(sig); i++) {
63
64 pid = fork();
65 ATF_REQUIRE(pid >= 0);
66
67 switch (pid) {
68
69 case 0:
70 pause();
71 break;
72
73 default:
74 ATF_REQUIRE(kill(pid, sig[i]) == 0);
75 }
76
77 (void)wait(&sta);
78
79 if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != sig[i])
80 atf_tc_fail("kill(2) failed to kill child");
81 }
82}
83
84ATF_TC(kill_err);
85ATF_TC_HEAD(kill_err, tc)
86{
87 atf_tc_set_md_var(tc, "descr", "Test error conditions of kill(2)");
88}
89
90ATF_TC_BODY(kill_err, tc)
91{
92 int rv, sta;
93 pid_t pid;
94
95 pid = fork();
96 ATF_REQUIRE(pid >= 0);
97
98 if (pid == 0) {
99
100 errno = 0;
101 rv = kill(getpid(), -1);
102
103 if (rv == 0 || errno != EINVAL)
104 _exit(EINVAL);
105
106 errno = 0;
107 rv = kill(INT_MAX, SIGUSR1);
108
109 if (rv == 0 || errno != ESRCH)
110 _exit(ESRCH);
111
112 _exit(EXIT_SUCCESS);
113 }
114
115 (void)wait(&sta);
116
117 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) {
118
119 if (WEXITSTATUS(sta) == EINVAL)
120 atf_tc_fail("expected EINVAL, but kill(2) succeeded");
121
122 if (WEXITSTATUS(sta) == ESRCH)
123 atf_tc_fail("expected ESRCH, but kill(2) succeeded");
124
125 atf_tc_fail("unknown error from kill(2)");
126 }
127}
128
129ATF_TC(kill_perm);
130ATF_TC_HEAD(kill_perm, tc)
131{
132 atf_tc_set_md_var(tc, "descr", "Test kill(2) permissions");
133 atf_tc_set_md_var(tc, "require.user", "root");
134}
135
136ATF_TC_BODY(kill_perm, tc)
137{
138 struct passwd *pw;
139 pid_t cpid, ppid;
140 uid_t cuid = 0;
141 uid_t puid = 0;
142 int sta;
143
144 /*
145 * Test that kill(2) fails when called
146 * for a PID owned by another user.
147 */
148 pw = getpwnam("operator");
149
150 if (pw != NULL)
151 cuid = pw->pw_uid;
152
153 pw = getpwnam("nobody");
154
155 if (pw != NULL)
156 puid = pw->pw_uid;
157
158 if (cuid == 0 || puid == 0 || cuid == puid)
159 atf_tc_fail("getpwnam(3) failed");
160
161 ppid = fork();
162
163 if (ppid < 0)
164 _exit(EXIT_FAILURE);
165
166 if (ppid == 0) {
167
168 cpid = fork();
169
170 if (cpid < 0)
171 _exit(EXIT_FAILURE);
172
173 if (cpid == 0) {
174
175 if (setuid(cuid) < 0)
176 _exit(EXIT_FAILURE);
177 else {
178 (void)sleep(1);
179 }
180
181 _exit(EXIT_SUCCESS);
182 }
183
184 /*
185 * Try to kill the child after having
186 * set the real and effective UID.
187 */
188 if (setuid(puid) != 0)
189 _exit(EXIT_FAILURE);
190
191 errno = 0;
192
193 if (kill(cpid, SIGKILL) == 0)
194 _exit(EPERM);
195
196 if (errno != EPERM)
197 _exit(EPERM);
198
199 (void)waitpid(cpid, &sta, 0);
200
201 _exit(EXIT_SUCCESS);
202 }
203
204 (void)waitpid(ppid, &sta, 0);
205
206 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) == EPERM)
207 atf_tc_fail("killed a process of another user");
208
209 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
210 atf_tc_fail("unknown error from kill(2)");
211}
212
213ATF_TC(kill_pgrp_neg);
214ATF_TC_HEAD(kill_pgrp_neg, tc)
215{
216 atf_tc_set_md_var(tc, "descr", "Test kill(2) with process group, #2");
217}
218
219ATF_TC_BODY(kill_pgrp_neg, tc)
220{
221 const int maxiter = 3;
222 pid_t cpid, ppid;
223 int i, sta;
224
225 ppid = fork();
226 ATF_REQUIRE(ppid >= 0);
227
228 if (ppid == 0) {
229
230 ATF_REQUIRE(setpgid(0, 0) == 0);
231
232 for (i = 0; i < maxiter; i++) {
233
234 cpid = fork();
235 ATF_REQUIRE(cpid >= 0);
236
237 if (cpid == 0)
238 pause();
239 }
240
241 /*
242 * Test the variant of killpg(3); if the process number
243 * is negative but not -1, the signal should be sent to
244 * all processes whose process group ID is equal to the
245 * absolute value of the process number.
246 */
247 ATF_REQUIRE(kill(-getpgrp(), SIGKILL) == 0);
248
249 (void)sleep(1);
250
251 _exit(EXIT_SUCCESS);
252 }
253
254 (void)waitpid(ppid, &sta, 0);
255
256 if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != SIGKILL)
257 atf_tc_fail("failed to kill(2) a process group");
258}
259
260ATF_TC(kill_pgrp_zero);
261ATF_TC_HEAD(kill_pgrp_zero, tc)
262{
263 atf_tc_set_md_var(tc, "descr", "Test kill(2) with process group, #1");
264}
265
266ATF_TC_BODY(kill_pgrp_zero, tc)
267{
268 const int maxiter = 3;
269 pid_t cpid, ppid;
270 int i, sta;
271
272 ppid = fork();
273 ATF_REQUIRE(ppid >= 0);
274
275 if (ppid == 0) {
276
277 ATF_REQUIRE(setpgid(0, 0) == 0);
278
279 for (i = 0; i < maxiter; i++) {
280
281 cpid = fork();
282 ATF_REQUIRE(cpid >= 0);
283
284 if (cpid == 0)
285 pause();
286 }
287
288 /*
289 * If the supplied process number is zero,
290 * the signal should be sent to all processes
291 * under the current process group.
292 */
293 ATF_REQUIRE(kill(0, SIGKILL) == 0);
294
295 (void)sleep(1);
296
297 _exit(EXIT_SUCCESS);
298 }
299
300 (void)waitpid(ppid, &sta, 0);
301
302 if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != SIGKILL)
303 atf_tc_fail("failed to kill(2) a process group");
304}
305
306ATF_TP_ADD_TCS(tp)
307{
308
309 ATF_TP_ADD_TC(tp, kill_basic);
310 ATF_TP_ADD_TC(tp, kill_err);
311 ATF_TP_ADD_TC(tp, kill_perm);
312 ATF_TP_ADD_TC(tp, kill_pgrp_neg);
313 ATF_TP_ADD_TC(tp, kill_pgrp_zero);
314
315 return atf_no_error();
316}
diff --git a/src/regress/lib/libc/sys/t_link.c b/src/regress/lib/libc/sys/t_link.c
new file mode 100644
index 0000000000..291fd9cda4
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_link.c
@@ -0,0 +1,234 @@
1/* $OpenBSD: t_link.c,v 1.1.1.1 2019/11/19 19:57:03 bluhm Exp $ */
2/* $NetBSD: t_link.c,v 1.3 2017/01/13 20:42:36 christos Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_link.c,v 1.3 2017/01/13 20:42:36 christos Exp $");
37
38#include <sys/param.h>
39#include <sys/stat.h>
40
41#include "atf-c.h"
42#include <errno.h>
43#include <fcntl.h>
44#include <limits.h>
45#include <stdio.h>
46#include <string.h>
47#include <unistd.h>
48
49static const char *getpath(void);
50static char path[] = "link";
51static const char *pathl;
52
53static const char *
54getpath(void)
55{
56 static char buf[LINE_MAX];
57
58 (void)memset(buf, '\0', sizeof(buf));
59
60 if (getcwd(buf, sizeof(buf)) == NULL)
61 return NULL;
62
63 (void)strlcat(buf, path, sizeof(buf));
64 (void)strlcat(buf, ".link", sizeof(buf));
65
66 return buf;
67}
68
69ATF_TC_WITH_CLEANUP(link_count);
70ATF_TC_HEAD(link_count, tc)
71{
72 atf_tc_set_md_var(tc, "descr", "link(2) counts are incremented?");
73}
74
75ATF_TC_BODY(link_count, tc)
76{
77 struct stat sa, sb;
78 int fd;
79
80 (void)memset(&sa, 0, sizeof(struct stat));
81 (void)memset(&sb, 0, sizeof(struct stat));
82
83 pathl = getpath();
84 fd = open(path, O_RDWR | O_CREAT, 0600);
85
86 ATF_REQUIRE(fd >= 0);
87 ATF_REQUIRE(pathl != NULL);
88
89 ATF_REQUIRE(stat(path, &sa) == 0);
90 ATF_REQUIRE(link(path, pathl) == 0);
91 ATF_REQUIRE(stat(path, &sb) == 0);
92
93 if (sa.st_nlink != sb.st_nlink - 1)
94 atf_tc_fail("incorrect link(2) count");
95
96 ATF_REQUIRE(close(fd) == 0);
97 ATF_REQUIRE(unlink(path) == 0);
98 ATF_REQUIRE(unlink(pathl) == 0);
99}
100
101ATF_TC_CLEANUP(link_count, tc)
102{
103 (void)unlink(path);
104 (void)unlink(pathl);
105}
106
107ATF_TC_WITH_CLEANUP(link_err);
108ATF_TC_HEAD(link_err, tc)
109{
110 atf_tc_set_md_var(tc, "descr", "Test error conditions of link(2)");
111}
112
113ATF_TC_BODY(link_err, tc)
114{
115 char buf[MAXPATHLEN + 1];
116 int fd;
117
118 (void)memset(buf, 'x', sizeof(buf));
119
120 pathl = getpath();
121 fd = open(path, O_RDWR | O_CREAT, 0600);
122
123 ATF_REQUIRE(fd >= 0);
124 ATF_REQUIRE(pathl != NULL);
125
126 errno = 0;
127 ATF_REQUIRE(link(path, pathl) == 0);
128 ATF_REQUIRE_ERRNO(EEXIST, link(path, pathl) == -1);
129
130 errno = 0;
131 ATF_REQUIRE_ERRNO(ENAMETOOLONG, link(buf, "xxx") == -1);
132
133 errno = 0;
134 ATF_REQUIRE_ERRNO(ENOENT, link(path, "/d/c/b/a") == -1);
135
136 errno = 0;
137 ATF_REQUIRE_ERRNO(ENOENT, link("/a/b/c/d", path) == -1);
138
139 errno = 0;
140 ATF_REQUIRE_ERRNO(ENOENT, link("/a/b/c/d", "/d/c/b/a") == -1);
141
142 errno = 0;
143 ATF_REQUIRE_ERRNO(EFAULT, link(path, (const char *)-1) == -1);
144
145 errno = 0;
146 ATF_REQUIRE_ERRNO(EFAULT, link((const char *)-1, "xxx") == -1);
147
148 ATF_REQUIRE(close(fd) == 0);
149 ATF_REQUIRE(unlink(path) == 0);
150 ATF_REQUIRE(unlink(pathl) == 0);
151}
152
153ATF_TC_CLEANUP(link_err, tc)
154{
155 (void)unlink(path);
156 (void)unlink(pathl);
157}
158
159ATF_TC(link_perm);
160ATF_TC_HEAD(link_perm, tc)
161{
162 atf_tc_set_md_var(tc, "descr", "Test permissions with link(2)");
163 atf_tc_set_md_var(tc, "require.user", "unprivileged");
164}
165
166ATF_TC_BODY(link_perm, tc)
167{
168 int rv;
169
170 errno = 0;
171 rv = link("/root", "/root.link");
172 ATF_REQUIRE_MSG(rv == -1 && (errno == EACCES || errno == EPERM),
173 "link to a directory did not fail with EPERM or EACCESS; link() "
174 "returned %d, errno %d", rv, errno);
175
176 errno = 0;
177 ATF_REQUIRE_ERRNO(EACCES,
178 link("/root/.profile", "/root/.profile.link") == -1);
179}
180
181ATF_TC_WITH_CLEANUP(link_stat);
182ATF_TC_HEAD(link_stat, tc)
183{
184 atf_tc_set_md_var(tc, "descr", "Check stat(2) of a linked file");
185}
186
187ATF_TC_BODY(link_stat, tc)
188{
189 struct stat sa, sb;
190 int fd;
191
192 (void)memset(&sa, 0, sizeof(struct stat));
193 (void)memset(&sb, 0, sizeof(struct stat));
194
195 pathl = getpath();
196 fd = open(path, O_RDWR | O_CREAT, 0600);
197
198 ATF_REQUIRE(fd >= 0);
199 ATF_REQUIRE(pathl != NULL);
200
201 ATF_REQUIRE(link(path, pathl) == 0);
202 ATF_REQUIRE(stat(path, &sa) == 0);
203 ATF_REQUIRE(lstat(pathl, &sb) == 0);
204
205 if (sa.st_uid != sb.st_uid)
206 atf_tc_fail("unequal UIDs");
207
208 if (sa.st_mode != sb.st_mode)
209 atf_tc_fail("unequal modes");
210
211 if (sa.st_ino != sb.st_ino)
212 atf_tc_fail("unequal inodes");
213
214 ATF_REQUIRE(close(fd) == 0);
215 ATF_REQUIRE(unlink(path) == 0);
216 ATF_REQUIRE(unlink(pathl) == 0);
217}
218
219ATF_TC_CLEANUP(link_stat, tc)
220{
221 (void)unlink(path);
222 (void)unlink(pathl);
223}
224
225ATF_TP_ADD_TCS(tp)
226{
227
228 ATF_TP_ADD_TC(tp, link_count);
229 ATF_TP_ADD_TC(tp, link_err);
230 ATF_TP_ADD_TC(tp, link_perm);
231 ATF_TP_ADD_TC(tp, link_stat);
232
233 return atf_no_error();
234}
diff --git a/src/regress/lib/libc/sys/t_listen.c b/src/regress/lib/libc/sys/t_listen.c
new file mode 100644
index 0000000000..da5b287cdf
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_listen.c
@@ -0,0 +1,139 @@
1/* $OpenBSD: t_listen.c,v 1.1.1.1 2019/11/19 19:57:03 bluhm Exp $ */
2/* $NetBSD: t_listen.c,v 1.6 2019/07/09 16:24:01 maya Exp $ */
3/*
4 * Copyright (c) 2007 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "macros.h"
31
32#include <sys/socket.h>
33#include "atf-c.h"
34#include <err.h>
35#include <errno.h>
36#include <fcntl.h>
37#include <string.h>
38#include <unistd.h>
39
40#include <arpa/inet.h>
41#include <netinet/in.h>
42
43static const char *path = "listen";
44
45ATF_TC_WITH_CLEANUP(listen_err);
46ATF_TC_HEAD(listen_err, tc)
47{
48 atf_tc_set_md_var(tc, "descr",
49 "Checks errors from listen(2) (PR standards/46150)");
50}
51
52ATF_TC_BODY(listen_err, tc)
53{
54 static const size_t siz = sizeof(struct sockaddr_in);
55 struct sockaddr_in sina, sinb;
56 int fda, fdb, fdc;
57
58 (void)memset(&sina, 0, sizeof(struct sockaddr_in));
59 (void)memset(&sinb, 0, sizeof(struct sockaddr_in));
60
61 sina.sin_family = AF_INET;
62 sina.sin_port = htons(31522);
63 sina.sin_addr.s_addr = inet_addr("127.0.0.1");
64
65 sinb.sin_family = AF_INET;
66 sinb.sin_port = htons(31522);
67 sinb.sin_addr.s_addr = inet_addr("127.0.0.1");
68
69 fda = socket(AF_INET, SOCK_STREAM, 0);
70 fdb = socket(AF_INET, SOCK_STREAM, 0);
71 fdc = open("listen", O_RDWR | O_CREAT, 0600);
72
73 ATF_REQUIRE(fda >= 0 && fdb >= 0 && fdc >= 0);
74 ATF_REQUIRE_ERRNO(ENOTSOCK, listen(fdc, 1) == -1);
75
76 (void)close(fdc);
77 (void)unlink(path);
78
79 ATF_REQUIRE(bind(fda, (struct sockaddr *)&sina, siz) == 0);
80 ATF_REQUIRE(listen(fda, 1) == 0);
81
82 /*
83 * According to IEEE Std 1003.1-2008: if the socket is
84 * already connected, the call should fail with EINVAL.
85 */
86 ATF_REQUIRE(connect(fdb, (struct sockaddr *)&sinb, siz) == 0);
87 ATF_REQUIRE_ERRNO(EINVAL, listen(fdb, 1) == -1);
88
89 (void)close(fda);
90 (void)close(fdb);
91
92 ATF_REQUIRE_ERRNO(EBADF, connect(fdb,
93 (struct sockaddr *)&sinb, siz) == -1);
94}
95
96ATF_TC_CLEANUP(listen_err, tc)
97{
98 (void)unlink(path);
99}
100
101ATF_TC(listen_low_port);
102ATF_TC_HEAD(listen_low_port, tc)
103{
104 atf_tc_set_md_var(tc, "descr", "Does low-port allocation work?");
105 atf_tc_set_md_var(tc, "require.user", "root");
106}
107
108ATF_TC_BODY(listen_low_port, tc)
109{
110 int sd, val;
111
112 sd = socket(AF_INET, SOCK_STREAM, 0);
113 ATF_REQUIRE_MSG(sd != -1, "socket failed: %s", strerror(errno));
114
115 val = IP_PORTRANGE_LOW;
116 if (setsockopt(sd, IPPROTO_IP, IP_PORTRANGE, &val,
117 sizeof(val)) == -1)
118 atf_tc_fail("setsockopt failed: %s", strerror(errno));
119
120 if (listen(sd, 5) == -1) {
121 int serrno = errno;
122 atf_tc_fail("listen failed: %s%s",
123 strerror(serrno),
124 serrno != EACCES ? "" :
125 " (see http://mail-index.netbsd.org/"
126 "source-changes/2007/12/16/0011.html)");
127 }
128
129 close(sd);
130}
131
132ATF_TP_ADD_TCS(tp)
133{
134
135 ATF_TP_ADD_TC(tp, listen_err);
136 ATF_TP_ADD_TC(tp, listen_low_port);
137
138 return atf_no_error();
139}
diff --git a/src/regress/lib/libc/sys/t_mkdir.c b/src/regress/lib/libc/sys/t_mkdir.c
new file mode 100644
index 0000000000..41df34ace9
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_mkdir.c
@@ -0,0 +1,213 @@
1/* $OpenBSD: t_mkdir.c,v 1.1.1.1 2019/11/19 19:57:03 bluhm Exp $ */
2/* $NetBSD: t_mkdir.c,v 1.2 2011/10/15 07:38:31 jruoho Exp $ */
3
4/*-
5 * Copyright (c) 2008, 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jason R. Thorpe and Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__COPYRIGHT("@(#) Copyright (c) 2008\
37 The NetBSD Foundation, inc. All rights reserved.");
38__RCSID("$NetBSD: t_mkdir.c,v 1.2 2011/10/15 07:38:31 jruoho Exp $");
39
40#include <sys/stat.h>
41#include <sys/wait.h>
42
43#include "atf-c.h"
44#include <errno.h>
45#include <fcntl.h>
46#include <limits.h>
47#include <pwd.h>
48#include <stdio.h>
49#include <stdlib.h>
50#include <string.h>
51#include <unistd.h>
52
53ATF_TC(mkdir_err);
54ATF_TC_HEAD(mkdir_err, tc)
55{
56 atf_tc_set_md_var(tc, "descr", "Checks errors from mkdir(2)");
57}
58
59ATF_TC_BODY(mkdir_err, tc)
60{
61 char buf[PATH_MAX + 1];
62 int fd;
63
64 (void)memset(buf, 'x', sizeof(buf));
65
66 fd = open("/etc", O_RDONLY);
67
68 if (fd >= 0) {
69
70 (void)close(fd);
71
72 errno = 0;
73 ATF_REQUIRE_ERRNO(EEXIST, mkdir("/etc", 0500) == -1);
74 }
75
76 errno = 0;
77 ATF_REQUIRE_ERRNO(EFAULT, mkdir((void *)-1, 0500) == -1);
78
79 errno = 0;
80 ATF_REQUIRE_ERRNO(ENAMETOOLONG, mkdir(buf, 0500) == -1);
81
82 errno = 0;
83 ATF_REQUIRE_ERRNO(ENOENT, mkdir("/a/b/c/d/e/f/g/h/i/j/k", 0500) == -1);
84}
85
86ATF_TC_WITH_CLEANUP(mkdir_perm);
87ATF_TC_HEAD(mkdir_perm, tc)
88{
89 atf_tc_set_md_var(tc, "descr", "Checks permissions with mkdir(2)");
90 atf_tc_set_md_var(tc, "require.user", "unprivileged");
91}
92
93ATF_TC_BODY(mkdir_perm, tc)
94{
95 errno = 0;
96 ATF_REQUIRE_ERRNO(EACCES, mkdir("/usr/__nonexistent__", 0500) == -1);
97}
98
99ATF_TC_CLEANUP(mkdir_perm, tc)
100{
101 (void)rmdir("/usr/__nonexistent__");
102}
103
104ATF_TC_WITH_CLEANUP(mkdir_mode);
105ATF_TC_HEAD(mkdir_mode, tc)
106{
107 atf_tc_set_md_var(tc, "descr", "Test that UIDs and GIDs are right "
108 "for a directory created with mkdir(2)");
109 atf_tc_set_md_var(tc, "require.user", "root");
110}
111
112ATF_TC_BODY(mkdir_mode, tc)
113{
114 static const char *path = "/tmp/mkdir";
115 struct stat st_a, st_b;
116 struct passwd *pw;
117 pid_t pid;
118 int sta;
119
120 (void)memset(&st_a, 0, sizeof(struct stat));
121 (void)memset(&st_b, 0, sizeof(struct stat));
122
123 pw = getpwnam("nobody");
124
125 ATF_REQUIRE(pw != NULL);
126 ATF_REQUIRE(stat("/tmp", &st_a) == 0);
127
128 pid = fork();
129 ATF_REQUIRE(pid >= 0);
130
131 if (pid == 0) {
132
133 if (setuid(pw->pw_uid) != 0)
134 _exit(EXIT_FAILURE);
135
136 if (mkdir(path, 0500) != 0)
137 _exit(EXIT_FAILURE);
138
139 _exit(EXIT_SUCCESS);
140 }
141
142 (void)sleep(1);
143 (void)wait(&sta);
144
145 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
146 atf_tc_fail("failed to create '%s'", path);
147
148 ATF_REQUIRE(stat(path, &st_b) == 0);
149 ATF_REQUIRE(rmdir(path) == 0);
150
151 /*
152 * The directory's owner ID should be set to the
153 * effective UID, whereas the group ID should be
154 * set to that of the parent directory.
155 */
156 if (st_b.st_uid != pw->pw_uid)
157 atf_tc_fail("invalid UID for '%s'", path);
158
159 if (st_b.st_gid != st_a.st_gid)
160 atf_tc_fail("GID did not follow the parent directory");
161}
162
163ATF_TC_CLEANUP(mkdir_mode, tc)
164{
165 (void)rmdir("/tmp/mkdir");
166}
167
168ATF_TC(mkdir_trail);
169ATF_TC_HEAD(mkdir_trail, tc)
170{
171 atf_tc_set_md_var(tc, "descr", "Checks mkdir(2) for trailing slashes");
172}
173
174ATF_TC_BODY(mkdir_trail, tc)
175{
176 const char *tests[] = {
177 /*
178 * IEEE 1003.1 second ed. 2.2.2.78:
179 *
180 * If the pathname refers to a directory, it may also have
181 * one or more trailing slashes. Multiple successive slashes
182 * are considered to be the same as one slash.
183 */
184 "dir1/",
185 "dir2//",
186
187 NULL,
188 };
189
190 const char **test;
191
192 for (test = &tests[0]; *test != NULL; ++test) {
193
194 (void)printf("Checking \"%s\"\n", *test);
195 (void)rmdir(*test);
196
197 ATF_REQUIRE(mkdir(*test, 0777) == 0);
198 ATF_REQUIRE(rename(*test, "foo") == 0);
199 ATF_REQUIRE(rename("foo/", *test) == 0);
200 ATF_REQUIRE(rmdir(*test) == 0);
201 }
202}
203
204ATF_TP_ADD_TCS(tp)
205{
206
207 ATF_TP_ADD_TC(tp, mkdir_err);
208 ATF_TP_ADD_TC(tp, mkdir_perm);
209 ATF_TP_ADD_TC(tp, mkdir_mode);
210 ATF_TP_ADD_TC(tp, mkdir_trail);
211
212 return atf_no_error();
213}
diff --git a/src/regress/lib/libc/sys/t_mkfifo.c b/src/regress/lib/libc/sys/t_mkfifo.c
new file mode 100644
index 0000000000..1c2fe60e3a
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_mkfifo.c
@@ -0,0 +1,309 @@
1/* $OpenBSD: t_mkfifo.c,v 1.1.1.1 2019/11/19 19:57:03 bluhm Exp $ */
2/* $NetBSD: t_mkfifo.c,v 1.3 2019/06/20 03:31:54 kamil Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_mkfifo.c,v 1.3 2019/06/20 03:31:54 kamil Exp $");
37
38#include <sys/stat.h>
39#include <sys/wait.h>
40
41#include "atf-c.h"
42#include <errno.h>
43#include <fcntl.h>
44#include <limits.h>
45#include <stdlib.h>
46#include <signal.h>
47#include <string.h>
48#include <unistd.h>
49
50static const char path[] = "fifo";
51static void support(void);
52
53static void
54support(void)
55{
56
57 errno = 0;
58
59 if (mkfifo(path, 0600) == 0) {
60 ATF_REQUIRE(unlink(path) == 0);
61 return;
62 }
63
64 if (errno == EOPNOTSUPP)
65 atf_tc_skip("the kernel does not support FIFOs");
66 else {
67 atf_tc_fail("mkfifo(2) failed");
68 }
69}
70
71ATF_TC_WITH_CLEANUP(mkfifo_block);
72ATF_TC_HEAD(mkfifo_block, tc)
73{
74 atf_tc_set_md_var(tc, "descr", "Test that FIFOs block");
75}
76
77ATF_TC_BODY(mkfifo_block, tc)
78{
79 int sta, fd = -1;
80 pid_t pid;
81
82 support();
83
84 ATF_REQUIRE(mkfifo(path, 0600) == 0);
85
86 pid = fork();
87 ATF_REQUIRE(pid >= 0);
88
89 if (pid == 0) {
90
91 /*
92 * If we open the FIFO as read-only (write-only),
93 * the call should block until another process
94 * opens the FIFO for writing (reading).
95 */
96 fd = open(path, O_RDONLY);
97
98 _exit(EXIT_FAILURE); /* NOTREACHED */
99 }
100
101 (void)sleep(1);
102
103 ATF_REQUIRE(kill(pid, SIGKILL) == 0);
104
105 (void)wait(&sta);
106
107 if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != SIGKILL)
108 atf_tc_fail("FIFO did not block");
109
110 (void)close(fd);
111 (void)unlink(path);
112}
113
114ATF_TC_CLEANUP(mkfifo_block, tc)
115{
116 (void)unlink(path);
117}
118
119ATF_TC_WITH_CLEANUP(mkfifo_err);
120ATF_TC_HEAD(mkfifo_err, tc)
121{
122 atf_tc_set_md_var(tc, "descr", "Test erros from mkfifo(2)");
123}
124
125ATF_TC_BODY(mkfifo_err, tc)
126{
127 char buf[PATH_MAX + 1];
128
129 support();
130
131 (void)memset(buf, 'x', sizeof(buf));
132 ATF_REQUIRE(mkfifo(path, 0600) == 0);
133
134 errno = 0;
135 ATF_REQUIRE_ERRNO(EFAULT, mkfifo((char *)-1, 0600) == -1);
136
137 errno = 0;
138 ATF_REQUIRE_ERRNO(EEXIST, mkfifo("/etc/passwd", 0600) == -1);
139
140 errno = 0;
141 ATF_REQUIRE_ERRNO(EEXIST, mkfifo(path, 0600) == -1);
142
143 errno = 0;
144 ATF_REQUIRE_ERRNO(ENAMETOOLONG, mkfifo(buf, 0600) == -1);
145
146 errno = 0;
147 ATF_REQUIRE_ERRNO(ENOENT, mkfifo("/a/b/c/d/e/f/g", 0600) == -1);
148
149 ATF_REQUIRE(unlink(path) == 0);
150}
151
152ATF_TC_CLEANUP(mkfifo_err, tc)
153{
154 (void)unlink(path);
155}
156
157ATF_TC_WITH_CLEANUP(mkfifo_nonblock);
158ATF_TC_HEAD(mkfifo_nonblock, tc)
159{
160 atf_tc_set_md_var(tc, "descr", "Test O_NONBLOCK with FIFOs");
161}
162
163ATF_TC_BODY(mkfifo_nonblock, tc)
164{
165 int fd, sta;
166 pid_t pid;
167
168 support();
169
170 fd = -1;
171 ATF_REQUIRE(mkfifo(path, 0600) == 0);
172
173 pid = fork();
174 ATF_REQUIRE(pid >= 0);
175
176 if (pid == 0) {
177
178 /*
179 * If we open the FIFO as O_NONBLOCK, the O_RDONLY
180 * call should return immediately, whereas the call
181 * for write-only should fail with ENXIO.
182 */
183 fd = open(path, O_RDONLY | O_NONBLOCK);
184
185 if (fd >= 0)
186 _exit(EXIT_SUCCESS);
187
188 (void)pause(); /* NOTREACHED */
189 }
190
191 (void)sleep(1);
192
193 errno = 0;
194 ATF_REQUIRE_ERRNO(ENXIO, open(path, O_WRONLY | O_NONBLOCK) == -1);
195
196 (void)kill(pid, SIGKILL);
197 (void)wait(&sta);
198
199 if (WIFSIGNALED(sta) != 0 || WTERMSIG(sta) == SIGKILL)
200 atf_tc_fail("FIFO blocked for O_NONBLOCK open(2)");
201
202 (void)close(fd);
203 (void)unlink(path);
204}
205
206ATF_TC_CLEANUP(mkfifo_nonblock, tc)
207{
208 (void)unlink(path);
209}
210
211ATF_TC_WITH_CLEANUP(mkfifo_perm);
212ATF_TC_HEAD(mkfifo_perm, tc)
213{
214 atf_tc_set_md_var(tc, "descr", "Test permissions with mkfifo(2)");
215 atf_tc_set_md_var(tc, "require.user", "unprivileged");
216}
217
218ATF_TC_BODY(mkfifo_perm, tc)
219{
220
221 support();
222
223 errno = 0;
224 ATF_REQUIRE_ERRNO(EACCES, mkfifo("/root/fifo", 0600) == -1);
225
226 ATF_REQUIRE(mkfifo(path, 0600) == 0);
227
228 /*
229 * For some reason this fails with EFTYPE...
230 */
231 errno = 0;
232 ATF_REQUIRE_ERRNO(EFTYPE, chmod(path, 1777) == -1);
233
234 ATF_REQUIRE(unlink(path) == 0);
235}
236
237ATF_TC_CLEANUP(mkfifo_perm, tc)
238{
239 (void)unlink(path);
240}
241
242ATF_TC_WITH_CLEANUP(mkfifo_stat);
243ATF_TC_HEAD(mkfifo_stat, tc)
244{
245 atf_tc_set_md_var(tc, "descr", "Test mkfifo(2) with stat");
246}
247
248ATF_TC_BODY(mkfifo_stat, tc)
249{
250 struct stat st;
251
252 support();
253
254 (void)memset(&st, 0, sizeof(struct stat));
255
256 ATF_REQUIRE(mkfifo(path, 0600) == 0);
257 ATF_REQUIRE(stat(path, &st) == 0);
258
259 if (S_ISFIFO(st.st_mode) == 0)
260 atf_tc_fail("invalid mode from mkfifo(2)");
261
262 ATF_REQUIRE(unlink(path) == 0);
263}
264
265ATF_TC_CLEANUP(mkfifo_stat, tc)
266{
267 (void)unlink(path);
268}
269
270ATF_TC_WITH_CLEANUP(mknod_s_ififo);
271ATF_TC_HEAD(mknod_s_ififo, tc)
272{
273 atf_tc_set_md_var(tc, "descr", "Test mknod(2) with S_IFIFO");
274}
275
276ATF_TC_BODY(mknod_s_ififo, tc)
277{
278 struct stat st;
279
280 support();
281
282 (void)memset(&st, 0, sizeof(struct stat));
283
284 ATF_REQUIRE(mknod(path, S_IFIFO | 0600, 0) == 0);
285 ATF_REQUIRE(stat(path, &st) == 0);
286
287 if (S_ISFIFO(st.st_mode) == 0)
288 atf_tc_fail("invalid mode from mknod(2) with S_IFIFO");
289
290 ATF_REQUIRE(unlink(path) == 0);
291}
292
293ATF_TC_CLEANUP(mknod_s_ififo, tc)
294{
295 (void)unlink(path);
296}
297
298ATF_TP_ADD_TCS(tp)
299{
300
301 ATF_TP_ADD_TC(tp, mkfifo_block);
302 ATF_TP_ADD_TC(tp, mkfifo_err);
303 ATF_TP_ADD_TC(tp, mkfifo_nonblock);
304 ATF_TP_ADD_TC(tp, mkfifo_perm);
305 ATF_TP_ADD_TC(tp, mkfifo_stat);
306 ATF_TP_ADD_TC(tp, mknod_s_ififo);
307
308 return atf_no_error();
309}
diff --git a/src/regress/lib/libc/sys/t_mknod.c b/src/regress/lib/libc/sys/t_mknod.c
new file mode 100644
index 0000000000..0a16124859
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_mknod.c
@@ -0,0 +1,199 @@
1/* $OpenBSD: t_mknod.c,v 1.1.1.1 2019/11/19 19:57:03 bluhm Exp $ */
2/* $NetBSD: t_mknod.c,v 1.2 2012/03/18 07:00:52 jruoho Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_mknod.c,v 1.2 2012/03/18 07:00:52 jruoho Exp $");
37
38#include <sys/stat.h>
39
40#include "atf-c.h"
41#include <errno.h>
42#include <fcntl.h>
43#include <limits.h>
44#include <paths.h>
45#include <stdio.h>
46#include <string.h>
47#include <unistd.h>
48
49static char path[] = "node";
50
51ATF_TC_WITH_CLEANUP(mknod_err);
52ATF_TC_HEAD(mknod_err, tc)
53{
54 atf_tc_set_md_var(tc, "descr",
55 "Test error conditions of mknod(2) (PR kern/45111)");
56 atf_tc_set_md_var(tc, "require.user", "root");
57}
58
59ATF_TC_BODY(mknod_err, tc)
60{
61 char buf[PATH_MAX + 1];
62
63 (void)memset(buf, 'x', sizeof(buf));
64
65 errno = 0;
66 ATF_REQUIRE_ERRNO(EINVAL, mknod(path, S_IFCHR, -1) == -1);
67
68 errno = 0;
69 ATF_REQUIRE_ERRNO(ENAMETOOLONG, mknod(buf, S_IFCHR, 0) == -1);
70
71 errno = 0;
72 ATF_REQUIRE_ERRNO(EFAULT, mknod((char *)-1, S_IFCHR, 0) == -1);
73
74 errno = 0;
75 ATF_REQUIRE_ERRNO(ENOENT, mknod("/a/b/c/d/e/f/g", S_IFCHR, 0) == -1);
76}
77
78ATF_TC_CLEANUP(mknod_err, tc)
79{
80 (void)unlink(path);
81}
82
83ATF_TC_WITH_CLEANUP(mknod_exist);
84ATF_TC_HEAD(mknod_exist, tc)
85{
86 atf_tc_set_md_var(tc, "descr", "Test EEXIST from mknod(2)");
87 atf_tc_set_md_var(tc, "require.user", "root");
88}
89
90ATF_TC_BODY(mknod_exist, tc)
91{
92 int fd;
93
94 fd = open("/etc/passwd", O_RDONLY);
95
96 if (fd >= 0) {
97
98 (void)close(fd);
99
100 errno = 0;
101 ATF_REQUIRE_ERRNO(EEXIST,
102 mknod("/etc/passwd", S_IFCHR, 0) == -1);
103 }
104
105 ATF_REQUIRE(mknod(path, S_IFCHR, 0) == 0);
106
107 errno = 0;
108 ATF_REQUIRE_ERRNO(EEXIST, mknod(path, S_IFCHR, 0) == -1);
109
110 ATF_REQUIRE(unlink(path) == 0);
111}
112
113ATF_TC_CLEANUP(mknod_exist, tc)
114{
115 (void)unlink(path);
116}
117
118ATF_TC_WITH_CLEANUP(mknod_perm);
119ATF_TC_HEAD(mknod_perm, tc)
120{
121 atf_tc_set_md_var(tc, "descr", "Test permissions of mknod(2)");
122 atf_tc_set_md_var(tc, "require.user", "unprivileged");
123}
124
125ATF_TC_BODY(mknod_perm, tc)
126{
127
128 errno = 0;
129 ATF_REQUIRE_ERRNO(EPERM, mknod(path, S_IFCHR, 0) == -1);
130
131 errno = 0;
132 ATF_REQUIRE_ERRNO(EPERM, mknod(path, S_IFBLK, 0) == -1);
133}
134
135ATF_TC_CLEANUP(mknod_perm, tc)
136{
137 (void)unlink(path);
138}
139
140ATF_TC_WITH_CLEANUP(mknod_stat);
141ATF_TC_HEAD(mknod_stat, tc)
142{
143 atf_tc_set_md_var(tc, "descr", "A basic test of mknod(2)");
144 atf_tc_set_md_var(tc, "require.user", "root");
145}
146
147ATF_TC_BODY(mknod_stat, tc)
148{
149 struct stat st;
150
151 (void)memset(&st, 0, sizeof(struct stat));
152
153 ATF_REQUIRE(mknod(path, S_IFCHR, 0) == 0);
154 ATF_REQUIRE(stat(path, &st) == 0);
155
156 if (S_ISCHR(st.st_mode) == 0)
157 atf_tc_fail_nonfatal("invalid mode from mknod(2) (S_IFCHR)");
158
159 ATF_REQUIRE(unlink(path) == 0);
160
161 (void)memset(&st, 0, sizeof(struct stat));
162
163 ATF_REQUIRE(mknod(path, S_IFBLK, 0) == 0);
164 ATF_REQUIRE(stat(path, &st) == 0);
165
166 if (S_ISBLK(st.st_mode) == 0)
167 atf_tc_fail_nonfatal("invalid mode from mknod(2) (S_IFBLK)");
168
169 ATF_REQUIRE(unlink(path) == 0);
170
171 (void)memset(&st, 0, sizeof(struct stat));
172
173 /*
174 * Adjusted for OpenBSD, only supports FIFO and device special files
175 * ATF_REQUIRE(mknod(path, S_IFREG, 0) == 0);
176 * ATF_REQUIRE(stat(path, &st) == 0);
177 *
178 * if (S_ISREG(st.st_mode) == 0)
179 * atf_tc_fail_nonfatal("invalid mode from mknod(2) (S_IFREG)");
180 *
181 * ATF_REQUIRE(unlink(path) == 0);
182 */
183}
184
185ATF_TC_CLEANUP(mknod_stat, tc)
186{
187 (void)unlink(path);
188}
189
190ATF_TP_ADD_TCS(tp)
191{
192
193 ATF_TP_ADD_TC(tp, mknod_err);
194 ATF_TP_ADD_TC(tp, mknod_exist);
195 ATF_TP_ADD_TC(tp, mknod_perm);
196 ATF_TP_ADD_TC(tp, mknod_stat);
197
198 return atf_no_error();
199}
diff --git a/src/regress/lib/libc/sys/t_mlock.c b/src/regress/lib/libc/sys/t_mlock.c
new file mode 100644
index 0000000000..1fd986383d
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_mlock.c
@@ -0,0 +1,325 @@
1/* $OpenBSD: t_mlock.c,v 1.1.1.1 2019/11/19 19:57:04 bluhm Exp $ */
2/* $NetBSD: t_mlock.c,v 1.7 2019/03/13 08:50:12 kre Exp $ */
3
4/*-
5 * Copyright (c) 2012 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_mlock.c,v 1.7 2019/03/13 08:50:12 kre Exp $");
37
38#include <sys/mman.h>
39#include <sys/resource.h>
40#include <sys/sysctl.h>
41#include <sys/wait.h>
42
43#include <errno.h>
44#include "atf-c.h"
45#include <stdint.h>
46#include <stdio.h>
47#include <stdlib.h>
48#include <string.h>
49#include <unistd.h>
50
51static long page = 0;
52
53ATF_TC(mlock_clip);
54ATF_TC_HEAD(mlock_clip, tc)
55{
56 atf_tc_set_md_var(tc, "descr", "Test with mlock(2) that UVM only "
57 "clips if the clip address is within the entry (PR kern/44788)");
58}
59
60ATF_TC_BODY(mlock_clip, tc)
61{
62 void *buf;
63 int err1, err2;
64
65 buf = malloc(page);
66 ATF_REQUIRE(buf != NULL);
67 fprintf(stderr, "mlock_clip: buf = %p (page=%ld)\n", buf, page);
68
69 if (page < 1024)
70 atf_tc_skip("page size too small");
71
72 for (size_t i = page; i >= 1; i = i - 1024) {
73 err1 = mlock(buf, page - i);
74 if (err1 != 0)
75 fprintf(stderr, "mlock_clip: page=%ld i=%zu,"
76 " mlock(%p, %ld): %s\n", page, i, buf, page - i,
77 strerror(errno));
78 err2 = munlock(buf, page - i);
79 if (err2 != 0)
80 fprintf(stderr, "mlock_clip: page=%ld i=%zu,"
81 " munlock(%p, %ld): %s (mlock %s)\n", page, i,
82 buf, page - i, strerror(errno), err1?"failed":"ok");
83 }
84
85 free(buf);
86}
87
88ATF_TC(mlock_err);
89ATF_TC_HEAD(mlock_err, tc)
90{
91 atf_tc_set_md_var(tc, "descr",
92 "Test error conditions in mlock(2) and munlock(2)");
93}
94
95ATF_TC_BODY(mlock_err, tc)
96{
97 void *invalid_ptr;
98 void *buf;
99 int mlock_err, munlock_err;
100
101 /*
102 * Any bad address must return ENOMEM (for lock & unlock)
103 */
104 errno = 0;
105 ATF_REQUIRE_ERRNO(ENOMEM, mlock(NULL, page) == -1);
106
107 errno = 0;
108 ATF_REQUIRE_ERRNO(ENOMEM, mlock((char *)0, page) == -1);
109
110 errno = 0;
111 /* Adjusted for OpenBSD, initially ENOMEM */
112 ATF_REQUIRE_ERRNO(EINVAL, mlock((char *)-1, page) == -1);
113
114 errno = 0;
115 ATF_REQUIRE_ERRNO(ENOMEM, munlock(NULL, page) == -1);
116
117 errno = 0;
118 ATF_REQUIRE_ERRNO(ENOMEM, munlock((char *)0, page) == -1);
119
120 errno = 0;
121 /* Adjusted for OpenBSD, initially ENOMEM */
122 ATF_REQUIRE_ERRNO(EINVAL, munlock((char *)-1, page) == -1);
123
124 buf = malloc(page);
125 ATF_REQUIRE(buf != NULL);
126 fprintf(stderr, "mlock_err: buf = %p (page=%ld)\n", buf, page);
127
128 /*
129 * unlocking memory that is not locked is an error...
130 */
131
132 /*
133 * Adjusted for OpenBSD
134 * errno = 0;
135 * ATF_REQUIRE_ERRNO(ENOMEM, munlock(buf, page) == -1);
136 */
137
138 /*
139 * These are permitted to fail (EINVAL) but do not on NetBSD
140 */
141 mlock_err = mlock((void *)(((uintptr_t)buf) + page/3), page/5);
142 if (mlock_err != 0)
143 fprintf(stderr, "mlock_err: mlock(%p, %ld): %d [%d] %s\n",
144 (void *)(((uintptr_t)buf) + page/3), page/5, mlock_err,
145 errno, strerror(errno));
146 ATF_REQUIRE(mlock_err == 0);
147 munlock_err= munlock((void *)(((uintptr_t)buf) + page/3), page/5);
148 if (munlock_err != 0)
149 fprintf(stderr, "mlock_err: munlock(%p, %ld): %d [%d] %s\n",
150 (void *)(((uintptr_t)buf) + page/3), page/5, munlock_err,
151 errno, strerror(errno));
152 ATF_REQUIRE(munlock_err == 0);
153
154 (void)free(buf);
155
156 /*
157 * Try to create a pointer to an unmapped page - first after current
158 * brk will likely do.
159 */
160 invalid_ptr = (void*)(((uintptr_t)sbrk(0)+page) & ~(page-1));
161 printf("testing with (hopefully) invalid pointer %p\n", invalid_ptr);
162
163 errno = 0;
164 ATF_REQUIRE_ERRNO(ENOMEM, mlock(invalid_ptr, page) == -1);
165
166 errno = 0;
167 ATF_REQUIRE_ERRNO(ENOMEM, munlock(invalid_ptr, page) == -1);
168}
169
170ATF_TC(mlock_limits);
171ATF_TC_HEAD(mlock_limits, tc)
172{
173 atf_tc_set_md_var(tc, "descr", "Test system limits with mlock(2)");
174}
175
176ATF_TC_BODY(mlock_limits, tc)
177{
178 struct rlimit res;
179 void *buf;
180 pid_t pid;
181 int sta;
182
183 buf = malloc(page);
184 ATF_REQUIRE(buf != NULL);
185 fprintf(stderr, "mlock_limits: buf = %p (page=%ld)\n", buf, page);
186
187 pid = fork();
188 ATF_REQUIRE(pid >= 0);
189
190 if (pid == 0) {
191
192 for (ssize_t i = page; i >= 2; i -= 100) {
193
194 res.rlim_cur = i - 1;
195 res.rlim_max = i - 1;
196
197 (void)fprintf(stderr, "trying to lock %zu bytes "
198 "with %zu byte limit\n", i, (size_t)res.rlim_cur);
199
200 if (setrlimit(RLIMIT_MEMLOCK, &res) != 0)
201 _exit(EXIT_FAILURE);
202
203 errno = 0;
204
205 if ((sta = mlock(buf, i)) != -1 || errno != EAGAIN) {
206 fprintf(stderr, "mlock(%p, %zu): %d [%d] %s\n",
207 buf, i, sta, errno, strerror(errno));
208 (void)munlock(buf, i);
209 _exit(EXIT_FAILURE);
210 }
211 }
212
213 _exit(EXIT_SUCCESS);
214 }
215
216 (void)wait(&sta);
217
218 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
219 atf_tc_fail("mlock(2) locked beyond system limits");
220
221 free(buf);
222}
223
224ATF_TC(mlock_mmap);
225ATF_TC_HEAD(mlock_mmap, tc)
226{
227 atf_tc_set_md_var(tc, "descr", "Test mlock(2)-mmap(2) interaction");
228}
229
230ATF_TC_BODY(mlock_mmap, tc)
231{
232 /* Adjusted for OpenBSD, initially ... | MAP_WIRED */
233 static const int flags = MAP_ANON | MAP_PRIVATE;
234 void *buf;
235
236 /*
237 * Make a wired RW mapping and check that mlock(2)
238 * does not fail for the (already locked) mapping.
239 */
240 buf = mmap(NULL, page, PROT_READ | PROT_WRITE, flags, -1, 0);
241
242 if (buf == MAP_FAILED)
243 fprintf(stderr,
244 "mlock_mmap: mmap(NULL, %ld, %#x, %#x, -1, 0): MAP_FAILED"
245 " [%d] %s\n", page, PROT_READ | PROT_WRITE, flags, errno,
246 strerror(errno));
247
248 ATF_REQUIRE(buf != MAP_FAILED);
249
250 fprintf(stderr, "mlock_mmap: buf=%p, page=%ld\n", buf, page);
251
252 ATF_REQUIRE(mlock(buf, page) == 0);
253 ATF_REQUIRE(munlock(buf, page) == 0);
254 ATF_REQUIRE(munmap(buf, page) == 0);
255 ATF_REQUIRE(munlock(buf, page) != 0);
256
257 fprintf(stderr, "mlock_mmap: first test succeeded\n");
258
259 /*
260 * But it should be impossible to mlock(2) a PROT_NONE mapping.
261 */
262 buf = mmap(NULL, page, PROT_NONE, flags, -1, 0);
263
264 if (buf == MAP_FAILED)
265 fprintf(stderr,
266 "mlock_mmap: mmap(NULL, %ld, %#x, %#x, -1, 0): MAP_FAILED"
267 " [%d] %s\n", page, PROT_NONE, flags, errno,
268 strerror(errno));
269
270 ATF_REQUIRE(buf != MAP_FAILED);
271 ATF_REQUIRE(mlock(buf, page) != 0);
272 ATF_REQUIRE(munmap(buf, page) == 0);
273
274 fprintf(stderr, "mlock_mmap: second test succeeded\n");
275}
276
277ATF_TC(mlock_nested);
278ATF_TC_HEAD(mlock_nested, tc)
279{
280 atf_tc_set_md_var(tc, "descr",
281 "Test that consecutive mlock(2) calls succeed");
282}
283
284ATF_TC_BODY(mlock_nested, tc)
285{
286 const size_t maxiter = 100;
287 void *buf;
288 int err;
289
290 buf = malloc(page);
291 ATF_REQUIRE(buf != NULL);
292 fprintf(stderr, "mlock_nested: buf = %p (page=%ld)\n", buf, page);
293
294 for (size_t i = 0; i < maxiter; i++) {
295 err = mlock(buf, page);
296 if (err != 0)
297 fprintf(stderr,
298 "mlock_nested: i=%zu (of %zu) mlock(%p, %ld): %d [%d] %s\n",
299 i, maxiter, buf, page, err, errno, strerror(errno));
300 ATF_REQUIRE(err == 0);
301 }
302
303 err = munlock(buf, page);
304 if (err != 0)
305 fprintf(stderr, "mlock_nested: munlock(%p, %ld): %d [%d] %s\n",
306 buf, page, err, errno, strerror(errno));
307 ATF_REQUIRE(err == 0);
308 free(buf);
309}
310
311ATF_TP_ADD_TCS(tp)
312{
313
314 page = sysconf(_SC_PAGESIZE);
315 fprintf(stderr, "t_mlock: pagesize %ld\n", page);
316 ATF_REQUIRE(page >= 0);
317
318 ATF_TP_ADD_TC(tp, mlock_clip);
319 ATF_TP_ADD_TC(tp, mlock_err);
320 ATF_TP_ADD_TC(tp, mlock_limits);
321 ATF_TP_ADD_TC(tp, mlock_mmap);
322 ATF_TP_ADD_TC(tp, mlock_nested);
323
324 return atf_no_error();
325}
diff --git a/src/regress/lib/libc/sys/t_mmap.c b/src/regress/lib/libc/sys/t_mmap.c
new file mode 100644
index 0000000000..6dbfae5bb1
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_mmap.c
@@ -0,0 +1,584 @@
1/* $OpenBSD: t_mmap.c,v 1.1.1.1 2019/11/19 19:57:04 bluhm Exp $ */
2/* $NetBSD: t_mmap.c,v 1.13 2017/05/23 13:04:29 christos Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33/*-
34 * Copyright (c)2004 YAMAMOTO Takashi,
35 * All rights reserved.
36 *
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
39 * are met:
40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution.
45 *
46 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
50 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56 * SUCH DAMAGE.
57 */
58
59#include "macros.h"
60
61#include <sys/cdefs.h>
62__RCSID("$NetBSD: t_mmap.c,v 1.13 2017/05/23 13:04:29 christos Exp $");
63
64#include <sys/param.h>
65#include <sys/disklabel.h>
66#include <sys/mman.h>
67#include <sys/stat.h>
68#include <sys/socket.h>
69#include <sys/sysctl.h>
70#include <sys/wait.h>
71
72#include "atf-c.h"
73#include <errno.h>
74#include <fcntl.h>
75#include <signal.h>
76#include <stdio.h>
77#include <stdlib.h>
78#include <string.h>
79#include <unistd.h>
80#include <paths.h>
81
82static long page = 0;
83static char path[] = "mmap";
84static void map_check(void *, int);
85static void map_sighandler(int);
86static void testloan(void *, void *, char, int);
87
88#define BUFSIZE (32 * 1024) /* enough size to trigger sosend_loan */
89
90static void
91map_check(void *map, int flag)
92{
93
94 if (flag != 0) {
95 ATF_REQUIRE(map == MAP_FAILED);
96 return;
97 }
98
99 ATF_REQUIRE(map != MAP_FAILED);
100 ATF_REQUIRE(munmap(map, page) == 0);
101}
102
103void
104testloan(void *vp, void *vp2, char pat, int docheck)
105{
106 char buf[BUFSIZE];
107 char backup[BUFSIZE];
108 ssize_t nwritten;
109 ssize_t nread;
110 int fds[2];
111 int val;
112
113 val = BUFSIZE;
114
115 if (docheck != 0)
116 (void)memcpy(backup, vp, BUFSIZE);
117
118 if (socketpair(AF_LOCAL, SOCK_STREAM, PF_UNSPEC, fds) != 0)
119 atf_tc_fail("socketpair() failed");
120
121 val = BUFSIZE;
122
123 if (setsockopt(fds[1], SOL_SOCKET, SO_RCVBUF, &val, sizeof(val)) != 0)
124 atf_tc_fail("setsockopt() failed, SO_RCVBUF");
125
126 val = BUFSIZE;
127
128 if (setsockopt(fds[0], SOL_SOCKET, SO_SNDBUF, &val, sizeof(val)) != 0)
129 atf_tc_fail("setsockopt() failed, SO_SNDBUF");
130
131 if (fcntl(fds[0], F_SETFL, O_NONBLOCK) != 0)
132 atf_tc_fail("fcntl() failed");
133
134 nwritten = write(fds[0], (char *)vp + page, BUFSIZE - page);
135
136 if (nwritten == -1)
137 atf_tc_fail("write() failed");
138
139 /* Break loan. */
140 (void)memset(vp2, pat, BUFSIZE);
141
142 nread = read(fds[1], buf + page, BUFSIZE - page);
143
144 if (nread == -1)
145 atf_tc_fail("read() failed");
146
147 if (nread != nwritten)
148 atf_tc_fail("too short read");
149
150 if (docheck != 0 && memcmp(backup, buf + page, nread) != 0)
151 atf_tc_fail("data mismatch");
152
153 ATF_REQUIRE(close(fds[0]) == 0);
154 ATF_REQUIRE(close(fds[1]) == 0);
155}
156
157static void
158map_sighandler(int signo)
159{
160 _exit(signo);
161}
162
163ATF_TC(mmap_block);
164ATF_TC_HEAD(mmap_block, tc)
165{
166 atf_tc_set_md_var(tc, "descr", "Test mmap(2) with a block device");
167 atf_tc_set_md_var(tc, "require.user", "root");
168}
169
170ATF_TC_BODY(mmap_block, tc)
171{
172 static const int mib[] = { CTL_HW, HW_DISKNAMES };
173 static const unsigned int miblen = __arraycount(mib);
174 char *map, *dk, *drives, dev[PATH_MAX];
175 size_t len;
176 int fd = -1;
177
178 atf_tc_skip("The test case causes a panic (PR kern/38889, kern/46592)");
179
180 ATF_REQUIRE(sysctl(mib, miblen, NULL, &len, NULL, 0) == 0);
181 drives = malloc(len);
182 ATF_REQUIRE(drives != NULL);
183 ATF_REQUIRE(sysctl(mib, miblen, drives, &len, NULL, 0) == 0);
184 for (dk = strtok(drives, " "); dk != NULL; dk = strtok(NULL, " ")) {
185 if (strncmp(dk, "dk", 2) == 0)
186 snprintf(dev, sizeof(dev), _PATH_DEV "%s", dk);
187 else
188 snprintf(dev, sizeof(dev), _PATH_DEV "%s%c", dk,
189 'a' + RAW_PART);
190 fprintf(stderr, "trying: %s\n", dev);
191
192 if ((fd = open(dev, O_RDONLY)) >= 0) {
193 (void)fprintf(stderr, "using %s\n", dev);
194 break;
195 } else
196 (void)fprintf(stderr, "%s: %s\n", dev, strerror(errno));
197 }
198 free(drives);
199
200 if (fd < 0)
201 atf_tc_skip("failed to find suitable block device");
202
203 map = mmap(NULL, 4096, PROT_READ, MAP_FILE, fd, 0);
204 ATF_REQUIRE_MSG(map != MAP_FAILED, "mmap: %s", strerror(errno));
205
206 (void)fprintf(stderr, "first byte %x\n", *map);
207 ATF_REQUIRE(close(fd) == 0);
208 (void)fprintf(stderr, "first byte %x\n", *map);
209
210 ATF_REQUIRE(munmap(map, 4096) == 0);
211}
212
213ATF_TC(mmap_err);
214ATF_TC_HEAD(mmap_err, tc)
215{
216 atf_tc_set_md_var(tc, "descr", "Test error conditions of mmap(2)");
217}
218
219ATF_TC_BODY(mmap_err, tc)
220{
221 size_t addr = SIZE_MAX;
222 void *map;
223
224 errno = 0;
225 map = mmap(NULL, 3, PROT_READ, MAP_FILE|MAP_PRIVATE, -1, 0);
226
227 ATF_REQUIRE(map == MAP_FAILED);
228 ATF_REQUIRE(errno == EBADF);
229
230 errno = 0;
231 map = mmap(&addr, page, PROT_READ, MAP_FIXED|MAP_PRIVATE, -1, 0);
232
233 ATF_REQUIRE(map == MAP_FAILED);
234 ATF_REQUIRE(errno == EINVAL);
235
236 errno = 0;
237 map = mmap(NULL, page, PROT_READ, MAP_ANON|MAP_PRIVATE, INT_MAX, 0);
238
239 ATF_REQUIRE(map == MAP_FAILED);
240 ATF_REQUIRE(errno == EINVAL);
241}
242
243ATF_TC_WITH_CLEANUP(mmap_loan);
244ATF_TC_HEAD(mmap_loan, tc)
245{
246 atf_tc_set_md_var(tc, "descr", "Test uvm page loanout with mmap(2)");
247}
248
249ATF_TC_BODY(mmap_loan, tc)
250{
251 char buf[BUFSIZE];
252 char *vp, *vp2;
253 int fd;
254
255 fd = open(path, O_RDWR | O_CREAT, 0600);
256 ATF_REQUIRE(fd >= 0);
257
258 (void)memset(buf, 'x', sizeof(buf));
259 (void)write(fd, buf, sizeof(buf));
260
261 vp = mmap(NULL, BUFSIZE, PROT_READ | PROT_WRITE,
262 MAP_FILE | MAP_PRIVATE, fd, 0);
263
264 ATF_REQUIRE(vp != MAP_FAILED);
265
266 vp2 = vp;
267
268 testloan(vp, vp2, 'A', 0);
269 testloan(vp, vp2, 'B', 1);
270
271 ATF_REQUIRE(munmap(vp, BUFSIZE) == 0);
272
273 vp = mmap(NULL, BUFSIZE, PROT_READ | PROT_WRITE,
274 MAP_FILE | MAP_SHARED, fd, 0);
275
276 vp2 = mmap(NULL, BUFSIZE, PROT_READ | PROT_WRITE,
277 MAP_FILE | MAP_SHARED, fd, 0);
278
279 ATF_REQUIRE(vp != MAP_FAILED);
280 ATF_REQUIRE(vp2 != MAP_FAILED);
281
282 testloan(vp, vp2, 'E', 1);
283
284 ATF_REQUIRE(munmap(vp, BUFSIZE) == 0);
285 ATF_REQUIRE(munmap(vp2, BUFSIZE) == 0);
286}
287
288ATF_TC_CLEANUP(mmap_loan, tc)
289{
290 (void)unlink(path);
291}
292
293ATF_TC_WITH_CLEANUP(mmap_prot_1);
294ATF_TC_HEAD(mmap_prot_1, tc)
295{
296 atf_tc_set_md_var(tc, "descr", "Test mmap(2) protections, #1");
297}
298
299ATF_TC_BODY(mmap_prot_1, tc)
300{
301 void *map;
302 int fd;
303
304 /*
305 * Open a file write-only and try to
306 * map it read-only. This should fail.
307 */
308 fd = open(path, O_WRONLY | O_CREAT, 0700);
309
310 if (fd < 0)
311 return;
312
313 ATF_REQUIRE(write(fd, "XXX", 3) == 3);
314
315 map = mmap(NULL, 3, PROT_READ, MAP_FILE|MAP_PRIVATE, fd, 0);
316 map_check(map, 1);
317
318 map = mmap(NULL, 3, PROT_WRITE, MAP_FILE|MAP_PRIVATE, fd, 0);
319 map_check(map, 0);
320
321 ATF_REQUIRE(close(fd) == 0);
322}
323
324ATF_TC_CLEANUP(mmap_prot_1, tc)
325{
326 (void)unlink(path);
327}
328
329ATF_TC(mmap_prot_2);
330ATF_TC_HEAD(mmap_prot_2, tc)
331{
332 atf_tc_set_md_var(tc, "descr", "Test mmap(2) protections, #2");
333}
334
335ATF_TC_BODY(mmap_prot_2, tc)
336{
337 char buf[2];
338 void *map;
339 pid_t pid;
340 int sta;
341
342 /*
343 * Make a PROT_NONE mapping and try to access it.
344 * If we catch a SIGSEGV, all works as expected.
345 */
346 map = mmap(NULL, page, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
347 ATF_REQUIRE(map != MAP_FAILED);
348
349 pid = fork();
350 ATF_REQUIRE(pid >= 0);
351
352 if (pid == 0) {
353 ATF_REQUIRE(signal(SIGSEGV, map_sighandler) != SIG_ERR);
354 ATF_REQUIRE(strlcpy(buf, map, sizeof(buf)) != 0);
355 }
356
357 (void)wait(&sta);
358
359 ATF_REQUIRE(WIFEXITED(sta) != 0);
360 ATF_REQUIRE(WEXITSTATUS(sta) == SIGSEGV);
361 ATF_REQUIRE(munmap(map, page) == 0);
362}
363
364ATF_TC_WITH_CLEANUP(mmap_prot_3);
365ATF_TC_HEAD(mmap_prot_3, tc)
366{
367 atf_tc_set_md_var(tc, "descr", "Test mmap(2) protections, #3");
368}
369
370ATF_TC_BODY(mmap_prot_3, tc)
371{
372 char buf[2];
373 int fd, sta;
374 void *map;
375 pid_t pid;
376
377 /*
378 * Open a file, change the permissions
379 * to read-only, and try to map it as
380 * PROT_NONE. This should succeed, but
381 * the access should generate SIGSEGV.
382 */
383 fd = open(path, O_RDWR | O_CREAT, 0700);
384
385 if (fd < 0)
386 return;
387
388 ATF_REQUIRE(write(fd, "XXX", 3) == 3);
389 ATF_REQUIRE(close(fd) == 0);
390 ATF_REQUIRE(chmod(path, 0444) == 0);
391
392 fd = open(path, O_RDONLY);
393 ATF_REQUIRE(fd != -1);
394
395 map = mmap(NULL, 3, PROT_NONE, MAP_FILE | MAP_SHARED, fd, 0);
396 ATF_REQUIRE(map != MAP_FAILED);
397
398 pid = fork();
399
400 ATF_REQUIRE(pid >= 0);
401
402 if (pid == 0) {
403 ATF_REQUIRE(signal(SIGSEGV, map_sighandler) != SIG_ERR);
404 ATF_REQUIRE(strlcpy(buf, map, sizeof(buf)) != 0);
405 }
406
407 (void)wait(&sta);
408
409 ATF_REQUIRE(WIFEXITED(sta) != 0);
410 ATF_REQUIRE(WEXITSTATUS(sta) == SIGSEGV);
411 ATF_REQUIRE(munmap(map, 3) == 0);
412}
413
414ATF_TC_CLEANUP(mmap_prot_3, tc)
415{
416 (void)unlink(path);
417}
418
419ATF_TC_WITH_CLEANUP(mmap_truncate);
420ATF_TC_HEAD(mmap_truncate, tc)
421{
422 atf_tc_set_md_var(tc, "descr", "Test mmap(2) and ftruncate(2)");
423}
424
425ATF_TC_BODY(mmap_truncate, tc)
426{
427 char *map;
428 long i;
429 int fd;
430
431 fd = open(path, O_RDWR | O_CREAT, 0700);
432
433 if (fd < 0)
434 return;
435
436 /*
437 * See that ftruncate(2) works
438 * while the file is mapped.
439 */
440 ATF_REQUIRE(ftruncate(fd, page) == 0);
441
442 map = mmap(NULL, page, PROT_READ | PROT_WRITE, MAP_FILE|MAP_PRIVATE,
443 fd, 0);
444 ATF_REQUIRE(map != MAP_FAILED);
445
446 for (i = 0; i < page; i++)
447 map[i] = 'x';
448
449 ATF_REQUIRE(ftruncate(fd, 0) == 0);
450 ATF_REQUIRE(ftruncate(fd, page / 8) == 0);
451 ATF_REQUIRE(ftruncate(fd, page / 4) == 0);
452 ATF_REQUIRE(ftruncate(fd, page / 2) == 0);
453 ATF_REQUIRE(ftruncate(fd, page / 12) == 0);
454 ATF_REQUIRE(ftruncate(fd, page / 64) == 0);
455
456 (void)munmap(map, page);
457 ATF_REQUIRE(close(fd) == 0);
458}
459
460ATF_TC_CLEANUP(mmap_truncate, tc)
461{
462 (void)unlink(path);
463}
464
465ATF_TC_WITH_CLEANUP(mmap_truncate_signal);
466ATF_TC_HEAD(mmap_truncate_signal, tc)
467{
468 atf_tc_set_md_var(tc, "descr",
469 "Test mmap(2) ftruncate(2) causing signal");
470}
471
472ATF_TC_BODY(mmap_truncate_signal, tc)
473{
474 char *map;
475 long i;
476 int fd, sta;
477 pid_t pid;
478
479 fd = open(path, O_RDWR | O_CREAT, 0700);
480
481 if (fd < 0)
482 return;
483
484 ATF_REQUIRE(write(fd, "foo\n", 5) == 5);
485
486 map = mmap(NULL, page, PROT_READ, MAP_FILE|MAP_PRIVATE, fd, 0);
487 ATF_REQUIRE(map != MAP_FAILED);
488
489 sta = 0;
490 for (i = 0; i < 5; i++)
491 sta += map[i];
492 ATF_REQUIRE(sta == 334);
493
494 ATF_REQUIRE(ftruncate(fd, 0) == 0);
495 pid = fork();
496 ATF_REQUIRE(pid >= 0);
497
498 if (pid == 0) {
499 ATF_REQUIRE(signal(SIGBUS, map_sighandler) != SIG_ERR);
500 ATF_REQUIRE(signal(SIGSEGV, map_sighandler) != SIG_ERR);
501 sta = 0;
502 for (i = 0; i < page; i++)
503 sta += map[i];
504 /* child never will get this far, but the compiler will
505 not know, so better use the values calculated to
506 prevent the access to be optimized out */
507 ATF_REQUIRE(i == 0);
508 ATF_REQUIRE(sta == 0);
509 (void)munmap(map, page);
510 (void)close(fd);
511 return;
512 }
513
514 (void)wait(&sta);
515
516 ATF_REQUIRE(WIFEXITED(sta) != 0);
517 if (WEXITSTATUS(sta) == SIGSEGV)
518 atf_tc_fail("child process got SIGSEGV instead of SIGBUS");
519 ATF_REQUIRE(WEXITSTATUS(sta) == SIGBUS);
520 ATF_REQUIRE(munmap(map, page) == 0);
521 ATF_REQUIRE(close(fd) == 0);
522}
523
524ATF_TC_CLEANUP(mmap_truncate_signal, tc)
525{
526 (void)unlink(path);
527}
528
529ATF_TC(mmap_va0);
530ATF_TC_HEAD(mmap_va0, tc)
531{
532 atf_tc_set_md_var(tc, "descr", "Test mmap(2) and vm.user_va0_disable");
533}
534
535ATF_TC_BODY(mmap_va0, tc)
536{
537 int flags = MAP_ANON | MAP_FIXED | MAP_PRIVATE;
538 size_t len = sizeof(int);
539 void *map;
540 int val;
541
542 /*
543 * Make an anonymous fixed mapping at zero address. If the address
544 * is restricted as noted in security(7), the syscall should fail.
545 */
546 if (sysctlbyname("vm.user_va0_disable", &val, &len, NULL, 0) != 0)
547 atf_tc_fail("failed to read vm.user_va0_disable");
548
549 map = mmap(NULL, page, PROT_EXEC, flags, -1, 0);
550 map_check(map, val);
551
552 map = mmap(NULL, page, PROT_READ, flags, -1, 0);
553 map_check(map, val);
554
555 map = mmap(NULL, page, PROT_WRITE, flags, -1, 0);
556 map_check(map, val);
557
558 map = mmap(NULL, page, PROT_READ|PROT_WRITE, flags, -1, 0);
559 map_check(map, val);
560
561 map = mmap(NULL, page, PROT_EXEC|PROT_READ|PROT_WRITE, flags, -1, 0);
562 map_check(map, val);
563}
564
565ATF_TP_ADD_TCS(tp)
566{
567 page = sysconf(_SC_PAGESIZE);
568 ATF_REQUIRE(page >= 0);
569
570 ATF_TP_ADD_TC(tp, mmap_block);
571 ATF_TP_ADD_TC(tp, mmap_err);
572 ATF_TP_ADD_TC(tp, mmap_loan);
573 ATF_TP_ADD_TC(tp, mmap_prot_1);
574 ATF_TP_ADD_TC(tp, mmap_prot_2);
575 ATF_TP_ADD_TC(tp, mmap_prot_3);
576 ATF_TP_ADD_TC(tp, mmap_truncate);
577 ATF_TP_ADD_TC(tp, mmap_truncate_signal);
578 /*
579 * Adjusted for OpenBSD, not available
580 * ATF_TP_ADD_TC(tp, mmap_va0);
581 */
582
583 return atf_no_error();
584}
diff --git a/src/regress/lib/libc/sys/t_msgctl.c b/src/regress/lib/libc/sys/t_msgctl.c
new file mode 100644
index 0000000000..980f11ee0b
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_msgctl.c
@@ -0,0 +1,405 @@
1/* $OpenBSD: t_msgctl.c,v 1.1.1.1 2019/11/19 19:57:04 bluhm Exp $ */
2/* $NetBSD: t_msgctl.c,v 1.7 2017/10/07 17:15:44 kre Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_msgctl.c,v 1.7 2017/10/07 17:15:44 kre Exp $");
37
38#include <sys/msg.h>
39#include <sys/stat.h>
40#include <sys/sysctl.h>
41#include <sys/wait.h>
42
43#include "atf-c.h"
44#include <errno.h>
45#include <limits.h>
46#include <pwd.h>
47#include <signal.h>
48#include <stdio.h>
49#include <stdlib.h>
50#include <string.h>
51#include <sysexits.h>
52#include <time.h>
53#include <unistd.h>
54
55#define MSG_KEY 12345689
56#define MSG_MTYPE_1 0x41
57
58struct msg {
59 long mtype;
60 char buf[3];
61};
62
63static void clean(void);
64
65static void
66clean(void)
67{
68 int id;
69
70 if ((id = msgget(MSG_KEY, 0)) != -1)
71 (void)msgctl(id, IPC_RMID, 0);
72}
73
74ATF_TC_WITH_CLEANUP(msgctl_err);
75ATF_TC_HEAD(msgctl_err, tc)
76{
77 atf_tc_set_md_var(tc, "descr", "Test errors from msgctl(2)");
78}
79
80ATF_TC_BODY(msgctl_err, tc)
81{
82 const int cmd[] = { IPC_STAT, IPC_SET, IPC_RMID };
83 struct msqid_ds msgds;
84 size_t i;
85 int id;
86
87 (void)memset(&msgds, 0, sizeof(struct msqid_ds));
88
89 id = msgget(MSG_KEY, IPC_CREAT | 0600);
90 ATF_REQUIRE(id != -1);
91
92 errno = 0;
93 ATF_REQUIRE_ERRNO(EINVAL, msgctl(id, INT_MAX, &msgds) == -1);
94
95 errno = 0;
96 ATF_REQUIRE_ERRNO(EFAULT, msgctl(id, IPC_STAT, (void *)-1) == -1);
97
98 for (i = 0; i < __arraycount(cmd); i++) {
99 errno = 0;
100 ATF_REQUIRE_ERRNO(EINVAL, msgctl(-1, cmd[i], &msgds) == -1);
101 }
102
103 ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
104}
105
106ATF_TC_CLEANUP(msgctl_err, tc)
107{
108 clean();
109}
110
111ATF_TC_WITH_CLEANUP(msgctl_perm);
112ATF_TC_HEAD(msgctl_perm, tc)
113{
114 atf_tc_set_md_var(tc, "descr", "Test permissions with msgctl(2)");
115 atf_tc_set_md_var(tc, "require.user", "root");
116}
117
118ATF_TC_BODY(msgctl_perm, tc)
119{
120 struct msqid_ds msgds;
121 struct passwd *pw;
122 pid_t pid;
123 int sta;
124 int id;
125
126 (void)memset(&msgds, 0, sizeof(struct msqid_ds));
127
128 pw = getpwnam("nobody");
129 id = msgget(MSG_KEY, IPC_CREAT | 0600);
130
131 ATF_REQUIRE(id != -1);
132 ATF_REQUIRE(pw != NULL);
133 ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0);
134
135 pid = fork();
136 ATF_REQUIRE(pid >= 0);
137
138 if (pid == 0) {
139
140 if (setuid(pw->pw_uid) != 0)
141 _exit(EX_OSERR);
142
143 msgds.msg_perm.uid = getuid();
144 msgds.msg_perm.gid = getgid();
145
146 errno = 0;
147
148 if (msgctl(id, IPC_SET, &msgds) == 0)
149 _exit(EXIT_FAILURE);
150
151 if (errno != EPERM)
152 _exit(EXIT_FAILURE);
153
154 (void)memset(&msgds, 0, sizeof(struct msqid_ds));
155
156 if (msgctl(id, IPC_STAT, &msgds) != 0)
157 _exit(EX_OSERR);
158
159 msgds.msg_qbytes = 1;
160
161 if (msgctl(id, IPC_SET, &msgds) == 0)
162 _exit(EXIT_FAILURE);
163
164 if (errno != EPERM)
165 _exit(EXIT_FAILURE);
166
167 _exit(EXIT_SUCCESS);
168 }
169
170 (void)wait(&sta);
171
172 if (WIFEXITED(sta) == 0) {
173
174 if (WEXITSTATUS(sta) == EX_OSERR)
175 atf_tc_fail("system call failed");
176
177 if (WEXITSTATUS(sta) == EXIT_FAILURE)
178 atf_tc_fail("UID %u manipulated root's "
179 "message queue", pw->pw_uid);
180 }
181
182 ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
183}
184
185ATF_TC_CLEANUP(msgctl_perm, tc)
186{
187 clean();
188}
189
190ATF_TC_WITH_CLEANUP(msgctl_pid);
191ATF_TC_HEAD(msgctl_pid, tc)
192{
193 atf_tc_set_md_var(tc, "descr", "Test that PIDs are updated");
194}
195
196ATF_TC_BODY(msgctl_pid, tc)
197{
198 struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
199 struct msqid_ds msgds;
200 int id, sta;
201 pid_t pid;
202
203 id = msgget(MSG_KEY, IPC_CREAT | 0600);
204 ATF_REQUIRE(id != -1);
205
206 pid = fork();
207 ATF_REQUIRE(pid >= 0);
208
209 if (pid == 0) {
210
211 (void)msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT);
212
213 _exit(EXIT_SUCCESS);
214 }
215
216 (void)sleep(1);
217 (void)wait(&sta);
218 (void)memset(&msgds, 0, sizeof(struct msqid_ds));
219
220 ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0);
221
222 if (pid != msgds.msg_lspid)
223 atf_tc_fail("the PID of last msgsnd(2) was not updated");
224
225 pid = fork();
226 ATF_REQUIRE(pid >= 0);
227
228 if (pid == 0) {
229
230 (void)msgrcv(id, &msg,
231 sizeof(struct msg), MSG_MTYPE_1, IPC_NOWAIT);
232
233 _exit(EXIT_SUCCESS);
234 }
235
236 (void)sleep(1);
237 (void)wait(&sta);
238 (void)memset(&msgds, 0, sizeof(struct msqid_ds));
239
240 ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0);
241
242 if (pid != msgds.msg_lrpid)
243 atf_tc_fail("the PID of last msgrcv(2) was not updated");
244
245 ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
246}
247
248ATF_TC_CLEANUP(msgctl_pid, tc)
249{
250 clean();
251}
252
253ATF_TC_WITH_CLEANUP(msgctl_set);
254ATF_TC_HEAD(msgctl_set, tc)
255{
256 atf_tc_set_md_var(tc, "descr", "Test msgctl(2) with IPC_SET");
257 atf_tc_set_md_var(tc, "require.user", "root");
258}
259
260ATF_TC_BODY(msgctl_set, tc)
261{
262 struct msqid_ds msgds;
263 struct passwd *pw;
264 int id;
265
266 (void)memset(&msgds, 0, sizeof(struct msqid_ds));
267
268 pw = getpwnam("nobody");
269 id = msgget(MSG_KEY, IPC_CREAT | 0600);
270
271 ATF_REQUIRE(id != -1);
272 ATF_REQUIRE(pw != NULL);
273 ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0);
274
275 msgds.msg_perm.uid = pw->pw_uid;
276
277 if (msgctl(id, IPC_SET, &msgds) != 0)
278 atf_tc_fail("root failed to change the UID of message queue");
279
280 msgds.msg_perm.uid = getuid();
281 msgds.msg_perm.gid = pw->pw_gid;
282
283 if (msgctl(id, IPC_SET, &msgds) != 0)
284 atf_tc_fail("root failed to change the GID of message queue");
285
286 /*
287 * Note: setting the qbytes to zero fails even as root.
288 */
289 msgds.msg_qbytes = 1;
290 msgds.msg_perm.gid = getgid();
291
292 if (msgctl(id, IPC_SET, &msgds) != 0)
293 atf_tc_fail("root failed to change qbytes of message queue");
294
295 ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
296}
297
298ATF_TC_CLEANUP(msgctl_set, tc)
299{
300 clean();
301}
302
303ATF_TC_WITH_CLEANUP(msgctl_time);
304ATF_TC_HEAD(msgctl_time, tc)
305{
306 atf_tc_set_md_var(tc, "descr", "Test that access times are updated");
307}
308
309ATF_TC_BODY(msgctl_time, tc)
310{
311 struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
312 struct msqid_ds msgds;
313 time_t t;
314 int id;
315
316 id = msgget(MSG_KEY, IPC_CREAT | 0600);
317 ATF_REQUIRE(id != -1);
318
319 t = time(NULL);
320
321 (void)memset(&msgds, 0, sizeof(struct msqid_ds));
322 (void)msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT);
323 (void)msgctl(id, IPC_STAT, &msgds);
324
325 if (llabs(t - msgds.msg_stime) > 1)
326 atf_tc_fail("time of last msgsnd(2) was not updated");
327
328 if (msgds.msg_rtime != 0)
329 atf_tc_fail("time of last msgrcv(2) was updated incorrectly");
330
331 t = time(NULL);
332
333 (void)memset(&msgds, 0, sizeof(struct msqid_ds));
334 (void)msgrcv(id, &msg, sizeof(struct msg), MSG_MTYPE_1, IPC_NOWAIT);
335 (void)msgctl(id, IPC_STAT, &msgds);
336
337 if (llabs(t - msgds.msg_rtime) > 1)
338 atf_tc_fail("time of last msgrcv(2) was not updated");
339
340 /*
341 * Note: this is non-zero even after the memset(3).
342 */
343 if (msgds.msg_stime == 0)
344 atf_tc_fail("time of last msgsnd(2) was updated incorrectly");
345
346 ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
347}
348
349ATF_TC_CLEANUP(msgctl_time, tc)
350{
351 clean();
352}
353
354static volatile int sig_caught;
355
356static void
357sigsys_handler(int signum)
358{
359
360 sig_caught = signum;
361}
362
363static int
364no_kernel_sysvmsg(void)
365{
366 int id;
367 void (*osig)(int);
368
369 sig_caught = 0;
370 osig = signal(SIGSYS, sigsys_handler);
371 id = msgget(MSG_KEY, IPC_CREAT | 0600);
372 if (sig_caught || id == -1)
373 return 1;
374
375 (void)msgctl(id, IPC_RMID, 0);
376 (void)signal(SIGSYS, osig);
377
378 return 0;
379}
380
381ATF_TC(msgctl_query);
382ATF_TC_HEAD(msgctl_query, tc)
383{
384 atf_tc_set_md_var(tc, "descr", "Skip msgctl_* tests - no SYSVMSG");
385}
386ATF_TC_BODY(msgctl_query, tc)
387{
388 atf_tc_skip("No SYSVMSG in kernel");
389}
390
391ATF_TP_ADD_TCS(tp)
392{
393
394 if (no_kernel_sysvmsg()) {
395 ATF_TP_ADD_TC(tp, msgctl_query);
396 } else {
397 ATF_TP_ADD_TC(tp, msgctl_err);
398 ATF_TP_ADD_TC(tp, msgctl_perm);
399 ATF_TP_ADD_TC(tp, msgctl_pid);
400 ATF_TP_ADD_TC(tp, msgctl_set);
401 ATF_TP_ADD_TC(tp, msgctl_time);
402 }
403
404 return atf_no_error();
405}
diff --git a/src/regress/lib/libc/sys/t_msgget.c b/src/regress/lib/libc/sys/t_msgget.c
new file mode 100644
index 0000000000..2a9bb4cf3b
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_msgget.c
@@ -0,0 +1,339 @@
1/* $OpenBSD: t_msgget.c,v 1.1.1.1 2019/11/19 19:57:04 bluhm Exp $ */
2/* $NetBSD: t_msgget.c,v 1.3 2017/10/08 08:31:05 kre Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_msgget.c,v 1.3 2017/10/08 08:31:05 kre Exp $");
37
38#include <sys/msg.h>
39#include <sys/stat.h>
40#include <sys/sysctl.h>
41#include <sys/wait.h>
42
43#include "atf-c.h"
44#include <errno.h>
45#include <pwd.h>
46#include <stdio.h>
47#include <stdlib.h>
48#include <string.h>
49#include <sysexits.h>
50#include <time.h>
51#include <unistd.h>
52
53#define MSG_KEY 12345689
54
55static void clean(void);
56
57static void
58clean(void)
59{
60 int id;
61
62 if ((id = msgget(MSG_KEY, 0)) != -1)
63 (void)msgctl(id, IPC_RMID, 0);
64}
65
66ATF_TC_WITH_CLEANUP(msgget_excl);
67ATF_TC_HEAD(msgget_excl, tc)
68{
69 atf_tc_set_md_var(tc, "descr", "Test msgget(2) with IPC_EXCL");
70}
71
72ATF_TC_BODY(msgget_excl, tc)
73{
74 int id;
75
76 /*
77 * Create a message queue and re-open it with
78 * O_CREAT and IPC_EXCL set. This should fail.
79 */
80 id = msgget(MSG_KEY, IPC_CREAT | 0600);
81
82 if (id < 0)
83 atf_tc_fail("failed to create message queue");
84
85 errno = 0;
86
87 if (msgget(MSG_KEY, IPC_CREAT | IPC_EXCL | 0600) != -1)
88 atf_tc_fail("msgget(2) failed for IPC_EXCL");
89
90 ATF_REQUIRE(errno == EEXIST);
91
92 /*
93 * However, the same call should succeed
94 * when IPC_EXCL is not set in the flags.
95 */
96 id = msgget(MSG_KEY, IPC_CREAT | 0600);
97
98 if (id < 0)
99 atf_tc_fail("msgget(2) failed to re-open");
100
101 ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
102}
103
104ATF_TC_CLEANUP(msgget_excl, tc)
105{
106 clean();
107}
108
109ATF_TC_WITH_CLEANUP(msgget_exit);
110ATF_TC_HEAD(msgget_exit, tc)
111{
112 atf_tc_set_md_var(tc, "descr",
113 "Test that XSI message queues are "
114 "not removed when the process exits");
115}
116
117ATF_TC_BODY(msgget_exit, tc)
118{
119 int id, sta;
120 pid_t pid;
121
122 pid = fork();
123 ATF_REQUIRE(pid >= 0);
124
125 if (pid == 0) {
126
127 if (msgget(MSG_KEY, IPC_CREAT | IPC_EXCL | 0600) == -1)
128 _exit(EXIT_FAILURE);
129
130 _exit(EXIT_SUCCESS);
131 }
132
133 (void)wait(&sta);
134
135 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
136 atf_tc_fail("failed to create message queue");
137
138 id = msgget(MSG_KEY, 0);
139
140 if (id == -1)
141 atf_tc_fail("message queue was removed on process exit");
142
143 ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
144}
145
146ATF_TC_CLEANUP(msgget_exit, tc)
147{
148 clean();
149}
150
151ATF_TC_WITH_CLEANUP(msgget_init);
152ATF_TC_HEAD(msgget_init, tc)
153{
154 atf_tc_set_md_var(tc, "descr",
155 "Test that msgget(2) initializes data structures properly");
156}
157
158ATF_TC_BODY(msgget_init, tc)
159{
160 const uid_t uid = geteuid();
161 const gid_t gid = getegid();
162 struct msqid_ds msgds;
163 time_t t;
164 int id;
165
166 (void)memset(&msgds, 0x9, sizeof(struct msqid_ds));
167
168 t = time(NULL);
169 id = msgget(MSG_KEY, IPC_CREAT | 0600);
170
171 ATF_REQUIRE(id !=-1);
172 ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0);
173
174 ATF_CHECK(msgds.msg_qnum == 0);
175 ATF_CHECK(msgds.msg_lspid == 0);
176 ATF_CHECK(msgds.msg_lrpid == 0);
177 ATF_CHECK(msgds.msg_rtime == 0);
178 ATF_CHECK(msgds.msg_stime == 0);
179 ATF_CHECK(msgds.msg_perm.uid == uid);
180 ATF_CHECK(msgds.msg_perm.gid == gid);
181 ATF_CHECK(msgds.msg_perm.cuid == uid);
182 ATF_CHECK(msgds.msg_perm.cgid == gid);
183 ATF_CHECK(msgds.msg_perm.mode == 0600);
184
185 if (llabs(t - msgds.msg_ctime) > 5)
186 atf_tc_fail("msgget(2) initialized current time incorrectly");
187
188 ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
189}
190
191ATF_TC_CLEANUP(msgget_init, tc)
192{
193 clean();
194}
195
196ATF_TC(msgget_limit);
197ATF_TC_HEAD(msgget_limit, tc)
198{
199 atf_tc_set_md_var(tc, "descr", "Test msgget(2) against system limits");
200}
201
202ATF_TC_BODY(msgget_limit, tc)
203{
204 size_t len = sizeof(int);
205 bool fail = false;
206 int i, lim = 0;
207 int *buf;
208
209 if (sysctlbyname("kern.ipc.msgmni", &lim, &len, NULL, 0) != 0)
210 atf_tc_skip("failed to read kern.ipc.msgmni sysctl");
211
212 buf = calloc(lim + 1, sizeof(*buf));
213 ATF_REQUIRE(buf != NULL);
214
215 for (i = 0; i < lim; i++) {
216
217 buf[i] = msgget(MSG_KEY + i, IPC_CREAT | IPC_EXCL | 0600);
218
219 (void)fprintf(stderr, "key[%d] = %d\n", i, buf[i]);
220
221 /*
222 * This test only works when there are zero existing
223 * message queues. Thus, bypass the unit test when
224 * this precondition is not met, for reason or another.
225 */
226 if (buf[i] == -1)
227 goto out;
228 }
229
230 i++;
231 errno = 0;
232
233 buf[i] = msgget(MSG_KEY + i, IPC_CREAT | IPC_EXCL | 0600);
234
235 if (buf[i] != -1 || errno != ENOSPC)
236 fail = true;
237
238out: /* Remember to clean-up. */
239 for (i = 0; i < lim; i++)
240 (void)msgctl(buf[i], IPC_RMID, 0);
241
242 free(buf);
243
244 if (fail != false)
245 atf_tc_fail("msgget(2) opened more than %d queues", lim);
246}
247
248ATF_TC_WITH_CLEANUP(msgget_mode);
249ATF_TC_HEAD(msgget_mode, tc)
250{
251 atf_tc_set_md_var(tc, "descr", "Test different modes with msgget(2)");
252 atf_tc_set_md_var(tc, "require.user", "root");
253}
254
255ATF_TC_BODY(msgget_mode, tc)
256{
257 static const mode_t mode[] = {
258 S_IRWXU, S_IRUSR, S_IWUSR, S_IXUSR, S_IRWXG, S_IRGRP,
259 S_IWGRP, S_IXGRP, S_IRWXO, S_IROTH, S_IWOTH, S_IXOTH
260 };
261
262 struct msqid_ds msgds;
263 size_t i;
264 int id;
265
266 for (i = 0; i < __arraycount(mode); i++) {
267
268 (void)fprintf(stderr, "testing mode %d\n", mode[i]);
269 (void)memset(&msgds, 0, sizeof(struct msqid_ds));
270
271 id = msgget(MSG_KEY, IPC_CREAT | IPC_EXCL | (int)mode[i]);
272
273 ATF_REQUIRE(id != -1);
274 ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0);
275 ATF_REQUIRE(msgds.msg_perm.mode == mode[i]);
276 ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
277 }
278}
279
280ATF_TC_CLEANUP(msgget_mode, tc)
281{
282 clean();
283}
284
285static volatile int sig_caught;
286
287static void
288sigsys_handler(int signum)
289{
290
291 sig_caught = signum;
292}
293
294static int
295no_kernel_sysvmsg(void)
296{
297 int id;
298 void (*osig)(int);
299
300 sig_caught = 0;
301 osig = signal(SIGSYS, sigsys_handler);
302 id = msgget(MSG_KEY, IPC_CREAT | 0600);
303 if (sig_caught || id == -1)
304 return 1;
305
306 (void)msgctl(id, IPC_RMID, 0);
307 (void)signal(SIGSYS, osig);
308
309 return 0;
310}
311
312ATF_TC(msgget_query);
313ATF_TC_HEAD(msgget_query, tc)
314{
315 atf_tc_set_md_var(tc, "descr", "Skip msgget_* tests - no SYSVMSG");
316}
317ATF_TC_BODY(msgget_query, tc)
318{
319 atf_tc_skip("No SYSVMSG in kernel");
320}
321
322ATF_TP_ADD_TCS(tp)
323{
324
325 if (no_kernel_sysvmsg()) {
326 ATF_TP_ADD_TC(tp, msgget_query);
327 } else {
328 ATF_TP_ADD_TC(tp, msgget_excl);
329 ATF_TP_ADD_TC(tp, msgget_exit);
330 ATF_TP_ADD_TC(tp, msgget_init);
331 /*
332 * Adjusted for OpenBSD, not available
333 * ATF_TP_ADD_TC(tp, msgget_limit);
334 */
335 ATF_TP_ADD_TC(tp, msgget_mode);
336 }
337
338 return atf_no_error();
339}
diff --git a/src/regress/lib/libc/sys/t_msgrcv.c b/src/regress/lib/libc/sys/t_msgrcv.c
new file mode 100644
index 0000000000..1fbcd41695
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_msgrcv.c
@@ -0,0 +1,388 @@
1/* $OpenBSD: t_msgrcv.c,v 1.1.1.1 2019/11/19 19:57:04 bluhm Exp $ */
2/* $NetBSD: t_msgrcv.c,v 1.5 2017/10/08 08:31:05 kre Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_msgrcv.c,v 1.5 2017/10/08 08:31:05 kre Exp $");
37
38#include <sys/msg.h>
39#include <sys/stat.h>
40#include <sys/sysctl.h>
41#include <sys/wait.h>
42
43#include "atf-c.h"
44#include <errno.h>
45#include <limits.h>
46#include <pwd.h>
47#include <signal.h>
48#include <stdio.h>
49#include <stdlib.h>
50#include <string.h>
51#include <sysexits.h>
52#include <time.h>
53#include <unistd.h>
54
55#define MSG_KEY 1234
56#define MSG_MTYPE_1 0x41
57#define MSG_MTYPE_2 0x42
58#define MSG_MTYPE_3 0x43
59#define MSG_LEN 3
60
61struct msg {
62 long mtype;
63 char buf[MSG_LEN];
64};
65
66static void clean(void);
67
68static void
69clean(void)
70{
71 int id;
72
73 if ((id = msgget(MSG_KEY, 0)) != -1)
74 (void)msgctl(id, IPC_RMID, 0);
75}
76
77ATF_TC_WITH_CLEANUP(msgrcv_basic);
78ATF_TC_HEAD(msgrcv_basic, tc)
79{
80 atf_tc_set_md_var(tc, "descr", "A basic test of msgrcv(2)");
81}
82
83ATF_TC_BODY(msgrcv_basic, tc)
84{
85 struct msg msg1 = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
86 struct msg msg2 = { MSG_MTYPE_1, { 'x', 'y', 'z' } };
87 int id;
88
89 id = msgget(MSG_KEY, IPC_CREAT | 0600);
90 ATF_REQUIRE(id != -1);
91
92 (void)msgsnd(id, &msg1, MSG_LEN, IPC_NOWAIT);
93 (void)msgrcv(id, &msg2, MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT);
94
95 ATF_CHECK(msg1.buf[0] == msg2.buf[0]);
96 ATF_CHECK(msg1.buf[1] == msg2.buf[1]);
97 ATF_CHECK(msg1.buf[2] == msg2.buf[2]);
98
99 ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
100}
101
102ATF_TC_CLEANUP(msgrcv_basic, tc)
103{
104 clean();
105}
106
107ATF_TC_WITH_CLEANUP(msgrcv_block);
108ATF_TC_HEAD(msgrcv_block, tc)
109{
110 atf_tc_set_md_var(tc, "descr", "Test that msgrcv(2) blocks");
111}
112
113ATF_TC_BODY(msgrcv_block, tc)
114{
115 struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
116 int id, sta;
117 pid_t pid;
118
119 id = msgget(MSG_KEY, IPC_CREAT | 0600);
120 ATF_REQUIRE(id != -1);
121
122 pid = fork();
123 ATF_REQUIRE(pid >= 0);
124
125 if (pid == 0) {
126
127 if (msgrcv(id, &msg, MSG_LEN, MSG_MTYPE_1, 0) < 0)
128 _exit(EXIT_FAILURE);
129
130 _exit(EXIT_SUCCESS);
131 }
132
133 /*
134 * Below msgsnd(2) should unblock the child,
135 * and hence kill(2) should fail with ESRCH.
136 */
137 (void)sleep(1);
138 (void)msgsnd(id, &msg, MSG_LEN, IPC_NOWAIT);
139 (void)sleep(1);
140 (void)kill(pid, SIGKILL);
141 (void)wait(&sta);
142
143 if (WIFEXITED(sta) == 0 || WIFSIGNALED(sta) != 0)
144 atf_tc_fail("msgrcv(2) did not block");
145
146 ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
147}
148
149ATF_TC_CLEANUP(msgrcv_block, tc)
150{
151 clean();
152}
153
154ATF_TC_WITH_CLEANUP(msgrcv_err);
155ATF_TC_HEAD(msgrcv_err, tc)
156{
157 atf_tc_set_md_var(tc, "descr", "Test errors from msgrcv(2)");
158}
159
160ATF_TC_BODY(msgrcv_err, tc)
161{
162 struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
163 int id, r = 0;
164
165 id = msgget(MSG_KEY, IPC_CREAT | 0600);
166 ATF_REQUIRE(id != -1);
167
168 errno = 0;
169
170 ATF_REQUIRE_ERRNO(ENOMSG, msgrcv(id, &msg,
171 MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT) == -1);
172
173 ATF_REQUIRE(msgsnd(id, &msg, MSG_LEN, IPC_NOWAIT) == 0);
174
175 errno = 0;
176
177 ATF_REQUIRE_ERRNO(EFAULT, msgrcv(id, (void *)-1,
178 MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT) == -1);
179
180 errno = 0;
181
182 ATF_REQUIRE_ERRNO(EINVAL, msgrcv(-1, &msg,
183 MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT) == -1);
184
185 errno = 0;
186
187 ATF_REQUIRE_ERRNO(EINVAL, msgrcv(-1, &msg,
188 SSIZE_MAX, MSG_MTYPE_1, IPC_NOWAIT) == -1);
189
190 ATF_REQUIRE(msgsnd(id, &msg, MSG_LEN, IPC_NOWAIT) == 0);
191
192 errno = 0;
193
194 ATF_REQUIRE_ERRNO(E2BIG, msgrcv(id, &r,
195 MSG_LEN - 1, MSG_MTYPE_1, IPC_NOWAIT) == -1);
196
197 ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
198}
199
200ATF_TC_CLEANUP(msgrcv_err, tc)
201{
202 clean();
203}
204
205
206ATF_TC_WITH_CLEANUP(msgrcv_mtype);
207ATF_TC_HEAD(msgrcv_mtype, tc)
208{
209 atf_tc_set_md_var(tc, "descr", "Test message types with msgrcv(2)");
210}
211
212ATF_TC_BODY(msgrcv_mtype, tc)
213{
214 struct msg msg1 = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
215 struct msg msg2 = { MSG_MTYPE_3, { 'x', 'y', 'z' } };
216 int id;
217
218 id = msgget(MSG_KEY, IPC_CREAT | 0600);
219 ATF_REQUIRE(id != -1);
220
221 (void)msgsnd(id, &msg1, MSG_LEN, IPC_NOWAIT);
222 (void)msgrcv(id, &msg2, MSG_LEN, MSG_MTYPE_2, IPC_NOWAIT);
223
224 ATF_CHECK(msg1.buf[0] != msg2.buf[0]); /* Different mtype. */
225 ATF_CHECK(msg1.buf[1] != msg2.buf[1]);
226 ATF_CHECK(msg1.buf[2] != msg2.buf[2]);
227
228 (void)msgrcv(id, &msg2, MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT);
229
230 ATF_CHECK(msg1.buf[0] == msg2.buf[0]); /* Same mtype. */
231 ATF_CHECK(msg1.buf[1] == msg2.buf[1]);
232 ATF_CHECK(msg1.buf[2] == msg2.buf[2]);
233
234 ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
235}
236
237ATF_TC_CLEANUP(msgrcv_mtype, tc)
238{
239 clean();
240}
241
242ATF_TC_WITH_CLEANUP(msgrcv_nonblock);
243ATF_TC_HEAD(msgrcv_nonblock, tc)
244{
245 atf_tc_set_md_var(tc, "descr", "Test msgrcv(2) with IPC_NOWAIT");
246 atf_tc_set_md_var(tc, "timeout", "10");
247}
248
249ATF_TC_BODY(msgrcv_nonblock, tc)
250{
251 struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
252 const ssize_t n = 10;
253 int id, sta;
254 ssize_t i;
255 pid_t pid;
256
257 id = msgget(MSG_KEY, IPC_CREAT | 0600);
258 ATF_REQUIRE(id != -1);
259
260 for (i = 0; i < n; i++) {
261
262 ATF_REQUIRE(msgsnd(id, &msg, MSG_LEN, IPC_NOWAIT) == 0);
263 }
264
265 pid = fork();
266 ATF_REQUIRE(pid >= 0);
267
268 if (pid == 0) {
269
270 while (i != 0) {
271
272 if (msgrcv(id, &msg, MSG_LEN, MSG_MTYPE_1,
273 IPC_NOWAIT) == -1)
274 _exit(EXIT_FAILURE);
275
276 i--;
277 }
278
279 _exit(EXIT_SUCCESS);
280 }
281
282 (void)sleep(2);
283 (void)kill(pid, SIGKILL);
284 (void)wait(&sta);
285
286 if (WIFSIGNALED(sta) != 0 || WTERMSIG(sta) == SIGKILL)
287 atf_tc_fail("msgrcv(2) blocked with IPC_NOWAIT");
288
289 if (WIFEXITED(sta) == 0 && WEXITSTATUS(sta) != EXIT_SUCCESS)
290 atf_tc_fail("msgrcv(2) failed");
291
292 ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
293}
294
295ATF_TC_CLEANUP(msgrcv_nonblock, tc)
296{
297 clean();
298}
299
300ATF_TC_WITH_CLEANUP(msgrcv_truncate);
301ATF_TC_HEAD(msgrcv_truncate, tc)
302{
303 atf_tc_set_md_var(tc, "descr", "Test msgrcv(2) with MSG_NOERROR");
304}
305
306ATF_TC_BODY(msgrcv_truncate, tc)
307{
308#define MSG_SMALLLEN 2
309 struct msgsmall {
310 long mtype;
311 char buf[MSG_SMALLLEN];
312 };
313
314 struct msg msg1 = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
315 struct msgsmall msg2 = { MSG_MTYPE_1, { 'x', 'y' } };
316 int id;
317
318 id = msgget(MSG_KEY, IPC_CREAT | 0600);
319 ATF_REQUIRE(id != -1);
320
321 (void)msgsnd(id, &msg1, MSG_LEN, IPC_NOWAIT);
322 (void)msgrcv(id, &msg2, MSG_SMALLLEN,
323 MSG_MTYPE_1, IPC_NOWAIT | MSG_NOERROR);
324
325 ATF_CHECK(msg1.buf[0] == msg2.buf[0]);
326 ATF_CHECK(msg1.buf[1] == msg2.buf[1]);
327
328 ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
329}
330
331ATF_TC_CLEANUP(msgrcv_truncate, tc)
332{
333 clean();
334}
335
336static volatile int sig_caught;
337
338static void
339sigsys_handler(int signum)
340{
341
342 sig_caught = signum;
343}
344
345static int
346no_kernel_sysvmsg(void)
347{
348 int id;
349 void (*osig)(int);
350
351 sig_caught = 0;
352 osig = signal(SIGSYS, sigsys_handler);
353 id = msgget(MSG_KEY, IPC_CREAT | 0600);
354 if (sig_caught || id == -1)
355 return 1;
356
357 (void)msgctl(id, IPC_RMID, 0);
358 (void)signal(SIGSYS, osig);
359
360 return 0;
361}
362
363ATF_TC(msgrcv_query);
364ATF_TC_HEAD(msgrcv_query, tc)
365{
366 atf_tc_set_md_var(tc, "descr", "Skip msgrcv_* tests - no SYSVMSG");
367}
368ATF_TC_BODY(msgrcv_query, tc)
369{
370 atf_tc_skip("No SYSVMSG in kernel");
371}
372
373ATF_TP_ADD_TCS(tp)
374{
375
376 if (no_kernel_sysvmsg()) {
377 ATF_TP_ADD_TC(tp, msgrcv_query);
378 } else {
379 ATF_TP_ADD_TC(tp, msgrcv_basic);
380 ATF_TP_ADD_TC(tp, msgrcv_block);
381 ATF_TP_ADD_TC(tp, msgrcv_err);
382 ATF_TP_ADD_TC(tp, msgrcv_mtype);
383 ATF_TP_ADD_TC(tp, msgrcv_nonblock);
384 ATF_TP_ADD_TC(tp, msgrcv_truncate);
385 }
386
387 return atf_no_error();
388}
diff --git a/src/regress/lib/libc/sys/t_msgsnd.c b/src/regress/lib/libc/sys/t_msgsnd.c
new file mode 100644
index 0000000000..ab0cc87e6f
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_msgsnd.c
@@ -0,0 +1,384 @@
1/* $OpenBSD: t_msgsnd.c,v 1.1.1.1 2019/11/19 19:57:04 bluhm Exp $ */
2/* $NetBSD: t_msgsnd.c,v 1.4 2017/10/08 08:31:05 kre Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_msgsnd.c,v 1.4 2017/10/08 08:31:05 kre Exp $");
37
38#include <sys/msg.h>
39#include <sys/stat.h>
40#include <sys/sysctl.h>
41#include <sys/wait.h>
42
43#include "atf-c.h"
44#include <errno.h>
45#include <limits.h>
46#include <pwd.h>
47#include <signal.h>
48#include <stdio.h>
49#include <stdlib.h>
50#include <string.h>
51#include <sysexits.h>
52#include <time.h>
53#include <unistd.h>
54
55#define MSG_KEY 1234
56#define MSG_MTYPE_1 0x41
57#define MSG_MTYPE_2 0x42
58#define MSG_MTYPE_3 0x43
59
60struct msg {
61 long mtype;
62 char buf[3];
63};
64
65static void clean(void);
66
67static void
68clean(void)
69{
70 int id;
71
72 if ((id = msgget(MSG_KEY, 0)) != -1)
73 (void)msgctl(id, IPC_RMID, 0);
74}
75
76ATF_TC_WITH_CLEANUP(msgsnd_block);
77ATF_TC_HEAD(msgsnd_block, tc)
78{
79 atf_tc_set_md_var(tc, "descr", "Test that msgsnd(2) blocks");
80 atf_tc_set_md_var(tc, "timeout", "10");
81}
82
83ATF_TC_BODY(msgsnd_block, tc)
84{
85 struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
86 int id, sta;
87 pid_t pid;
88
89 id = msgget(MSG_KEY, IPC_CREAT | 0600);
90 ATF_REQUIRE(id != -1);
91
92 pid = fork();
93 ATF_REQUIRE(pid >= 0);
94
95 if (pid == 0) {
96
97 /*
98 * Enqueue messages until some limit (e.g. the maximum
99 * number of messages in the queue or the maximum number
100 * of bytes in the queue) is reached. After this the call
101 * should block when the IPC_NOWAIT is not set.
102 */
103 for (;;) {
104
105 if (msgsnd(id, &msg, sizeof(struct msg), 0) < 0)
106 _exit(EXIT_FAILURE);
107 }
108 }
109
110 (void)sleep(2);
111 (void)kill(pid, SIGKILL);
112 (void)wait(&sta);
113
114 if (WIFEXITED(sta) != 0 || WIFSIGNALED(sta) == 0)
115 atf_tc_fail("msgsnd(2) did not block");
116
117 ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
118}
119
120ATF_TC_CLEANUP(msgsnd_block, tc)
121{
122 clean();
123}
124
125ATF_TC_WITH_CLEANUP(msgsnd_count);
126ATF_TC_HEAD(msgsnd_count, tc)
127{
128 atf_tc_set_md_var(tc, "descr",
129 "Test that msgsnd(2) increments the amount of "
130 "message in the queue, as given by msgctl(2)");
131 atf_tc_set_md_var(tc, "timeout", "10");
132}
133
134ATF_TC_BODY(msgsnd_count, tc)
135{
136 struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
137 struct msqid_ds ds;
138 size_t i = 0;
139 int id, rv;
140
141 id = msgget(MSG_KEY, IPC_CREAT | 0600);
142 ATF_REQUIRE(id != -1);
143
144 for (;;) {
145
146 errno = 0;
147 rv = msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT);
148
149 if (rv == 0) {
150 i++;
151 continue;
152 }
153
154 if (rv == -1 && errno == EAGAIN)
155 break;
156
157 atf_tc_fail("failed to enqueue a message");
158 }
159
160 (void)memset(&ds, 0, sizeof(struct msqid_ds));
161 (void)msgctl(id, IPC_STAT, &ds);
162
163 if (ds.msg_qnum != i)
164 atf_tc_fail("incorrect message count");
165
166 ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
167}
168
169ATF_TC_CLEANUP(msgsnd_count, tc)
170{
171 clean();
172}
173
174ATF_TC_WITH_CLEANUP(msgsnd_err);
175ATF_TC_HEAD(msgsnd_err, tc)
176{
177 atf_tc_set_md_var(tc, "descr", "Test errors from msgsnd(2)");
178}
179
180ATF_TC_BODY(msgsnd_err, tc)
181{
182 struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
183 int id;
184
185 id = msgget(MSG_KEY, IPC_CREAT | 0600);
186 ATF_REQUIRE(id != -1);
187
188 errno = 0;
189
190 ATF_REQUIRE_ERRNO(EFAULT, msgsnd(id, (void *)-1,
191 sizeof(struct msg), IPC_NOWAIT) == -1);
192
193 errno = 0;
194
195 ATF_REQUIRE_ERRNO(EINVAL, msgsnd(-1, &msg,
196 sizeof(struct msg), IPC_NOWAIT) == -1);
197
198 errno = 0;
199
200 ATF_REQUIRE_ERRNO(EINVAL, msgsnd(-1, &msg,
201 SSIZE_MAX, IPC_NOWAIT) == -1);
202
203 errno = 0;
204 msg.mtype = 0;
205
206 ATF_REQUIRE_ERRNO(EINVAL, msgsnd(id, &msg,
207 sizeof(struct msg), IPC_NOWAIT) == -1);
208
209 ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
210}
211
212ATF_TC_CLEANUP(msgsnd_err, tc)
213{
214 clean();
215}
216
217ATF_TC_WITH_CLEANUP(msgsnd_nonblock);
218ATF_TC_HEAD(msgsnd_nonblock, tc)
219{
220 atf_tc_set_md_var(tc, "descr", "Test msgsnd(2) with IPC_NOWAIT");
221 atf_tc_set_md_var(tc, "timeout", "10");
222}
223
224ATF_TC_BODY(msgsnd_nonblock, tc)
225{
226 struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
227 int id, rv, sta;
228 pid_t pid;
229
230 id = msgget(MSG_KEY, IPC_CREAT | 0600);
231 ATF_REQUIRE(id != -1);
232
233 pid = fork();
234 ATF_REQUIRE(pid >= 0);
235
236 if (pid == 0) {
237
238 for (;;) {
239
240 errno = 0;
241 rv = msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT);
242
243 if (rv == -1 && errno == EAGAIN)
244 _exit(EXIT_SUCCESS);
245 }
246 }
247
248 (void)sleep(2);
249 (void)kill(pid, SIGKILL);
250 (void)wait(&sta);
251
252 if (WIFEXITED(sta) == 0 || WIFSIGNALED(sta) != 0)
253 atf_tc_fail("msgsnd(2) blocked with IPC_NOWAIT");
254
255 ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
256}
257
258ATF_TC_CLEANUP(msgsnd_nonblock, tc)
259{
260 clean();
261}
262
263ATF_TC_WITH_CLEANUP(msgsnd_perm);
264ATF_TC_HEAD(msgsnd_perm, tc)
265{
266 atf_tc_set_md_var(tc, "descr", "Test permissions with msgsnd(2)");
267 atf_tc_set_md_var(tc, "require.user", "root");
268}
269
270ATF_TC_BODY(msgsnd_perm, tc)
271{
272 struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
273 struct passwd *pw;
274 int id, sta;
275 pid_t pid;
276 uid_t uid;
277
278 pw = getpwnam("nobody");
279 id = msgget(MSG_KEY, IPC_CREAT | 0600);
280
281 ATF_REQUIRE(id != -1);
282 ATF_REQUIRE(pw != NULL);
283
284 uid = pw->pw_uid;
285 ATF_REQUIRE(uid != 0);
286
287 pid = fork();
288 ATF_REQUIRE(pid >= 0);
289
290 if (pid == 0) {
291
292 /*
293 * Try to enqueue a message to the queue
294 * created by root as RW for owner only.
295 */
296 if (setuid(uid) != 0)
297 _exit(EX_OSERR);
298
299 id = msgget(MSG_KEY, 0);
300
301 if (id == -1)
302 _exit(EX_OSERR);
303
304 errno = 0;
305
306 if (msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT) == 0)
307 _exit(EXIT_FAILURE);
308
309 if (errno != EACCES)
310 _exit(EXIT_FAILURE);
311
312 _exit(EXIT_SUCCESS);
313 }
314
315 (void)wait(&sta);
316
317 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) {
318
319 if (errno == EX_OSERR)
320 atf_tc_fail("system call failed");
321
322 atf_tc_fail("UID %u enqueued message to root's queue", uid);
323 }
324
325 ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
326}
327
328ATF_TC_CLEANUP(msgsnd_perm, tc)
329{
330 clean();
331}
332
333static volatile int sig_caught;
334
335static void
336sigsys_handler(int signum)
337{
338
339 sig_caught = signum;
340}
341
342static int
343no_kernel_sysvmsg(void)
344{
345 int id;
346 void (*osig)(int);
347
348 sig_caught = 0;
349 osig = signal(SIGSYS, sigsys_handler);
350 id = msgget(MSG_KEY, IPC_CREAT | 0600);
351 if (sig_caught || id == -1)
352 return 1;
353
354 (void)msgctl(id, IPC_RMID, 0);
355 (void)signal(SIGSYS, osig);
356
357 return 0;
358}
359
360ATF_TC(msgsnd_query);
361ATF_TC_HEAD(msgsnd_query, tc)
362{
363 atf_tc_set_md_var(tc, "descr", "Skip msgsnd_* tests - no SYSVMSG");
364}
365ATF_TC_BODY(msgsnd_query, tc)
366{
367 atf_tc_skip("No SYSVMSG in kernel");
368}
369
370ATF_TP_ADD_TCS(tp)
371{
372
373 if (no_kernel_sysvmsg()) {
374 ATF_TP_ADD_TC(tp, msgsnd_query);
375 } else {
376 ATF_TP_ADD_TC(tp, msgsnd_block);
377 ATF_TP_ADD_TC(tp, msgsnd_count);
378 ATF_TP_ADD_TC(tp, msgsnd_err);
379 ATF_TP_ADD_TC(tp, msgsnd_nonblock);
380 ATF_TP_ADD_TC(tp, msgsnd_perm);
381 }
382
383 return atf_no_error();
384}
diff --git a/src/regress/lib/libc/sys/t_msync.c b/src/regress/lib/libc/sys/t_msync.c
new file mode 100644
index 0000000000..8e06d79d9a
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_msync.c
@@ -0,0 +1,228 @@
1/* $OpenBSD: t_msync.c,v 1.1.1.1 2019/11/19 19:57:04 bluhm Exp $ */
2/* $NetBSD: t_msync.c,v 1.3 2017/01/14 20:52:42 christos Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_msync.c,v 1.3 2017/01/14 20:52:42 christos Exp $");
37
38#include <sys/mman.h>
39
40#include "atf-c.h"
41#include <errno.h>
42#include <fcntl.h>
43#include <limits.h>
44#include <stdlib.h>
45#include <string.h>
46#include <unistd.h>
47
48static long page = 0;
49static const off_t off = 512;
50static const char path[] = "msync";
51
52static const char *msync_sync(const char *, int);
53
54static const char *
55msync_sync(const char *garbage, int flags)
56{
57 char *buf, *map = MAP_FAILED;
58 const char *str = NULL;
59 size_t len;
60 int fd, rv;
61
62 /*
63 * Create a temporary file, write
64 * one page to it, and map the file.
65 */
66 buf = malloc(page);
67
68 if (buf == NULL)
69 return NULL;
70
71 memset(buf, 'x', page);
72
73 fd = open(path, O_RDWR | O_CREAT, 0700);
74
75 if (fd < 0) {
76 free(buf);
77 return "failed to open";
78 }
79
80 ATF_REQUIRE_MSG(write(fd, buf, page) != -1, "write(2) failed: %s",
81 strerror(errno));
82
83 map = mmap(NULL, page, PROT_READ | PROT_WRITE, MAP_FILE|MAP_PRIVATE,
84 fd, 0);
85
86 if (map == MAP_FAILED) {
87 str = "failed to map";
88 goto out;
89 }
90
91 /*
92 * Seek to an arbitrary offset and
93 * write garbage to this position.
94 */
95 if (lseek(fd, off, SEEK_SET) != off) {
96 str = "failed to seek";
97 goto out;
98 }
99
100 len = strlen(garbage);
101 rv = write(fd, garbage, len);
102
103 if (rv != (ssize_t)len) {
104 str = "failed to write garbage";
105 goto out;
106 }
107
108 /*
109 * Synchronize the mapping and verify
110 * that garbage is at the given offset.
111 */
112 if (msync(map, page, flags) != 0) {
113 str = "failed to msync";
114 goto out;
115 }
116
117 if (memcmp(map + off, garbage, len) != 0) {
118 str = "msync did not synchronize";
119 goto out;
120 }
121
122out:
123 free(buf);
124
125 (void)close(fd);
126 (void)unlink(path);
127
128 if (map != MAP_FAILED)
129 (void)munmap(map, page);
130
131 return str;
132}
133
134ATF_TC(msync_async);
135ATF_TC_HEAD(msync_async, tc)
136{
137 atf_tc_set_md_var(tc, "descr", "Test of msync(2), MS_ASYNC");
138}
139
140ATF_TC_BODY(msync_async, tc)
141{
142 const char *str;
143
144 str = msync_sync("garbage", MS_ASYNC);
145
146 if (str != NULL)
147 atf_tc_fail("%s", str);
148}
149
150ATF_TC(msync_err);
151ATF_TC_HEAD(msync_err, tc)
152{
153 atf_tc_set_md_var(tc, "descr", "Test error conditions in msync(2)");
154}
155
156ATF_TC_BODY(msync_err, tc)
157{
158
159 char *map = MAP_FAILED;
160
161 /*
162 * Test that invalid flags error out.
163 */
164 ATF_REQUIRE(msync_sync("error", -1) != NULL);
165 ATF_REQUIRE(msync_sync("error", INT_MAX) != NULL);
166
167 errno = 0;
168
169 /*
170 * Map a page and then unmap to get an unmapped address.
171 */
172 map = mmap(NULL, page, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,
173 -1, 0);
174 ATF_REQUIRE(map != MAP_FAILED);
175
176 (void)munmap(map, page);
177
178 ATF_REQUIRE(msync(map, page, MS_SYNC) != 0);
179 ATF_REQUIRE(errno == EFAULT);
180}
181
182ATF_TC(msync_invalidate);
183ATF_TC_HEAD(msync_invalidate, tc)
184{
185 atf_tc_set_md_var(tc, "descr", "Test of msync(2), MS_INVALIDATE");
186}
187
188ATF_TC_BODY(msync_invalidate, tc)
189{
190 const char *str;
191
192 str = msync_sync("garbage", MS_INVALIDATE);
193
194 if (str != NULL)
195 atf_tc_fail("%s", str);
196}
197
198ATF_TC(msync_sync);
199ATF_TC_HEAD(msync_sync, tc)
200{
201 atf_tc_set_md_var(tc, "descr", "Test of msync(2), MS_SYNC");
202}
203
204ATF_TC_BODY(msync_sync, tc)
205{
206 const char *str;
207
208 str = msync_sync("garbage", MS_SYNC);
209
210 if (str != NULL)
211 atf_tc_fail("%s", str);
212}
213
214ATF_TP_ADD_TCS(tp)
215{
216
217 page = sysconf(_SC_PAGESIZE);
218
219 ATF_REQUIRE(page >= 0);
220 ATF_REQUIRE(page > off);
221
222 ATF_TP_ADD_TC(tp, msync_async);
223 ATF_TP_ADD_TC(tp, msync_err);
224 ATF_TP_ADD_TC(tp, msync_invalidate);
225 ATF_TP_ADD_TC(tp, msync_sync);
226
227 return atf_no_error();
228}
diff --git a/src/regress/lib/libc/sys/t_pipe.c b/src/regress/lib/libc/sys/t_pipe.c
new file mode 100644
index 0000000000..bd9805a4b9
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_pipe.c
@@ -0,0 +1,168 @@
1/* $OpenBSD: t_pipe.c,v 1.1.1.1 2019/11/19 19:57:04 bluhm Exp $ */
2/* $NetBSD: t_pipe.c,v 1.5 2017/01/13 21:30:41 christos Exp $ */
3
4/*-
5 * Copyright (c) 2001, 2008 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "macros.h"
31
32#include <sys/cdefs.h>
33#include <sys/cdefs.h>
34__COPYRIGHT("@(#) Copyright (c) 2008\
35 The NetBSD Foundation, inc. All rights reserved.");
36__RCSID("$NetBSD: t_pipe.c,v 1.5 2017/01/13 21:30:41 christos Exp $");
37
38#include <sys/types.h>
39#include <sys/wait.h>
40
41#include <errno.h>
42#include <fcntl.h>
43#include <poll.h>
44#include <sched.h>
45#include <signal.h>
46#include <stdio.h>
47#include <stdlib.h>
48#include <unistd.h>
49
50#include "atf-c.h"
51
52#include "h_macros.h"
53
54static pid_t pid;
55static int nsiginfo = 0;
56
57/*
58 * This is used for both parent and child. Handle parent's SIGALRM,
59 * the childs SIGINFO doesn't need anything.
60 */
61static void
62sighand(int sig)
63{
64 if (sig == SIGALRM) {
65 kill(pid, SIGINFO);
66 }
67 if (sig == SIGINFO) {
68 nsiginfo++;
69 }
70}
71
72ATF_TC(pipe_restart);
73ATF_TC_HEAD(pipe_restart, tc)
74{
75 atf_tc_set_md_var(tc, "descr", "Checks that writing to pipe "
76 "works correctly after being interrupted and restarted "
77 "(kern/14087)");
78}
79
80ATF_TC_BODY(pipe_restart, tc)
81{
82 int pp[2], st;
83 ssize_t sz, todo, done;
84 char *f;
85 sigset_t asigset, osigset, emptysigset;
86
87 /* Initialise signal masks */
88 RL(sigemptyset(&emptysigset));
89 RL(sigemptyset(&asigset));
90 RL(sigaddset(&asigset, SIGINFO));
91
92 /* Register signal handlers for both read and writer */
93 REQUIRE_LIBC(signal(SIGINFO, sighand), SIG_ERR);
94 REQUIRE_LIBC(signal(SIGALRM, sighand), SIG_ERR);
95
96 todo = 2 * 1024 * 1024;
97 REQUIRE_LIBC(f = malloc(todo), NULL);
98
99 RL(pipe(pp));
100
101 RL(pid = fork());
102 if (pid == 0) {
103 /* child */
104 RL(close(pp[1]));
105
106 /* Do inital write. This should succeed, make
107 * the other side do partial write and wait for us to pick
108 * rest up.
109 */
110 RL(done = read(pp[0], f, 128 * 1024));
111
112 /* Wait until parent is alarmed and awakens us */
113 RL(sigprocmask(SIG_BLOCK, &asigset, &osigset));
114 while (nsiginfo == 0) {
115 if (sigsuspend(&emptysigset) != -1 || errno != EINTR)
116 atf_tc_fail("sigsuspend(&emptysigset): %s",
117 strerror(errno));
118 }
119 RL(sigprocmask(SIG_SETMASK, &osigset, NULL));
120
121 /* Read all what parent wants to give us */
122 while((sz = read(pp[0], f, 1024 * 1024)) > 0)
123 done += sz;
124
125 /*
126 * Exit with 1 if number of bytes read doesn't match
127 * number of expected bytes
128 */
129 printf("Read: %#zx\n", (size_t)done);
130 printf("Expected: %#zx\n", (size_t)todo);
131
132 exit(done != todo);
133
134 /* NOTREACHED */
135 } else {
136 RL(close(pp[0]));
137
138 /*
139 * Arrange for alarm after two seconds. Since we have
140 * handler setup for SIGARLM, the write(2) call should
141 * be restarted internally by kernel.
142 */
143 (void)alarm(2);
144
145 /* We write exactly 'todo' bytes. The very first write(2)
146 * should partially succeed, block and eventually
147 * be restarted by kernel
148 */
149 while(todo > 0 && ((sz = write(pp[1], f, todo)) > 0))
150 todo -= sz;
151
152 /* Close the pipe, so that child would stop reading */
153 RL(close(pp[1]));
154
155 /* And pickup child's exit status */
156 RL(waitpid(pid, &st, 0));
157
158 ATF_REQUIRE_EQ(WEXITSTATUS(st), 0);
159 }
160 free(f);
161}
162
163ATF_TP_ADD_TCS(tp)
164{
165 ATF_TP_ADD_TC(tp, pipe_restart);
166
167 return atf_no_error();
168}
diff --git a/src/regress/lib/libc/sys/t_pipe2.c b/src/regress/lib/libc/sys/t_pipe2.c
new file mode 100644
index 0000000000..4964be14ce
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_pipe2.c
@@ -0,0 +1,203 @@
1/* $OpenBSD: t_pipe2.c,v 1.1.1.1 2019/11/19 19:57:04 bluhm Exp $ */
2/* $NetBSD: t_pipe2.c,v 1.9 2017/01/13 21:19:45 christos Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Christos Zoulas.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the NetBSD
22 * Foundation, Inc. and its contributors.
23 * 4. Neither the name of The NetBSD Foundation nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40#include "macros.h"
41
42#include <sys/cdefs.h>
43__RCSID("$NetBSD: t_pipe2.c,v 1.9 2017/01/13 21:19:45 christos Exp $");
44
45#include "atf-c.h"
46#include <fcntl.h>
47#include <unistd.h>
48#include <stdlib.h>
49#include <errno.h>
50#include <sys/resource.h>
51
52static void
53run(int flags)
54{
55 int fd[2], i;
56
57 while ((i = open("/", O_RDONLY)) < 3)
58 ATF_REQUIRE(i != -1);
59
60 ATF_REQUIRE_MSG(closefrom(3) != -1, "closefrom failed: %s",
61 strerror(errno));
62
63 ATF_REQUIRE(pipe2(fd, flags) == 0);
64
65 ATF_REQUIRE(fd[0] == 3);
66 ATF_REQUIRE(fd[1] == 4);
67
68 if (flags & O_CLOEXEC) {
69 ATF_REQUIRE((fcntl(fd[0], F_GETFD) & FD_CLOEXEC) != 0);
70 ATF_REQUIRE((fcntl(fd[1], F_GETFD) & FD_CLOEXEC) != 0);
71 } else {
72 ATF_REQUIRE((fcntl(fd[0], F_GETFD) & FD_CLOEXEC) == 0);
73 ATF_REQUIRE((fcntl(fd[1], F_GETFD) & FD_CLOEXEC) == 0);
74 }
75
76 if (flags & O_NONBLOCK) {
77 ATF_REQUIRE((fcntl(fd[0], F_GETFL) & O_NONBLOCK) != 0);
78 ATF_REQUIRE((fcntl(fd[1], F_GETFL) & O_NONBLOCK) != 0);
79 } else {
80 ATF_REQUIRE((fcntl(fd[0], F_GETFL) & O_NONBLOCK) == 0);
81 ATF_REQUIRE((fcntl(fd[1], F_GETFL) & O_NONBLOCK) == 0);
82 }
83
84 /*
85 * Adjusted for OpenBSD, not available
86 * if (flags & O_NOSIGPIPE) {
87 * ATF_REQUIRE(fcntl(fd[0], F_GETNOSIGPIPE) != 0);
88 * ATF_REQUIRE(fcntl(fd[1], F_GETNOSIGPIPE) != 0);
89 *} else {
90 * ATF_REQUIRE(fcntl(fd[0], F_GETNOSIGPIPE) == 0);
91 * ATF_REQUIRE(fcntl(fd[1], F_GETNOSIGPIPE) == 0);
92 *}
93 */
94
95 ATF_REQUIRE(close(fd[0]) != -1);
96 ATF_REQUIRE(close(fd[1]) != -1);
97}
98
99ATF_TC(pipe2_basic);
100ATF_TC_HEAD(pipe2_basic, tc)
101{
102 atf_tc_set_md_var(tc, "descr", "A basic test of pipe2(2)");
103}
104
105ATF_TC_BODY(pipe2_basic, tc)
106{
107 run(0);
108}
109
110ATF_TC(pipe2_consume);
111ATF_TC_HEAD(pipe2_consume, tc)
112{
113 atf_tc_set_md_var(tc, "descr", "Test that consuming file descriptors "
114 "with pipe2(2) does not crash the system (PR kern/46457)");
115}
116
117ATF_TC_BODY(pipe2_consume, tc)
118{
119 struct rlimit rl;
120 int err, filedes[2];
121 int old;
122
123 ATF_REQUIRE_MSG(closefrom(4) != -1, "closefrom failed: %s",
124 strerror(errno));
125
126 err = getrlimit(RLIMIT_NOFILE, &rl);
127 ATF_REQUIRE(err == 0);
128 /*
129 * The heart of this test is to run against the number of open
130 * file descriptor limit in the middle of a pipe2() call - i.e.
131 * before the call only a single descriptor may be openend.
132 */
133 old = rl.rlim_cur;
134 rl.rlim_cur = 4;
135 err = setrlimit(RLIMIT_NOFILE, &rl);
136 ATF_REQUIRE(err == 0);
137
138 err = pipe2(filedes, O_CLOEXEC);
139 ATF_REQUIRE(err == -1);
140 rl.rlim_cur = old;
141 err = setrlimit(RLIMIT_NOFILE, &rl);
142}
143
144ATF_TC(pipe2_nonblock);
145ATF_TC_HEAD(pipe2_nonblock, tc)
146{
147 atf_tc_set_md_var(tc, "descr", "A non-blocking test of pipe2(2)");
148}
149
150ATF_TC_BODY(pipe2_nonblock, tc)
151{
152 run(O_NONBLOCK);
153}
154
155ATF_TC(pipe2_cloexec);
156ATF_TC_HEAD(pipe2_cloexec, tc)
157{
158 atf_tc_set_md_var(tc, "descr", "A close-on-exec test of pipe2(2)");
159}
160
161ATF_TC_BODY(pipe2_cloexec, tc)
162{
163 run(O_CLOEXEC);
164}
165
166ATF_TC(pipe2_nosigpipe);
167ATF_TC_HEAD(pipe2_nosigpipe, tc)
168{
169 atf_tc_set_md_var(tc, "descr", "A no sigpipe test of pipe2(2)");
170}
171
172ATF_TC_BODY(pipe2_nosigpipe, tc)
173{
174 run(O_NOSIGPIPE);
175}
176
177ATF_TC(pipe2_einval);
178ATF_TC_HEAD(pipe2_einval, tc)
179{
180 atf_tc_set_md_var(tc, "descr", "A error check of pipe2(2)");
181}
182
183ATF_TC_BODY(pipe2_einval, tc)
184{
185 int fd[2];
186 ATF_REQUIRE_ERRNO(EINVAL, pipe2(fd, O_ASYNC) == -1);
187}
188
189ATF_TP_ADD_TCS(tp)
190{
191
192 ATF_TP_ADD_TC(tp, pipe2_basic);
193 ATF_TP_ADD_TC(tp, pipe2_consume);
194 ATF_TP_ADD_TC(tp, pipe2_nonblock);
195 ATF_TP_ADD_TC(tp, pipe2_cloexec);
196 /*
197 * Adjusted for OpenBSD, not available
198 * ATF_TP_ADD_TC(tp, pipe2_nosigpipe);
199 */
200 ATF_TP_ADD_TC(tp, pipe2_einval);
201
202 return atf_no_error();
203}
diff --git a/src/regress/lib/libc/sys/t_poll.c b/src/regress/lib/libc/sys/t_poll.c
new file mode 100644
index 0000000000..bbb8dc2d14
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_poll.c
@@ -0,0 +1,398 @@
1/* $OpenBSD: t_poll.c,v 1.1.1.1 2019/11/19 19:57:04 bluhm Exp $ */
2/* $NetBSD: t_poll.c,v 1.3 2012/03/18 07:00:52 jruoho Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Matthias Scheler.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/time.h>
36#include <sys/wait.h>
37
38#include "atf-c.h"
39#include <errno.h>
40#include <fcntl.h>
41#include <paths.h>
42#include <poll.h>
43#include <stdio.h>
44#include <signal.h>
45#include <unistd.h>
46
47static int desc;
48
49static void
50child1(void)
51{
52 struct pollfd pfd;
53
54 pfd.fd = desc;
55 pfd.events = POLLIN | POLLHUP | POLLOUT;
56
57 (void)poll(&pfd, 1, 2000);
58 (void)printf("child1 exit\n");
59}
60
61static void
62child2(void)
63{
64 struct pollfd pfd;
65
66 pfd.fd = desc;
67 pfd.events = POLLIN | POLLHUP | POLLOUT;
68
69 (void)sleep(1);
70 (void)poll(&pfd, 1, INFTIM);
71 (void)printf("child2 exit\n");
72}
73
74static void
75child3(void)
76{
77 struct pollfd pfd;
78
79 (void)sleep(5);
80
81 pfd.fd = desc;
82 pfd.events = POLLIN | POLLHUP | POLLOUT;
83
84 (void)poll(&pfd, 1, INFTIM);
85 (void)printf("child3 exit\n");
86}
87
88ATF_TC(poll_3way);
89ATF_TC_HEAD(poll_3way, tc)
90{
91 atf_tc_set_md_var(tc, "timeout", "15");
92 atf_tc_set_md_var(tc, "descr",
93 "Check for 3-way collision for descriptor. First child comes "
94 "and polls on descriptor, second child comes and polls, first "
95 "child times out and exits, third child comes and polls. When "
96 "the wakeup event happens, the two remaining children should "
97 "both be awaken. (kern/17517)");
98}
99
100ATF_TC_BODY(poll_3way, tc)
101{
102 int pf[2];
103 int status, i;
104 pid_t pid;
105
106 pipe(pf);
107 desc = pf[0];
108
109 pid = fork();
110 ATF_REQUIRE(pid >= 0);
111
112 if (pid == 0) {
113 (void)close(pf[1]);
114 child1();
115 _exit(0);
116 /* NOTREACHED */
117 }
118
119 pid = fork();
120 ATF_REQUIRE(pid >= 0);
121
122 if (pid == 0) {
123 (void)close(pf[1]);
124 child2();
125 _exit(0);
126 /* NOTREACHED */
127 }
128
129 pid = fork();
130 ATF_REQUIRE( pid >= 0);
131
132 if (pid == 0) {
133 (void)close(pf[1]);
134 child3();
135 _exit(0);
136 /* NOTREACHED */
137 }
138
139 (void)sleep(10);
140
141 (void)printf("parent write\n");
142
143 ATF_REQUIRE(write(pf[1], "konec\n", 6) == 6);
144
145 for(i = 0; i < 3; ++i)
146 (void)wait(&status);
147
148 (void)printf("parent terminated\n");
149}
150
151ATF_TC(poll_basic);
152ATF_TC_HEAD(poll_basic, tc)
153{
154 atf_tc_set_md_var(tc, "timeout", "10");
155 atf_tc_set_md_var(tc, "descr",
156 "Basis functionality test for poll(2)");
157}
158
159ATF_TC_BODY(poll_basic, tc)
160{
161 int fds[2];
162 struct pollfd pfds[2];
163 int ret;
164
165 ATF_REQUIRE_EQ(pipe(fds), 0);
166
167 pfds[0].fd = fds[0];
168 pfds[0].events = POLLIN;
169 pfds[1].fd = fds[1];
170 pfds[1].events = POLLOUT;
171
172 /*
173 * Check that we get a timeout waiting for data on the read end
174 * of our pipe.
175 */
176 pfds[0].revents = -1;
177 pfds[1].revents = -1;
178 ATF_REQUIRE_EQ_MSG(ret = poll(&pfds[0], 1, 1), 0,
179 "got: %d", ret);
180 ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents);
181 ATF_REQUIRE_EQ_MSG(pfds[1].revents, -1, "got: %d", pfds[1].revents);
182
183 /* Check that the write end of the pipe as reported as ready. */
184 pfds[0].revents = -1;
185 pfds[1].revents = -1;
186 ATF_REQUIRE_EQ_MSG(ret = poll(&pfds[1], 1, 1), 1,
187 "got: %d", ret);
188 ATF_REQUIRE_EQ_MSG(pfds[0].revents, -1, "got: %d", pfds[0].revents);
189 ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",\
190 pfds[1].revents);
191
192 /* Check that only the write end of the pipe as reported as ready. */
193 pfds[0].revents = -1;
194 pfds[1].revents = -1;
195 ATF_REQUIRE_EQ_MSG(ret = poll(pfds, 2, 1), 1,
196 "got: %d", ret);
197 ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents);
198 ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",
199 pfds[1].revents);
200
201 /* Write data to our pipe. */
202 ATF_REQUIRE_EQ(write(fds[1], "", 1), 1);
203
204 /* Check that both ends of our pipe are reported as ready. */
205 pfds[0].revents = -1;
206 pfds[1].revents = -1;
207 ATF_REQUIRE_EQ_MSG(ret = poll(pfds, 2, 1), 2,
208 "got: %d", ret);
209 ATF_REQUIRE_EQ_MSG(pfds[0].revents, POLLIN, "got: %d",
210 pfds[0].revents);
211 ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",
212 pfds[1].revents);
213
214 ATF_REQUIRE_EQ(close(fds[0]), 0);
215 ATF_REQUIRE_EQ(close(fds[1]), 0);
216}
217
218ATF_TC(poll_err);
219ATF_TC_HEAD(poll_err, tc)
220{
221 atf_tc_set_md_var(tc, "descr", "Check errors from poll(2)");
222}
223
224ATF_TC_BODY(poll_err, tc)
225{
226 struct pollfd pfd;
227 int fd = 0;
228
229 pfd.fd = fd;
230 pfd.events = POLLIN;
231
232 errno = 0;
233 ATF_REQUIRE_ERRNO(EFAULT, poll((struct pollfd *)-1, 1, -1) == -1);
234
235 errno = 0;
236 ATF_REQUIRE_ERRNO(EINVAL, poll(&pfd, 1, -2) == -1);
237}
238
239ATF_TC(pollts_basic);
240ATF_TC_HEAD(pollts_basic, tc)
241{
242 atf_tc_set_md_var(tc, "timeout", "10");
243 atf_tc_set_md_var(tc, "descr",
244 "Basis functionality test for pollts(2)");
245}
246
247ATF_TC_BODY(pollts_basic, tc)
248{
249 int fds[2];
250 struct pollfd pfds[2];
251 struct timespec timeout;
252 int ret;
253
254 ATF_REQUIRE_EQ(pipe(fds), 0);
255
256 pfds[0].fd = fds[0];
257 pfds[0].events = POLLIN;
258 pfds[1].fd = fds[1];
259 pfds[1].events = POLLOUT;
260
261 /* Use a timeout of 1 second. */
262 timeout.tv_sec = 1;
263 timeout.tv_nsec = 0;
264
265 /*
266 * Check that we get a timeout waiting for data on the read end
267 * of our pipe.
268 */
269 pfds[0].revents = -1;
270 pfds[1].revents = -1;
271 ATF_REQUIRE_EQ_MSG(ret = pollts(&pfds[0], 1, &timeout, NULL), 0,
272 "got: %d", ret);
273 ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents);
274 ATF_REQUIRE_EQ_MSG(pfds[1].revents, -1, "got: %d", pfds[1].revents);
275
276 /* Check that the write end of the pipe as reported as ready. */
277 pfds[0].revents = -1;
278 pfds[1].revents = -1;
279 ATF_REQUIRE_EQ_MSG(ret = pollts(&pfds[1], 1, &timeout, NULL), 1,
280 "got: %d", ret);
281 ATF_REQUIRE_EQ_MSG(pfds[0].revents, -1, "got: %d", pfds[0].revents);
282 ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",\
283 pfds[1].revents);
284
285 /* Check that only the write end of the pipe as reported as ready. */
286 pfds[0].revents = -1;
287 pfds[1].revents = -1;
288 ATF_REQUIRE_EQ_MSG(ret = pollts(pfds, 2, &timeout, NULL), 1,
289 "got: %d", ret);
290 ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents);
291 ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",
292 pfds[1].revents);
293
294 /* Write data to our pipe. */
295 ATF_REQUIRE_EQ(write(fds[1], "", 1), 1);
296
297 /* Check that both ends of our pipe are reported as ready. */
298 pfds[0].revents = -1;
299 pfds[1].revents = -1;
300 ATF_REQUIRE_EQ_MSG(ret = pollts(pfds, 2, &timeout, NULL), 2,
301 "got: %d", ret);
302 ATF_REQUIRE_EQ_MSG(pfds[0].revents, POLLIN, "got: %d",
303 pfds[0].revents);
304 ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",
305 pfds[1].revents);
306
307 ATF_REQUIRE_EQ(close(fds[0]), 0);
308 ATF_REQUIRE_EQ(close(fds[1]), 0);
309}
310
311ATF_TC(pollts_err);
312ATF_TC_HEAD(pollts_err, tc)
313{
314 atf_tc_set_md_var(tc, "descr", "Check errors from pollts(2)");
315}
316
317ATF_TC_BODY(pollts_err, tc)
318{
319 struct timespec timeout;
320 struct pollfd pfd;
321 int fd = 0;
322
323 pfd.fd = fd;
324 pfd.events = POLLIN;
325
326 timeout.tv_sec = 1;
327 timeout.tv_nsec = 0;
328
329 errno = 0;
330 ATF_REQUIRE_ERRNO(EFAULT, pollts((void *)-1, 1, &timeout, NULL) == -1);
331
332 timeout.tv_sec = -1;
333 timeout.tv_nsec = -1;
334
335 errno = 0;
336 ATF_REQUIRE_ERRNO(EINVAL, pollts(&pfd, 1, &timeout, NULL) == -1);
337}
338
339ATF_TC(pollts_sigmask);
340ATF_TC_HEAD(pollts_sigmask, tc)
341{
342 atf_tc_set_md_var(tc, "timeout", "10");
343 atf_tc_set_md_var(tc, "descr",
344 "Check that pollts(2) restores the signal mask (PR kern/44986)");
345}
346
347ATF_TC_BODY(pollts_sigmask, tc)
348{
349 int fd;
350 struct pollfd pfd;
351 struct timespec timeout;
352 sigset_t mask;
353 int ret;
354
355 fd = open(_PATH_DEVNULL, O_RDONLY);
356 ATF_REQUIRE(fd >= 0);
357
358 pfd.fd = fd;
359 pfd.events = POLLIN;
360
361 /* Use a timeout of 1 second. */
362 timeout.tv_sec = 1;
363 timeout.tv_nsec = 0;
364
365 /* Unblock all signals. */
366 ATF_REQUIRE_EQ(sigfillset(&mask), 0);
367 ATF_REQUIRE_EQ(sigprocmask(SIG_UNBLOCK, &mask, NULL), 0);
368
369 /*
370 * Check that pollts(2) immediately returns. We block *all*
371 * signals during pollts(2).
372 */
373 ATF_REQUIRE_EQ_MSG(ret = pollts(&pfd, 1, &timeout, &mask), 1,
374 "got: %d", ret);
375
376 /* Check that signals are now longer blocked. */
377 ATF_REQUIRE_EQ(sigprocmask(SIG_SETMASK, NULL, &mask), 0);
378 ATF_REQUIRE_EQ_MSG(sigismember(&mask, SIGUSR1), 0,
379 "signal mask was changed.");
380
381 ATF_REQUIRE_EQ(close(fd), 0);
382}
383
384ATF_TP_ADD_TCS(tp)
385{
386
387 ATF_TP_ADD_TC(tp, poll_3way);
388 ATF_TP_ADD_TC(tp, poll_basic);
389 ATF_TP_ADD_TC(tp, poll_err);
390 /*
391 * Adjusted for OpenBSD, not supported
392 * ATF_TP_ADD_TC(tp, pollts_basic);
393 * ATF_TP_ADD_TC(tp, pollts_err);
394 * ATF_TP_ADD_TC(tp, pollts_sigmask);
395 */
396
397 return atf_no_error();
398}
diff --git a/src/regress/lib/libc/sys/t_ptrace.c b/src/regress/lib/libc/sys/t_ptrace.c
new file mode 100644
index 0000000000..756c9c514e
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_ptrace.c
@@ -0,0 +1,231 @@
1/* $OpenBSD: t_ptrace.c,v 1.1.1.1 2019/11/19 19:57:04 bluhm Exp $ */
2/* $NetBSD: t_ptrace.c,v 1.4 2018/05/14 12:44:40 kamil Exp $ */
3
4/*-
5 * Copyright (c) 2016 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "macros.h"
31
32#include <sys/cdefs.h>
33__RCSID("$NetBSD: t_ptrace.c,v 1.4 2018/05/14 12:44:40 kamil Exp $");
34
35#include <sys/param.h>
36#include <sys/types.h>
37#include <sys/ptrace.h>
38#include <sys/stat.h>
39#include <sys/sysctl.h>
40#include <err.h>
41#include <errno.h>
42#include <unistd.h>
43
44#include "atf-c.h"
45
46#include "h_macros.h"
47
48/*
49 * A child process cannot call atf functions and expect them to magically
50 * work like in the parent.
51 * The printf(3) messaging from a child will not work out of the box as well
52 * without estabilishing a communication protocol with its parent. To not
53 * overcomplicate the tests - do not log from a child and use err(3)/errx(3)
54 * wrapped with FORKEE_ASSERT()/FORKEE_ASSERTX() as that is guaranteed to work.
55 */
56#define FORKEE_ASSERTX(x) \
57do { \
58 int ret = (x); \
59 if (!ret) \
60 errx(EXIT_FAILURE, "%s:%d %s(): Assertion failed for: %s", \
61 __FILE__, __LINE__, __func__, #x); \
62} while (0)
63
64#define FORKEE_ASSERT(x) \
65do { \
66 int ret = (x); \
67 if (!ret) \
68 err(EXIT_FAILURE, "%s:%d %s(): Assertion failed for: %s", \
69 __FILE__, __LINE__, __func__, #x); \
70} while (0)
71
72ATF_TC(attach_pid0);
73ATF_TC_HEAD(attach_pid0, tc)
74{
75 atf_tc_set_md_var(tc, "descr",
76 "Assert that a debugger cannot attach to PID 0");
77}
78
79ATF_TC_BODY(attach_pid0, tc)
80{
81 errno = 0;
82 ATF_REQUIRE_ERRNO(EPERM, ptrace(PT_ATTACH, 0, NULL, 0) == -1);
83}
84
85ATF_TC(attach_pid1);
86ATF_TC_HEAD(attach_pid1, tc)
87{
88 atf_tc_set_md_var(tc, "descr",
89 "Assert that a debugger cannot attach to PID 1 (as non-root)");
90
91 atf_tc_set_md_var(tc, "require.user", "unprivileged");
92}
93
94ATF_TC_BODY(attach_pid1, tc)
95{
96 ATF_REQUIRE_ERRNO(EPERM, ptrace(PT_ATTACH, 1, NULL, 0) == -1);
97}
98
99ATF_TC(attach_pid1_securelevel);
100ATF_TC_HEAD(attach_pid1_securelevel, tc)
101{
102 atf_tc_set_md_var(tc, "descr",
103 "Assert that a debugger cannot attach to PID 1 with "
104 "securelevel >= 0 (as root)");
105
106 atf_tc_set_md_var(tc, "require.user", "root");
107}
108
109ATF_TC_BODY(attach_pid1_securelevel, tc)
110{
111 int level;
112 size_t len = sizeof(level);
113
114 ATF_REQUIRE(sysctlbyname("kern.securelevel", &level, &len, NULL, 0)
115 != -1);
116
117 if (level < 0) {
118 atf_tc_skip("Test must be run with securelevel >= 0");
119 }
120
121 ATF_REQUIRE_ERRNO(EPERM, ptrace(PT_ATTACH, 1, NULL, 0) == -1);
122}
123
124ATF_TC(attach_self);
125ATF_TC_HEAD(attach_self, tc)
126{
127 atf_tc_set_md_var(tc, "descr",
128 "Assert that a debugger cannot attach to self (as it's nonsense)");
129}
130
131ATF_TC_BODY(attach_self, tc)
132{
133 ATF_REQUIRE_ERRNO(EINVAL, ptrace(PT_ATTACH, getpid(), NULL, 0) == -1);
134}
135
136ATF_TC(attach_chroot);
137ATF_TC_HEAD(attach_chroot, tc)
138{
139 atf_tc_set_md_var(tc, "descr",
140 "Assert that a debugger cannot trace another process unless the "
141 "process's root directory is at or below the tracing process's "
142 "root");
143
144 atf_tc_set_md_var(tc, "require.user", "root");
145}
146
147ATF_TC_BODY(attach_chroot, tc)
148{
149 char buf[PATH_MAX];
150 pid_t child;
151 int fds_toparent[2], fds_fromparent[2];
152 int rv;
153 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
154
155 (void)memset(buf, '\0', sizeof(buf));
156 ATF_REQUIRE(getcwd(buf, sizeof(buf)) != NULL);
157 (void)strlcat(buf, "/dir", sizeof(buf));
158
159 ATF_REQUIRE(mkdir(buf, 0500) == 0);
160 ATF_REQUIRE(chdir(buf) == 0);
161
162 ATF_REQUIRE(pipe(fds_toparent) == 0);
163 ATF_REQUIRE(pipe(fds_fromparent) == 0);
164 child = atf_utils_fork();
165 if (child == 0) {
166 FORKEE_ASSERT(close(fds_toparent[0]) == 0);
167 FORKEE_ASSERT(close(fds_fromparent[1]) == 0);
168
169 FORKEE_ASSERT(chroot(buf) == 0);
170
171 rv = write(fds_toparent[1], &msg, sizeof(msg));
172 FORKEE_ASSERTX(rv == sizeof(msg));
173
174 ATF_REQUIRE_ERRNO(EPERM,
175 ptrace(PT_ATTACH, getppid(), NULL, 0) == -1);
176
177 rv = read(fds_fromparent[0], &msg, sizeof(msg));
178 FORKEE_ASSERTX(rv == sizeof(msg));
179
180 _exit(0);
181 }
182 ATF_REQUIRE(close(fds_toparent[1]) == 0);
183 ATF_REQUIRE(close(fds_fromparent[0]) == 0);
184
185 printf("Waiting for chrooting of the child PID %d", child);
186 rv = read(fds_toparent[0], &msg, sizeof(msg));
187 ATF_REQUIRE(rv == sizeof(msg));
188
189 printf("Child is ready, it will try to PT_ATTACH to parent\n");
190 rv = write(fds_fromparent[1], &msg, sizeof(msg));
191 ATF_REQUIRE(rv == sizeof(msg));
192
193 printf("fds_fromparent is no longer needed - close it\n");
194 ATF_REQUIRE(close(fds_fromparent[1]) == 0);
195
196 printf("fds_toparent is no longer needed - close it\n");
197 ATF_REQUIRE(close(fds_toparent[0]) == 0);
198}
199
200ATF_TC(traceme_twice);
201ATF_TC_HEAD(traceme_twice, tc)
202{
203 atf_tc_set_md_var(tc, "descr",
204 "Assert that a process cannot mark its parent a debugger twice");
205}
206
207ATF_TC_BODY(traceme_twice, tc)
208{
209
210 printf("Mark the parent process (PID %d) a debugger of PID %d",
211 getppid(), getpid());
212 ATF_REQUIRE(ptrace(PT_TRACE_ME, 0, NULL, 0) == 0);
213
214 printf("Mark the parent process (PID %d) a debugger of PID %d again",
215 getppid(), getpid());
216 ATF_REQUIRE_ERRNO(EBUSY, ptrace(PT_TRACE_ME, 0, NULL, 0) == -1);
217}
218
219ATF_TP_ADD_TCS(tp)
220{
221 setvbuf(stdout, NULL, _IONBF, 0);
222 setvbuf(stderr, NULL, _IONBF, 0);
223 ATF_TP_ADD_TC(tp, attach_pid0);
224 ATF_TP_ADD_TC(tp, attach_pid1);
225 ATF_TP_ADD_TC(tp, attach_pid1_securelevel);
226 ATF_TP_ADD_TC(tp, attach_self);
227 ATF_TP_ADD_TC(tp, attach_chroot);
228 ATF_TP_ADD_TC(tp, traceme_twice);
229
230 return atf_no_error();
231}
diff --git a/src/regress/lib/libc/sys/t_revoke.c b/src/regress/lib/libc/sys/t_revoke.c
new file mode 100644
index 0000000000..ad54f814d1
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_revoke.c
@@ -0,0 +1,198 @@
1/* $OpenBSD: t_revoke.c,v 1.1.1.1 2019/11/19 19:57:04 bluhm Exp $ */
2/* $NetBSD: t_revoke.c,v 1.2 2017/01/13 21:15:57 christos Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_revoke.c,v 1.2 2017/01/13 21:15:57 christos Exp $");
37
38#include <sys/resource.h>
39#include <sys/wait.h>
40
41#include "atf-c.h"
42#include <fcntl.h>
43#include <errno.h>
44#include <pwd.h>
45#include <stdio.h>
46#include <stdlib.h>
47#include <string.h>
48#include <unistd.h>
49
50static const char path[] = "revoke";
51
52ATF_TC_WITH_CLEANUP(revoke_basic);
53ATF_TC_HEAD(revoke_basic, tc)
54{
55 atf_tc_set_md_var(tc, "descr", "A basic test of revoke(2)");
56}
57
58ATF_TC_BODY(revoke_basic, tc)
59{
60 struct rlimit res;
61 char tmp[10];
62 size_t i, n;
63 int *buf;
64
65 (void)memset(&res, 0, sizeof(struct rlimit));
66 (void)getrlimit(RLIMIT_NOFILE, &res);
67
68 if ((n = res.rlim_cur / 10) == 0)
69 n = 10;
70
71 buf = calloc(n, sizeof(int));
72 ATF_REQUIRE(buf != NULL);
73
74 buf[0] = open(path, O_RDWR | O_CREAT, 0600);
75 ATF_REQUIRE(buf[0] >= 0);
76
77 for (i = 1; i < n; i++) {
78 buf[i] = open(path, O_RDWR);
79 ATF_REQUIRE(buf[i] >= 0);
80 }
81
82 ATF_REQUIRE(revoke(path) == 0);
83
84 for (i = 0; i < n; i++) {
85
86 ATF_REQUIRE(read(buf[i], tmp, sizeof(tmp)) == -1);
87
88 (void)close(buf[i]);
89 }
90
91 free(buf);
92
93 (void)unlink(path);
94}
95
96ATF_TC_CLEANUP(revoke_basic, tc)
97{
98 (void)unlink(path);
99}
100
101ATF_TC(revoke_err);
102ATF_TC_HEAD(revoke_err, tc)
103{
104 atf_tc_set_md_var(tc, "descr", "Test errors from revoke(2)");
105 atf_tc_set_md_var(tc, "require.user", "unprivileged");
106}
107
108ATF_TC_BODY(revoke_err, tc)
109{
110 char buf[1024 + 1]; /* XXX: From the manual page... */
111
112 (void)memset(buf, 'x', sizeof(buf));
113
114 errno = 0;
115 ATF_REQUIRE_ERRNO(EFAULT, revoke((char *)-1) == -1);
116
117 errno = 0;
118 ATF_REQUIRE_ERRNO(ENAMETOOLONG, revoke(buf) == -1);
119
120 errno = 0;
121 /* Adjusted for OpenBSD, initially EPERM */
122 ATF_REQUIRE_ERRNO(ENOTTY, revoke("/etc/passwd") == -1);
123
124 errno = 0;
125 ATF_REQUIRE_ERRNO(ENOENT, revoke("/etc/xxx/yyy") == -1);
126}
127
128ATF_TC_WITH_CLEANUP(revoke_perm);
129ATF_TC_HEAD(revoke_perm, tc)
130{
131 atf_tc_set_md_var(tc, "descr", "Test permissions revoke(2)");
132 atf_tc_set_md_var(tc, "require.user", "root");
133}
134
135ATF_TC_BODY(revoke_perm, tc)
136{
137 struct passwd *pw;
138 int fd, sta;
139 pid_t pid;
140
141 pw = getpwnam("nobody");
142 fd = open(path, O_RDWR | O_CREAT, 0600);
143
144 ATF_REQUIRE(fd >= 0);
145 ATF_REQUIRE(pw != NULL);
146 ATF_REQUIRE(revoke(path) == 0);
147
148 pid = fork();
149 ATF_REQUIRE(pid >= 0);
150
151 if (pid == 0) {
152
153 if (setuid(pw->pw_uid) != 0)
154 _exit(EXIT_FAILURE);
155
156 errno = 0;
157
158 if (revoke(path) == 0)
159 _exit(EXIT_FAILURE);
160
161 if (errno != EACCES)
162 _exit(EXIT_FAILURE);
163
164 if (close(fd) != 0)
165 _exit(EXIT_FAILURE);
166
167 _exit(EXIT_SUCCESS);
168 }
169
170 (void)wait(&sta);
171
172 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
173 atf_tc_fail("revoke(2) did not obey permissions");
174
175 (void)close(fd);
176 ATF_REQUIRE(unlink(path) == 0);
177}
178
179ATF_TC_CLEANUP(revoke_perm, tc)
180{
181 (void)unlink(path);
182}
183
184ATF_TP_ADD_TCS(tp)
185{
186
187 /*
188 * Adjusted for OpenBSD, revoke only on ttys supported
189 * ATF_TP_ADD_TC(tp, revoke_basic);
190 */
191 ATF_TP_ADD_TC(tp, revoke_err);
192 /*
193 * Adjusted for OpenBSD, revoke only on ttys supported
194 * ATF_TP_ADD_TC(tp, revoke_perm);
195 */
196
197 return atf_no_error();
198}
diff --git a/src/regress/lib/libc/sys/t_select.c b/src/regress/lib/libc/sys/t_select.c
new file mode 100644
index 0000000000..94ff3d3410
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_select.c
@@ -0,0 +1,219 @@
1/* $OpenBSD: t_select.c,v 1.1.1.1 2019/11/19 19:57:04 bluhm Exp $ */
2/* $NetBSD: t_select.c,v 1.4 2017/01/13 21:18:33 christos Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundatiom
9 * by Christos Zoulas.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <assert.h>
36#include <sys/types.h>
37#include <sys/select.h>
38#include <sys/wait.h>
39#include <err.h>
40#include <stdio.h>
41#include <string.h>
42#include <signal.h>
43#include <stdlib.h>
44#include <unistd.h>
45#include <errno.h>
46#include <fcntl.h>
47
48#include "atf-c.h"
49
50static sig_atomic_t keep_going = 1;
51
52static void
53sig_handler(int signum __unused)
54{
55 keep_going = 0;
56}
57
58static void
59sigchld(int signum __unused)
60{
61}
62
63static char
64xtoa(uint8_t n)
65{
66 static const char xarray[] = "0123456789abcdef";
67 assert(n < sizeof(xarray));
68 return xarray[n];
69}
70
71static const char *
72prmask(const sigset_t *m, char *buf, size_t len)
73{
74 size_t j = 2;
75 assert(len >= 3 + sizeof(*m));
76 buf[0] = '0';
77 buf[1] = 'x';
78#define N(p, a) (((p) >> ((a) * 4)) & 0xf)
79 /* Adjusted for OpenBSD, on NetBSD sigset_t is a struct */
80 uint32_t p = (*m);
81 for (size_t k = sizeof(p); k > 0; k--)
82 buf[j++] = xtoa(N(p, k - 1));
83 buf[j] = '\0';
84 return buf;
85}
86
87static __dead void
88child(const struct timespec *ts)
89{
90 struct sigaction sa;
91 sigset_t set, oset, nset;
92 char obuf[sizeof(oset) + 3], nbuf[sizeof(nset) + 3];
93 int fd;
94
95 memset(&sa, 0, sizeof(sa));
96 sa.sa_handler = sig_handler;
97 if ((fd = open("/dev/null", O_RDONLY)) == -1)
98 err(1, "open");
99
100 if (sigaction(SIGTERM, &sa, NULL) == -1)
101 err(1, "sigaction");
102
103 sigfillset(&set);
104 if (sigprocmask(SIG_BLOCK, &set, NULL) == -1)
105 err(1, "sigprocmask");
106
107 if (sigprocmask(SIG_BLOCK, NULL, &oset) == -1)
108 err(1, "sigprocmask");
109
110 sigemptyset(&set);
111
112 for (;;) {
113 fd_set rset;
114 FD_ZERO(&rset);
115 FD_SET(fd, &rset);
116 if (pselect(1, &rset, NULL, NULL, ts, &set) == -1) {
117 if(errno == EINTR) {
118 if (!keep_going)
119 break;
120 }
121 }
122 if (ts)
123 break;
124 }
125 if (sigprocmask(SIG_BLOCK, NULL, &nset) == -1)
126 err(1, "sigprocmask");
127 if (memcmp(&oset, &nset, sizeof(oset)) != 0)
128 atf_tc_fail("pselect() masks don't match "
129 "after timeout %s != %s",
130 prmask(&nset, nbuf, sizeof(nbuf)),
131 prmask(&oset, obuf, sizeof(obuf)));
132 _exit(0);
133}
134
135ATF_TC(pselect_sigmask);
136ATF_TC_HEAD(pselect_sigmask, tc)
137{
138 atf_tc_set_md_var(tc, "descr", "Checks pselect's temporary mask "
139 "setting when a signal is received (PR lib/43625)");
140}
141
142ATF_TC_BODY(pselect_sigmask, tc)
143{
144 pid_t pid;
145 int status;
146
147 signal(SIGCHLD, sigchld);
148
149 switch (pid = fork()) {
150 case 0:
151 child(NULL);
152 /*NOTREACHED*/
153 case -1:
154 err(1, "fork");
155 default:
156 sleep(1);
157 if (kill(pid, SIGTERM) == -1)
158 err(1, "kill");
159 sleep(1);
160 switch (waitpid(pid, &status, WNOHANG)) {
161 case -1:
162 err(1, "wait");
163 case 0:
164 if (kill(pid, SIGKILL) == -1)
165 err(1, "kill");
166 atf_tc_fail("pselect() did not receive signal");
167 break;
168 default:
169 break;
170 }
171 }
172}
173
174ATF_TC(pselect_timeout);
175ATF_TC_HEAD(pselect_timeout, tc)
176{
177
178 atf_tc_set_md_var(tc, "descr", "Checks pselect's temporary mask "
179 "setting when a timeout occurs");
180}
181
182ATF_TC_BODY(pselect_timeout, tc)
183{
184 pid_t pid;
185 int status;
186 static const struct timespec zero = { 0, 0 };
187
188 signal(SIGCHLD, sigchld);
189
190 switch (pid = fork()) {
191 case 0:
192 child(&zero);
193 break;
194 case -1:
195 err(1, "fork");
196 default:
197 sleep(1);
198 switch (waitpid(pid, &status, WNOHANG)) {
199 case -1:
200 err(1, "wait");
201 case 0:
202 if (kill(pid, SIGKILL) == -1)
203 err(1, "kill");
204 atf_tc_fail("pselect() did not receive signal");
205 break;
206 default:
207 break;
208 }
209 }
210}
211
212ATF_TP_ADD_TCS(tp)
213{
214
215 ATF_TP_ADD_TC(tp, pselect_sigmask);
216 ATF_TP_ADD_TC(tp, pselect_timeout);
217
218 return atf_no_error();
219}
diff --git a/src/regress/lib/libc/sys/t_sendrecv.c b/src/regress/lib/libc/sys/t_sendrecv.c
new file mode 100644
index 0000000000..cf44af2b3e
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_sendrecv.c
@@ -0,0 +1,186 @@
1/* $OpenBSD: t_sendrecv.c,v 1.1.1.1 2019/11/19 19:57:04 bluhm Exp $ */
2/* $NetBSD: t_sendrecv.c,v 1.6 2019/02/03 03:19:28 mrg Exp $ */
3
4/*-
5 * Copyright (c) 2018 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Christos Zoulas.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_sendrecv.c,v 1.6 2019/02/03 03:19:28 mrg Exp $");
37
38#include "atf-c.h"
39#include <sys/types.h>
40#include <sys/socket.h>
41
42#include <string.h>
43#include <stdint.h>
44#include <errno.h>
45#include <stdio.h>
46#include <stdlib.h>
47#include <unistd.h>
48#include <sched.h>
49#include <signal.h>
50
51
52#define COUNT 100
53
54union packet {
55 uint8_t buf[1316];
56 uintmax_t seq;
57};
58
59static volatile sig_atomic_t rdied;
60
61static void
62handle_sigchld(__unused int pid)
63{
64
65 rdied = 1;
66}
67
68static void
69sender(int fd)
70{
71 union packet p;
72 ssize_t n;
73 p.seq = 0;
74 for (size_t i = 0; i < COUNT; i++) {
75 for (; (n = send(fd, &p, sizeof(p), 0)) == sizeof(p);
76 p.seq++)
77 continue;
78 printf(">>%zd %d %ju\n", n, errno, p.seq);
79 ATF_REQUIRE_MSG(errno == ENOBUFS, "send %s", strerror(errno));
80// sched_yield();
81 }
82 printf("sender done\n");
83}
84
85static void
86receiver(int fd)
87{
88 union packet p;
89 ssize_t n;
90 uintmax_t seq = 0;
91
92 do {
93 if (rdied)
94 return;
95 while ((n = recv(fd, &p, sizeof(p), 0), sizeof(p))
96 == sizeof(p))
97 {
98 if (rdied)
99 return;
100 if (p.seq != seq)
101 printf("%ju != %ju\n", p.seq, seq);
102 seq = p.seq + 1;
103 }
104 printf("<<%zd %d %ju\n", n, errno, seq);
105 if (n == 0)
106 return;
107 ATF_REQUIRE_EQ(n, -1);
108 ATF_REQUIRE_MSG(errno == ENOBUFS, "recv %s", strerror(errno));
109 } while (p.seq < COUNT);
110}
111
112static void
113sendrecv(int rerror)
114{
115 int fd[2], error;
116 struct sigaction sa;
117
118 error = socketpair(AF_UNIX, SOCK_DGRAM, 0, fd);
119// error = pipe(fd);
120 ATF_REQUIRE_MSG(error != -1, "socketpair failed (%s)", strerror(errno));
121
122 for (size_t i = 0; i < __arraycount(fd); i++) {
123 error = setsockopt(fd[i], SOL_SOCKET, SO_RERROR, &rerror,
124 sizeof(rerror));
125 ATF_REQUIRE_MSG(error != -1,
126 "setsockopt(SO_RERROR) failed (%s)", strerror(errno));
127 }
128
129 memset(&sa, 0, sizeof(sa));
130 sa.sa_flags = 0;
131 sa.sa_handler = &handle_sigchld;
132 sigemptyset(&sa.sa_mask);
133 error = sigaction(SIGCHLD, &sa, 0);
134 ATF_REQUIRE_MSG(error != -1, "sigaction failed (%s)",
135 strerror(errno));
136
137 switch (fork()) {
138 case -1:
139 ATF_REQUIRE_MSG(errno == 0,
140 "socketpair failed (%s)", strerror(errno));
141 __unreachable();
142 /*NOTREACHED*/
143 case 0:
144 sched_yield();
145 sender(fd[0]);
146 close(fd[0]);
147 exit(EXIT_SUCCESS);
148 /*NOTREACHED*/
149 default:
150 receiver(fd[1]);
151 return;
152 }
153}
154
155ATF_TC(sendrecv_basic);
156
157ATF_TC_HEAD(sendrecv_basic, tc)
158{
159 atf_tc_set_md_var(tc, "descr", "A basic test of send/recv(2)");
160}
161
162ATF_TC_BODY(sendrecv_basic, tc)
163{
164 sendrecv(0);
165}
166
167ATF_TC(sendrecv_rerror);
168
169ATF_TC_HEAD(sendrecv_rerror, tc)
170{
171 atf_tc_set_md_var(tc, "descr", "Test send/recv(2) with receiver error");
172}
173
174ATF_TC_BODY(sendrecv_rerror, tc)
175{
176 sendrecv(1);
177}
178
179ATF_TP_ADD_TCS(tp)
180{
181
182 ATF_TP_ADD_TC(tp, sendrecv_basic);
183 ATF_TP_ADD_TC(tp, sendrecv_rerror);
184
185 return atf_no_error();
186}
diff --git a/src/regress/lib/libc/sys/t_setuid.c b/src/regress/lib/libc/sys/t_setuid.c
new file mode 100644
index 0000000000..7d3bd1986b
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_setuid.c
@@ -0,0 +1,126 @@
1/* $OpenBSD: t_setuid.c,v 1.1.1.1 2019/11/19 19:57:04 bluhm Exp $ */
2/* $NetBSD: t_setuid.c,v 1.1 2011/07/07 06:57:54 jruoho Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_setuid.c,v 1.1 2011/07/07 06:57:54 jruoho Exp $");
37
38#include <sys/wait.h>
39
40#include "atf-c.h"
41#include <errno.h>
42#include <pwd.h>
43#include <stdlib.h>
44#include <unistd.h>
45
46ATF_TC(setuid_perm);
47ATF_TC_HEAD(setuid_perm, tc)
48{
49 atf_tc_set_md_var(tc, "descr", "Test setuid(0) as normal user");
50 atf_tc_set_md_var(tc, "require.user", "unprivileged");
51}
52
53ATF_TC_BODY(setuid_perm, tc)
54{
55 errno = 0;
56
57 ATF_REQUIRE(setuid(0) == -1);
58 ATF_REQUIRE(errno == EPERM);
59}
60
61ATF_TC(setuid_real);
62ATF_TC_HEAD(setuid_real, tc)
63{
64 atf_tc_set_md_var(tc, "descr", "Test setuid(2) with real UID");
65}
66
67ATF_TC_BODY(setuid_real, tc)
68{
69 uid_t uid = getuid();
70
71 ATF_REQUIRE(setuid(uid) == 0);
72
73 ATF_REQUIRE(getuid() == uid);
74 ATF_REQUIRE(geteuid() == uid);
75}
76
77ATF_TC(setuid_root);
78ATF_TC_HEAD(setuid_root, tc)
79{
80 atf_tc_set_md_var(tc, "descr", "A basic test of setuid(2)");
81 atf_tc_set_md_var(tc, "require.user", "root");
82}
83
84ATF_TC_BODY(setuid_root, tc)
85{
86 struct passwd *pw;
87 int rv, sta;
88 pid_t pid;
89 uid_t uid;
90
91 while ((pw = getpwent()) != NULL) {
92
93 pid = fork();
94 ATF_REQUIRE(pid >= 0);
95
96 if (pid == 0) {
97
98 rv = setuid(pw->pw_uid);
99
100 if (rv != 0)
101 _exit(EXIT_FAILURE);
102
103 uid = getuid();
104
105 if (uid != pw->pw_uid)
106 _exit(EXIT_FAILURE);
107
108 _exit(EXIT_SUCCESS);
109 }
110
111 (void)wait(&sta);
112
113 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
114 atf_tc_fail("failed to change UID to %u", pw->pw_uid);
115 }
116}
117
118ATF_TP_ADD_TCS(tp)
119{
120
121 ATF_TP_ADD_TC(tp, setuid_perm);
122 ATF_TP_ADD_TC(tp, setuid_real);
123 ATF_TP_ADD_TC(tp, setuid_root);
124
125 return atf_no_error();
126}
diff --git a/src/regress/lib/libc/sys/t_sigaction.c b/src/regress/lib/libc/sys/t_sigaction.c
new file mode 100644
index 0000000000..21c793d74a
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_sigaction.c
@@ -0,0 +1,156 @@
1/* $OpenBSD: t_sigaction.c,v 1.1.1.1 2019/11/19 19:57:04 bluhm Exp $ */
2/* $NetBSD: t_sigaction.c,v 1.5 2017/01/13 21:30:41 christos Exp $ */
3
4/*-
5 * Copyright (c) 2010 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "macros.h"
31
32#include <sys/cdefs.h>
33__COPYRIGHT("@(#) Copyright (c) 2010\
34 The NetBSD Foundation, inc. All rights reserved.");
35__RCSID("$NetBSD: t_sigaction.c,v 1.5 2017/01/13 21:30:41 christos Exp $");
36
37#include <sys/wait.h>
38
39#include <signal.h>
40#include <stdbool.h>
41#include <stdlib.h>
42#include <string.h>
43#include <unistd.h>
44
45#include "atf-c.h"
46
47#include "h_macros.h"
48
49static bool handler_called = false;
50
51static void
52handler(int signo __unused)
53{
54 handler_called = true;
55}
56
57static void
58sa_resethand_child(const int flags)
59{
60 struct sigaction sa;
61
62 sa.sa_flags = flags;
63 sa.sa_handler = &handler;
64 sigemptyset(&sa.sa_mask);
65
66 sigaction(SIGUSR1, &sa, NULL);
67 kill(getpid(), SIGUSR1);
68 exit(handler_called ? EXIT_SUCCESS : EXIT_FAILURE);
69}
70
71static void
72wait_and_check_child(const pid_t pid, const char *fail_message)
73{
74 int status;
75
76 (void)waitpid(pid, &status, 0);
77
78 if (WIFEXITED(status))
79 ATF_CHECK_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
80 else
81 atf_tc_fail("%s; raw exit status was %d", fail_message, status);
82}
83
84static void
85catch(int sig __unused)
86{
87 return;
88}
89
90ATF_TC(sigaction_basic);
91ATF_TC_HEAD(sigaction_basic, tc)
92{
93
94 atf_tc_set_md_var(tc, "descr", "Checks for correct I&D cache"
95 "synchronization after copying out the trampoline code.");
96}
97
98ATF_TC_BODY(sigaction_basic, tc)
99{
100 static struct sigaction sa;
101
102 sa.sa_handler = catch;
103
104 sigaction(SIGUSR1, &sa, 0);
105 kill(getpid(), SIGUSR1);
106 atf_tc_pass();
107}
108
109ATF_TC(sigaction_noflags);
110ATF_TC_HEAD(sigaction_noflags, tc)
111{
112 atf_tc_set_md_var(tc, "descr", "Checks programming a signal with "
113 "sigaction(2) but without any flags");
114}
115
116ATF_TC_BODY(sigaction_noflags, tc)
117{
118 const pid_t pid = fork();
119 if (pid == -1)
120 atf_tc_fail_errno("fork(2) failed");
121 else if (pid == 0)
122 sa_resethand_child(0);
123 else
124 wait_and_check_child(pid, "Child process did not exit cleanly;"
125 " it failed to process the signal");
126}
127
128ATF_TC(sigaction_resethand);
129ATF_TC_HEAD(sigaction_resethand, tc)
130{
131 atf_tc_set_md_var(tc, "descr", "Checks that SA_RESETHAND works");
132}
133
134ATF_TC_BODY(sigaction_resethand, tc)
135{
136 const pid_t pid = fork();
137 if (pid == -1)
138 atf_tc_fail_errno("fork(2) failed");
139 else if (pid == 0)
140 sa_resethand_child(SA_RESETHAND);
141 else {
142 wait_and_check_child(pid, "Child process did not exit cleanly;"
143 " it either failed to process the signal or SA_RESETHAND"
144 " is broken");
145 }
146}
147
148ATF_TP_ADD_TCS(tp)
149{
150
151 ATF_TP_ADD_TC(tp, sigaction_basic);
152 ATF_TP_ADD_TC(tp, sigaction_noflags);
153 ATF_TP_ADD_TC(tp, sigaction_resethand);
154
155 return atf_no_error();
156}
diff --git a/src/regress/lib/libc/sys/t_socketpair.c b/src/regress/lib/libc/sys/t_socketpair.c
new file mode 100644
index 0000000000..076d2fa057
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_socketpair.c
@@ -0,0 +1,141 @@
1/* $OpenBSD: t_socketpair.c,v 1.1.1.1 2019/11/19 19:57:04 bluhm Exp $ */
2/* $NetBSD: t_socketpair.c,v 1.2 2017/01/13 20:04:52 christos Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Christos Zoulas.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the NetBSD
22 * Foundation, Inc. and its contributors.
23 * 4. Neither the name of The NetBSD Foundation nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40#include "macros.h"
41
42#include <sys/cdefs.h>
43__RCSID("$NetBSD: t_socketpair.c,v 1.2 2017/01/13 20:04:52 christos Exp $");
44
45#include "atf-c.h"
46#include <fcntl.h>
47#include <unistd.h>
48#include <stdlib.h>
49#include <sys/socket.h>
50#include <sys/un.h>
51#include <errno.h>
52
53static void
54connected(int fd)
55{
56 struct sockaddr_un addr;
57 socklen_t len = (socklen_t)sizeof(addr);
58 ATF_REQUIRE(getpeername(fd, (struct sockaddr*)(void *)&addr,
59 &len) == 0);
60}
61
62static void
63run(int flags)
64{
65 int fd[2], i;
66
67 while ((i = open("/", O_RDONLY)) < 3)
68 ATF_REQUIRE(i != -1);
69
70 ATF_REQUIRE(closefrom(3) != -1);
71
72 ATF_REQUIRE(socketpair(AF_UNIX, SOCK_DGRAM | flags, 0, fd) == 0);
73
74 ATF_REQUIRE(fd[0] == 3);
75 ATF_REQUIRE(fd[1] == 4);
76
77 connected(fd[0]);
78 connected(fd[1]);
79
80 if (flags & SOCK_CLOEXEC) {
81 ATF_REQUIRE((fcntl(fd[0], F_GETFD) & FD_CLOEXEC) != 0);
82 ATF_REQUIRE((fcntl(fd[1], F_GETFD) & FD_CLOEXEC) != 0);
83 } else {
84 ATF_REQUIRE((fcntl(fd[0], F_GETFD) & FD_CLOEXEC) == 0);
85 ATF_REQUIRE((fcntl(fd[1], F_GETFD) & FD_CLOEXEC) == 0);
86 }
87
88 if (flags & SOCK_NONBLOCK) {
89 ATF_REQUIRE((fcntl(fd[0], F_GETFL) & O_NONBLOCK) != 0);
90 ATF_REQUIRE((fcntl(fd[1], F_GETFL) & O_NONBLOCK) != 0);
91 } else {
92 ATF_REQUIRE((fcntl(fd[0], F_GETFL) & O_NONBLOCK) == 0);
93 ATF_REQUIRE((fcntl(fd[1], F_GETFL) & O_NONBLOCK) == 0);
94 }
95
96 ATF_REQUIRE(close(fd[0]) != -1);
97 ATF_REQUIRE(close(fd[1]) != -1);
98}
99
100ATF_TC(socketpair_basic);
101ATF_TC_HEAD(socketpair_basic, tc)
102{
103 atf_tc_set_md_var(tc, "descr", "A basic test of socketpair(2)");
104}
105
106ATF_TC_BODY(socketpair_basic, tc)
107{
108 run(0);
109}
110
111ATF_TC(socketpair_nonblock);
112ATF_TC_HEAD(socketpair_nonblock, tc)
113{
114 atf_tc_set_md_var(tc, "descr", "A non-blocking test of socketpair(2)");
115}
116
117ATF_TC_BODY(socketpair_nonblock, tc)
118{
119 run(SOCK_NONBLOCK);
120}
121
122ATF_TC(socketpair_cloexec);
123ATF_TC_HEAD(socketpair_cloexec, tc)
124{
125 atf_tc_set_md_var(tc, "descr", "A close-on-exec of socketpair(2)");
126}
127
128ATF_TC_BODY(socketpair_cloexec, tc)
129{
130 run(SOCK_CLOEXEC);
131}
132
133ATF_TP_ADD_TCS(tp)
134{
135
136 ATF_TP_ADD_TC(tp, socketpair_basic);
137 ATF_TP_ADD_TC(tp, socketpair_nonblock);
138 ATF_TP_ADD_TC(tp, socketpair_cloexec);
139
140 return atf_no_error();
141}
diff --git a/src/regress/lib/libc/sys/t_stat.c b/src/regress/lib/libc/sys/t_stat.c
new file mode 100644
index 0000000000..ea7f4b24a2
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_stat.c
@@ -0,0 +1,423 @@
1/* $OpenBSD: t_stat.c,v 1.1.1.1 2019/11/19 19:57:04 bluhm Exp $ */
2/* $NetBSD: t_stat.c,v 1.5 2017/01/13 20:06:50 christos Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_stat.c,v 1.5 2017/01/13 20:06:50 christos Exp $");
37
38#include <sys/stat.h>
39#include <sys/socket.h>
40#include <sys/types.h>
41
42#include <arpa/inet.h>
43#include <netinet/in.h>
44
45#include "atf-c.h"
46#include <errno.h>
47#include <fcntl.h>
48#include <fts.h>
49#include <limits.h>
50#include <string.h>
51#include <unistd.h>
52
53#include <stdio.h>
54
55static const char *path = "stat";
56
57ATF_TC_WITH_CLEANUP(stat_chflags);
58ATF_TC_HEAD(stat_chflags, tc)
59{
60 atf_tc_set_md_var(tc, "descr", "Test chflags(2) with stat(2)");
61}
62
63ATF_TC_BODY(stat_chflags, tc)
64{
65 struct stat sa, sb;
66 int fd;
67
68 (void)memset(&sa, 0, sizeof(struct stat));
69 (void)memset(&sb, 0, sizeof(struct stat));
70
71 fd = open(path, O_RDONLY | O_CREAT);
72
73 ATF_REQUIRE(fd != -1);
74 ATF_REQUIRE(stat(path, &sa) == 0);
75 ATF_REQUIRE(chflags(path, UF_NODUMP) == 0);
76 ATF_REQUIRE(stat(path, &sb) == 0);
77
78 if (sa.st_flags == sb.st_flags)
79 atf_tc_fail("stat(2) did not detect chflags(2)");
80
81 ATF_REQUIRE(close(fd) == 0);
82 ATF_REQUIRE(unlink(path) == 0);
83}
84
85ATF_TC_CLEANUP(stat_chflags, tc)
86{
87 (void)unlink(path);
88}
89
90ATF_TC(stat_dir);
91ATF_TC_HEAD(stat_dir, tc)
92{
93 atf_tc_set_md_var(tc, "descr", "Test stat(2) with directories");
94}
95
96ATF_TC_BODY(stat_dir, tc)
97{
98 const short depth = 2;
99 struct stat sa, sb;
100 char *argv[2];
101 FTSENT *ftse;
102 FTS *fts;
103 int ops;
104
105 argv[1] = NULL;
106 argv[0] = __UNCONST("/");
107
108 ops = FTS_NOCHDIR;
109 ops |= FTS_PHYSICAL;
110
111 fts = fts_open(argv, ops, NULL);
112 ATF_REQUIRE(fts != NULL);
113
114 while ((ftse = fts_read(fts)) != NULL) {
115
116 if (ftse->fts_level < 1)
117 continue;
118
119 if (ftse->fts_level > depth) {
120 (void)fts_set(fts, ftse, FTS_SKIP);
121 continue;
122 }
123
124 switch(ftse->fts_info) {
125
126 case FTS_DP:
127
128 (void)memset(&sa, 0, sizeof(struct stat));
129 (void)memset(&sb, 0, sizeof(struct stat));
130
131 ATF_REQUIRE(stat(ftse->fts_parent->fts_path,&sa) == 0);
132 ATF_REQUIRE(chdir(ftse->fts_path) == 0);
133 ATF_REQUIRE(stat(".", &sb) == 0);
134
135 /*
136 * The previous two stat(2) calls
137 * should be for the same directory.
138 */
139 if (sa.st_dev != sb.st_dev || sa.st_ino != sb.st_ino)
140 atf_tc_fail("inconsistent stat(2)");
141
142 /*
143 * Check that fts(3)'s stat(2)
144 * call equals the manual one.
145 */
146 if (sb.st_ino != ftse->fts_statp->st_ino)
147 atf_tc_fail("stat(2) and fts(3) differ");
148
149 break;
150
151 default:
152 break;
153 }
154 }
155
156 (void)fts_close(fts);
157}
158
159ATF_TC(stat_err);
160ATF_TC_HEAD(stat_err, tc)
161{
162 atf_tc_set_md_var(tc, "descr", "Test errors from the stat(2) family");
163}
164
165ATF_TC_BODY(stat_err, tc)
166{
167 char buf[NAME_MAX + 1];
168 struct stat st;
169
170 (void)memset(buf, 'x', sizeof(buf));
171
172 errno = 0;
173 ATF_REQUIRE_ERRNO(EBADF, fstat(-1, &st) == -1);
174
175 errno = 0;
176 ATF_REQUIRE_ERRNO(ENAMETOOLONG, stat(buf, &st) == -1);
177
178 errno = 0;
179 ATF_REQUIRE_ERRNO(ENAMETOOLONG, lstat(buf, &st) == -1);
180
181 errno = 0;
182 ATF_REQUIRE_ERRNO(EFAULT, stat((void *)-1, &st) == -1);
183
184 errno = 0;
185 ATF_REQUIRE_ERRNO(EFAULT, lstat((void *)-1, &st) == -1);
186
187 errno = 0;
188 ATF_REQUIRE_ERRNO(EFAULT, stat("/etc/passwd", (void *)-1) == -1);
189
190 errno = 0;
191 ATF_REQUIRE_ERRNO(EFAULT, lstat("/etc/passwd", (void *)-1) == -1);
192
193 errno = 0;
194 ATF_REQUIRE_ERRNO(ENOENT, stat("/a/b/c/d/e/f/g/h/i/j/k", &st) == -1);
195
196 errno = 0;
197 ATF_REQUIRE_ERRNO(ENOENT, lstat("/a/b/c/d/e/f/g/h/i/j/k", &st) == -1);
198}
199
200ATF_TC_WITH_CLEANUP(stat_mtime);
201ATF_TC_HEAD(stat_mtime, tc)
202{
203 atf_tc_set_md_var(tc, "descr", "Test modification times with stat(2)");
204}
205
206ATF_TC_BODY(stat_mtime, tc)
207{
208 struct stat sa, sb;
209 int fd[3];
210 size_t i;
211
212 for (i = 0; i < __arraycount(fd); i++) {
213
214 (void)memset(&sa, 0, sizeof(struct stat));
215 (void)memset(&sb, 0, sizeof(struct stat));
216
217 fd[i] = open(path, O_WRONLY | O_CREAT);
218
219 ATF_REQUIRE(fd[i] != -1);
220 ATF_REQUIRE(write(fd[i], "X", 1) == 1);
221 ATF_REQUIRE(stat(path, &sa) == 0);
222
223 (void)sleep(1);
224
225 ATF_REQUIRE(write(fd[i], "X", 1) == 1);
226 ATF_REQUIRE(stat(path, &sb) == 0);
227
228 ATF_REQUIRE(close(fd[i]) == 0);
229 ATF_REQUIRE(unlink(path) == 0);
230
231 if (sa.st_mtime == sb.st_mtime)
232 atf_tc_fail("mtimes did not change");
233 }
234}
235
236ATF_TC_CLEANUP(stat_mtime, tc)
237{
238 (void)unlink(path);
239}
240
241ATF_TC_WITH_CLEANUP(stat_perm);
242ATF_TC_HEAD(stat_perm, tc)
243{
244 atf_tc_set_md_var(tc, "descr", "Test permissions with stat(2)");
245 atf_tc_set_md_var(tc, "require.user", "root");
246}
247
248ATF_TC_BODY(stat_perm, tc)
249{
250 struct stat sa, sb;
251 gid_t gid;
252 uid_t uid;
253 int fd;
254
255 (void)memset(&sa, 0, sizeof(struct stat));
256 (void)memset(&sb, 0, sizeof(struct stat));
257
258 uid = getuid();
259 gid = getgid();
260
261 fd = open(path, O_RDONLY | O_CREAT);
262
263 ATF_REQUIRE(fd != -1);
264 ATF_REQUIRE(fstat(fd, &sa) == 0);
265 ATF_REQUIRE(stat(path, &sb) == 0);
266
267 if (gid != sa.st_gid || sa.st_gid != sb.st_gid)
268 atf_tc_fail("invalid GID");
269
270 if (uid != sa.st_uid || sa.st_uid != sb.st_uid)
271 atf_tc_fail("invalid UID");
272
273 ATF_REQUIRE(close(fd) == 0);
274 ATF_REQUIRE(unlink(path) == 0);
275}
276
277ATF_TC_CLEANUP(stat_perm, tc)
278{
279 (void)unlink(path);
280}
281
282ATF_TC_WITH_CLEANUP(stat_size);
283ATF_TC_HEAD(stat_size, tc)
284{
285 atf_tc_set_md_var(tc, "descr", "Test file sizes with stat(2)");
286}
287
288ATF_TC_BODY(stat_size, tc)
289{
290 struct stat sa, sb, sc;
291 const size_t n = 10;
292 size_t i;
293 int fd;
294
295 fd = open(path, O_WRONLY | O_CREAT);
296 ATF_REQUIRE(fd >= 0);
297
298 for (i = 0; i < n; i++) {
299
300 (void)memset(&sa, 0, sizeof(struct stat));
301 (void)memset(&sb, 0, sizeof(struct stat));
302 (void)memset(&sc, 0, sizeof(struct stat));
303
304 ATF_REQUIRE(fstat(fd, &sa) == 0);
305 ATF_REQUIRE(write(fd, "X", 1) == 1);
306 ATF_REQUIRE(fstat(fd, &sb) == 0);
307 ATF_REQUIRE(stat(path, &sc) == 0);
308
309 if (sa.st_size + 1 != sb.st_size)
310 atf_tc_fail("invalid file size");
311
312 if (sb.st_size != sc.st_size)
313 atf_tc_fail("stat(2) and fstat(2) mismatch");
314 }
315
316 ATF_REQUIRE(close(fd) == 0);
317 ATF_REQUIRE(unlink(path) == 0);
318}
319
320ATF_TC_CLEANUP(stat_size, tc)
321{
322 (void)unlink(path);
323}
324
325ATF_TC(stat_socket);
326ATF_TC_HEAD(stat_socket, tc)
327{
328 atf_tc_set_md_var(tc, "descr", "Test fstat(2) with "
329 "a socket (PR kern/46077)");
330}
331
332ATF_TC_BODY(stat_socket, tc)
333{
334 struct sockaddr_in addr;
335 struct stat st;
336 uint32_t iaddr;
337 int fd, flags;
338
339 (void)memset(&st, 0, sizeof(struct stat));
340 (void)memset(&addr, 0, sizeof(struct sockaddr_in));
341
342 fd = socket(AF_INET, SOCK_STREAM, 0);
343 ATF_REQUIRE(fd >= 0);
344
345 flags = fcntl(fd, F_GETFL);
346
347 ATF_REQUIRE(flags != -1);
348 ATF_REQUIRE(fcntl(fd, F_SETFL, flags | O_NONBLOCK) != -1);
349 ATF_REQUIRE(inet_pton(AF_INET, "127.0.0.1", &iaddr) == 1);
350
351 addr.sin_port = htons(42);
352 addr.sin_family = AF_INET;
353 addr.sin_addr.s_addr = iaddr;
354
355 errno = 0;
356
357 ATF_REQUIRE_ERRNO(EINPROGRESS,
358 connect(fd, (struct sockaddr *)&addr,
359 sizeof(struct sockaddr_in)) == -1);
360
361 errno = 0;
362
363 if (fstat(fd, &st) != 0 || errno != 0)
364 atf_tc_fail("fstat(2) failed for a EINPROGRESS socket");
365
366 (void)close(fd);
367}
368
369ATF_TC_WITH_CLEANUP(stat_symlink);
370ATF_TC_HEAD(stat_symlink, tc)
371{
372 atf_tc_set_md_var(tc, "descr", "Test symbolic links with stat(2)");
373}
374
375ATF_TC_BODY(stat_symlink, tc)
376{
377 const char *pathlink = "pathlink";
378 struct stat sa, sb;
379 int fd;
380
381 (void)memset(&sa, 0, sizeof(struct stat));
382 (void)memset(&sb, 0, sizeof(struct stat));
383
384 fd = open(path, O_WRONLY | O_CREAT);
385
386 ATF_REQUIRE(fd >= 0);
387 ATF_REQUIRE(symlink(path, pathlink) == 0);
388 ATF_REQUIRE(stat(pathlink, &sa) == 0);
389 ATF_REQUIRE(lstat(pathlink, &sb) == 0);
390
391 if (S_ISLNK(sa.st_mode) != 0)
392 atf_tc_fail("stat(2) detected symbolic link");
393
394 if (S_ISLNK(sb.st_mode) == 0)
395 atf_tc_fail("lstat(2) did not detect symbolic link");
396
397 if (sa.st_mode == sb.st_mode)
398 atf_tc_fail("inconsistencies between stat(2) and lstat(2)");
399
400 (void)close(fd);
401 ATF_REQUIRE(unlink(path) == 0);
402 ATF_REQUIRE(unlink(pathlink) == 0);
403}
404
405ATF_TC_CLEANUP(stat_symlink, tc)
406{
407 (void)unlink(path);
408}
409
410ATF_TP_ADD_TCS(tp)
411{
412
413 ATF_TP_ADD_TC(tp, stat_chflags);
414 ATF_TP_ADD_TC(tp, stat_dir);
415 ATF_TP_ADD_TC(tp, stat_err);
416 ATF_TP_ADD_TC(tp, stat_mtime);
417 ATF_TP_ADD_TC(tp, stat_perm);
418 ATF_TP_ADD_TC(tp, stat_size);
419 ATF_TP_ADD_TC(tp, stat_socket);
420 ATF_TP_ADD_TC(tp, stat_symlink);
421
422 return atf_no_error();
423}
diff --git a/src/regress/lib/libc/sys/t_syscall.c b/src/regress/lib/libc/sys/t_syscall.c
new file mode 100644
index 0000000000..e864970262
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_syscall.c
@@ -0,0 +1,122 @@
1/* $OpenBSD: t_syscall.c,v 1.1.1.1 2019/11/19 19:57:04 bluhm Exp $ */
2/* $NetBSD: t_syscall.c,v 1.3 2018/05/28 07:55:56 martin Exp $ */
3
4/*-
5 * Copyright (c) 2018 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Martin Husemann.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_syscall.c,v 1.3 2018/05/28 07:55:56 martin Exp $");
37
38
39#include "atf-c.h"
40#include <stdio.h>
41#include <unistd.h>
42#include <fcntl.h>
43#include <err.h>
44#include <string.h>
45#include <stdlib.h>
46#include <sys/mman.h>
47#include <sys/endian.h>
48#include <sys/syscall.h>
49
50#if !defined(_LP64) && BYTE_ORDER == _BIG_ENDIAN
51#define __SYSCALL_TO_UINTPTR_T(V) ((uintptr_t)((V)>>32))
52#else
53#define __SYSCALL_TO_UINTPTR_T(V) ((uintptr_t)(V))
54#endif
55
56static const char secrect_data[1024] = {
57 "my secret key\n"
58};
59
60#define FILE_NAME "dummy"
61
62#ifndef _LP64
63ATF_TC(mmap_syscall);
64
65ATF_TC_HEAD(mmap_syscall, tc)
66{
67 atf_tc_set_md_var(tc, "descr", "Tests mmap(2) via syscall(2)");
68}
69
70ATF_TC_BODY(mmap_syscall, tc)
71{
72 int fd;
73 const char *p;
74
75 fd = open(FILE_NAME, O_RDWR|O_CREAT|O_TRUNC, 0666);
76 ATF_REQUIRE(fd != -1);
77
78 write(fd, secrect_data, sizeof(secrect_data));
79
80 p = (const char *)syscall(SYS_mmap,
81 0, sizeof(secrect_data), PROT_READ, MAP_PRIVATE, fd, 0, 0, 0);
82 ATF_REQUIRE(p != NULL);
83
84 ATF_REQUIRE(strcmp(p, secrect_data) == 0);
85}
86#endif
87
88ATF_TC(mmap___syscall);
89
90ATF_TC_HEAD(mmap___syscall, tc)
91{
92 atf_tc_set_md_var(tc, "descr", "Tests mmap(2) via __syscall(2)");
93}
94
95ATF_TC_BODY(mmap___syscall, tc)
96{
97 int fd;
98 const char *p;
99
100 fd = open(FILE_NAME, O_RDWR|O_CREAT|O_TRUNC, 0666);
101 ATF_REQUIRE(fd != -1);
102
103 write(fd, secrect_data, sizeof(secrect_data));
104
105 p = (const char *)__SYSCALL_TO_UINTPTR_T(__syscall(SYS_mmap,
106 0, sizeof(secrect_data), PROT_READ, MAP_PRIVATE, fd,
107 /* pad*/ 0, (off_t)0));
108 ATF_REQUIRE(p != NULL);
109
110 ATF_REQUIRE(strcmp(p, secrect_data) == 0);
111}
112
113ATF_TP_ADD_TCS(tp)
114{
115
116#ifndef _LP64
117 ATF_TP_ADD_TC(tp, mmap_syscall);
118#endif
119 ATF_TP_ADD_TC(tp, mmap___syscall);
120
121 return atf_no_error();
122}
diff --git a/src/regress/lib/libc/sys/t_truncate.c b/src/regress/lib/libc/sys/t_truncate.c
new file mode 100644
index 0000000000..1d059af5f5
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_truncate.c
@@ -0,0 +1,183 @@
1/* $OpenBSD: t_truncate.c,v 1.1.1.1 2019/11/19 19:57:04 bluhm Exp $ */
2/* $NetBSD: t_truncate.c,v 1.3 2017/01/13 20:03:51 christos Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_truncate.c,v 1.3 2017/01/13 20:03:51 christos Exp $");
37
38#include <sys/stat.h>
39
40#include "atf-c.h"
41#include <errno.h>
42#include <fcntl.h>
43#include <limits.h>
44#include <stdio.h>
45#include <string.h>
46#include <unistd.h>
47
48static const char path[] = "truncate";
49static const size_t sizes[] = { 8, 16, 512, 1024, 2048, 4094, 3000, 30 };
50
51ATF_TC_WITH_CLEANUP(ftruncate_basic);
52ATF_TC_HEAD(ftruncate_basic, tc)
53{
54 atf_tc_set_md_var(tc, "descr", "A basic test of ftruncate(2)");
55}
56
57ATF_TC_BODY(ftruncate_basic, tc)
58{
59 struct stat st;
60 size_t i;
61 int fd;
62
63 fd = open(path, O_RDWR | O_CREAT, 0600);
64 ATF_REQUIRE(fd >= 0);
65
66 for (i = 0; i < __arraycount(sizes); i++) {
67
68 (void)memset(&st, 0, sizeof(struct stat));
69
70 ATF_REQUIRE(ftruncate(fd, sizes[i]) == 0);
71 ATF_REQUIRE(fstat(fd, &st) == 0);
72
73 (void)fprintf(stderr, "truncating to %zu bytes\n", sizes[i]);
74
75 if (sizes[i] != (size_t)st.st_size)
76 atf_tc_fail("ftruncate(2) did not truncate");
77 }
78
79 (void)close(fd);
80 (void)unlink(path);
81}
82
83ATF_TC_CLEANUP(ftruncate_basic, tc)
84{
85 (void)unlink(path);
86}
87
88ATF_TC(ftruncate_err);
89ATF_TC_HEAD(ftruncate_err, tc)
90{
91 atf_tc_set_md_var(tc, "descr", "Test errors from ftruncate(2)");
92 atf_tc_set_md_var(tc, "require.user", "unprivileged");
93}
94
95ATF_TC_BODY(ftruncate_err, tc)
96{
97 int fd;
98
99 fd = open("/etc/passwd", O_RDONLY, 0400);
100 ATF_REQUIRE(fd >= 0);
101
102 errno = 0;
103 ATF_REQUIRE_ERRNO(EBADF, ftruncate(-1, 999) == -1);
104
105 errno = 0;
106 ATF_REQUIRE_ERRNO(EINVAL, ftruncate(fd, 999) == -1);
107
108 (void)close(fd);
109}
110
111ATF_TC_WITH_CLEANUP(truncate_basic);
112ATF_TC_HEAD(truncate_basic, tc)
113{
114 atf_tc_set_md_var(tc, "descr", "A basic test of truncate(2)");
115}
116
117ATF_TC_BODY(truncate_basic, tc)
118{
119 struct stat st;
120 size_t i;
121 int fd;
122
123 fd = open(path, O_RDWR | O_CREAT, 0600);
124 ATF_REQUIRE(fd >= 0);
125
126 for (i = 0; i < __arraycount(sizes); i++) {
127
128 (void)memset(&st, 0, sizeof(struct stat));
129
130 ATF_REQUIRE(truncate(path, sizes[i]) == 0);
131 ATF_REQUIRE(fstat(fd, &st) == 0);
132
133 (void)fprintf(stderr, "truncating to %zu bytes\n", sizes[i]);
134
135 if (sizes[i] != (size_t)st.st_size)
136 atf_tc_fail("truncate(2) did not truncate");
137 }
138
139 (void)close(fd);
140 (void)unlink(path);
141}
142
143ATF_TC_CLEANUP(truncate_basic, tc)
144{
145 (void)unlink(path);
146}
147
148ATF_TC(truncate_err);
149ATF_TC_HEAD(truncate_err, tc)
150{
151 atf_tc_set_md_var(tc, "descr", "Test errors from truncate(2)");
152 atf_tc_set_md_var(tc, "require.user", "unprivileged");
153}
154
155ATF_TC_BODY(truncate_err, tc)
156{
157 char buf[PATH_MAX];
158
159 errno = 0;
160 ATF_REQUIRE_ERRNO(EFAULT, truncate((void *)-1, 999) == -1);
161
162 errno = 0;
163 ATF_REQUIRE_ERRNO(EISDIR, truncate("/etc", 999) == -1);
164
165 errno = 0;
166 ATF_REQUIRE_ERRNO(ENOENT, truncate("/a/b/c/d/e/f/g", 999) == -1);
167
168 errno = 0;
169 snprintf(buf, sizeof(buf), "%s/truncate_test.root_owned",
170 atf_tc_get_config_var(tc, "srcdir"));
171 ATF_REQUIRE_ERRNO(EACCES, truncate(buf, 999) == -1);
172}
173
174ATF_TP_ADD_TCS(tp)
175{
176
177 ATF_TP_ADD_TC(tp, ftruncate_basic);
178 ATF_TP_ADD_TC(tp, ftruncate_err);
179 ATF_TP_ADD_TC(tp, truncate_basic);
180 ATF_TP_ADD_TC(tp, truncate_err);
181
182 return atf_no_error();
183}
diff --git a/src/regress/lib/libc/sys/t_umask.c b/src/regress/lib/libc/sys/t_umask.c
new file mode 100644
index 0000000000..b312e8183b
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_umask.c
@@ -0,0 +1,210 @@
1/* $OpenBSD: t_umask.c,v 1.1.1.1 2019/11/19 19:57:04 bluhm Exp $ */
2/* $NetBSD: t_umask.c,v 1.2 2017/01/13 19:34:19 christos Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_umask.c,v 1.2 2017/01/13 19:34:19 christos Exp $");
37
38#include <sys/stat.h>
39#include <sys/wait.h>
40
41#include "atf-c.h"
42#include <fcntl.h>
43#include <stdlib.h>
44#include <string.h>
45#include <unistd.h>
46
47static const char path[] = "umask";
48static const mode_t mask[] = {
49 S_IRWXU,
50 S_IRUSR,
51 S_IWUSR,
52 S_IXUSR,
53 S_IRWXG,
54 S_IRGRP,
55 S_IWGRP,
56 S_IXGRP,
57 S_IRWXO,
58 S_IROTH,
59 S_IWOTH,
60 S_IXOTH
61};
62
63ATF_TC_WITH_CLEANUP(umask_fork);
64ATF_TC_HEAD(umask_fork, tc)
65{
66 atf_tc_set_md_var(tc, "descr", "Check that umask(2) is inherited");
67}
68
69ATF_TC_BODY(umask_fork, tc)
70{
71 mode_t mode;
72 pid_t pid;
73 size_t i;
74 int sta;
75
76 for (i = 0; i < __arraycount(mask) - 1; i++) {
77
78 (void)umask(mask[i] | mask[i + 1]);
79
80 pid = fork();
81
82 if (pid < 0)
83 continue;
84
85 if (pid == 0) {
86
87 mode = umask(mask[i]);
88
89 if (mode != (mask[i] | mask[i + 1]))
90 _exit(EXIT_FAILURE);
91
92 _exit(EXIT_SUCCESS);
93 }
94
95 (void)wait(&sta);
96
97 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
98 goto fail;
99 }
100
101 return;
102
103fail:
104 (void)umask(S_IWGRP | S_IWOTH);
105
106 atf_tc_fail("umask(2) was not inherited");
107}
108
109ATF_TC_CLEANUP(umask_fork, tc)
110{
111 (void)umask(S_IWGRP | S_IWOTH);
112}
113
114ATF_TC_WITH_CLEANUP(umask_open);
115ATF_TC_HEAD(umask_open, tc)
116{
117 atf_tc_set_md_var(tc, "descr", "A basic test of open(2) and umask(2)");
118}
119
120ATF_TC_BODY(umask_open, tc)
121{
122 const char *str = NULL;
123 struct stat st;
124 size_t i;
125 int fd;
126
127 for (i = 0; i < __arraycount(mask); i++) {
128
129 (void)umask(mask[i]);
130
131 fd = open(path, O_RDWR | O_CREAT, 0777);
132
133 if (fd < 0)
134 continue;
135
136 (void)close(fd);
137 (void)memset(&st, 0, sizeof(struct stat));
138
139 if (stat(path, &st) != 0) {
140 str = "failed to stat(2)";
141 goto out;
142 }
143
144 if ((st.st_mode & mask[i]) != 0) {
145 str = "invalid umask(2)";
146 goto out;
147 }
148
149 if (unlink(path) != 0) {
150 str = "failed to unlink(2)";
151 goto out;
152 }
153
154 }
155
156out:
157 (void)umask(S_IWGRP | S_IWOTH);
158
159 if (str != NULL)
160 atf_tc_fail("%s", str);
161}
162
163ATF_TC_CLEANUP(umask_open, tc)
164{
165 (void)umask(S_IWGRP | S_IWOTH);
166 (void)unlink(path);
167}
168
169ATF_TC_WITH_CLEANUP(umask_previous);
170ATF_TC_HEAD(umask_previous, tc)
171{
172 atf_tc_set_md_var(tc, "descr", "Test the return value from umask(2)");
173}
174
175ATF_TC_BODY(umask_previous, tc)
176{
177 mode_t mode;
178 size_t i;
179
180 for (i = 0; i < __arraycount(mask); i++) {
181
182 mode = umask(mask[i]);
183 mode = umask(mask[i]);
184
185 if (mode != mask[i])
186 goto fail;
187 }
188
189 return;
190
191fail:
192 (void)umask(S_IWGRP | S_IWOTH);
193
194 atf_tc_fail("umask(2) did not return the previous mask");
195}
196
197ATF_TC_CLEANUP(umask_previous, tc)
198{
199 (void)umask(S_IWGRP | S_IWOTH);
200}
201
202ATF_TP_ADD_TCS(tp)
203{
204
205 ATF_TP_ADD_TC(tp, umask_fork);
206 ATF_TP_ADD_TC(tp, umask_open);
207 ATF_TP_ADD_TC(tp, umask_previous);
208
209 return atf_no_error();
210}
diff --git a/src/regress/lib/libc/sys/t_unlink.c b/src/regress/lib/libc/sys/t_unlink.c
new file mode 100644
index 0000000000..9736d77593
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_unlink.c
@@ -0,0 +1,162 @@
1/* $OpenBSD: t_unlink.c,v 1.1.1.1 2019/11/19 19:57:04 bluhm Exp $ */
2/* $NetBSD: t_unlink.c,v 1.4 2017/01/14 20:55:26 christos Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_unlink.c,v 1.4 2017/01/14 20:55:26 christos Exp $");
37
38#include <sys/stat.h>
39
40#include "atf-c.h"
41#include <errno.h>
42#include <fcntl.h>
43#include <limits.h>
44#include <string.h>
45#include <unistd.h>
46
47static char path[] = "unlink";
48
49ATF_TC_WITH_CLEANUP(unlink_basic);
50ATF_TC_HEAD(unlink_basic, tc)
51{
52 atf_tc_set_md_var(tc, "descr", "A basic test of unlink(2)");
53}
54
55ATF_TC_BODY(unlink_basic, tc)
56{
57 const size_t n = 512;
58 size_t i;
59 int fd;
60
61 for (i = 0; i < n; i++) {
62
63 fd = open(path, O_RDWR | O_CREAT, 0666);
64
65 ATF_REQUIRE(fd != -1);
66 ATF_REQUIRE(close(fd) == 0);
67 ATF_REQUIRE(unlink(path) == 0);
68
69 errno = 0;
70 ATF_REQUIRE_ERRNO(ENOENT, open(path, O_RDONLY) == -1);
71 }
72}
73
74ATF_TC_CLEANUP(unlink_basic, tc)
75{
76 (void)unlink(path);
77}
78
79ATF_TC_WITH_CLEANUP(unlink_err);
80ATF_TC_HEAD(unlink_err, tc)
81{
82 atf_tc_set_md_var(tc, "descr", "Test error conditions of unlink(2)");
83}
84
85ATF_TC_BODY(unlink_err, tc)
86{
87 char buf[PATH_MAX + 1];
88
89 (void)memset(buf, 'x', sizeof(buf));
90
91 errno = 0;
92 ATF_REQUIRE_ERRNO(EBUSY, unlink("/") == -1);
93
94 errno = 0;
95 ATF_REQUIRE_ERRNO(ENAMETOOLONG, unlink(buf) == -1);
96
97 errno = 0;
98 ATF_REQUIRE_ERRNO(ENOENT, unlink("/a/b/c/d/e/f/g/h/i/j/k/l/m") == -1);
99}
100
101ATF_TC_CLEANUP(unlink_err, tc)
102{
103 (void)unlink(path);
104}
105
106ATF_TC_WITH_CLEANUP(unlink_fifo);
107ATF_TC_HEAD(unlink_fifo, tc)
108{
109 atf_tc_set_md_var(tc, "descr", "Test unlink(2) for a FIFO");
110}
111
112ATF_TC_BODY(unlink_fifo, tc)
113{
114
115 ATF_REQUIRE(mkfifo(path, 0666) == 0);
116 ATF_REQUIRE(unlink(path) == 0);
117
118 errno = 0;
119 ATF_REQUIRE_ERRNO(ENOENT, open(path, O_RDONLY) == -1);
120}
121
122ATF_TC_CLEANUP(unlink_fifo, tc)
123{
124 (void)unlink(path);
125}
126
127ATF_TC_WITH_CLEANUP(unlink_perm);
128ATF_TC_HEAD(unlink_perm, tc)
129{
130 atf_tc_set_md_var(tc, "descr", "Test permissions with unlink(2)");
131 atf_tc_set_md_var(tc, "require.user", "unprivileged");
132}
133
134ATF_TC_BODY(unlink_perm, tc)
135{
136 int rv;
137
138 errno = 0;
139 rv = unlink("/etc");
140 ATF_REQUIRE_MSG(rv == -1 && (errno == EACCES || errno == EPERM),
141 "unlinking a directory did not fail with EPERM or EACCESS; "
142 "unlink() returned %d, errno %d", rv, errno);
143
144 errno = 0;
145 ATF_REQUIRE_ERRNO(EACCES, unlink("/root/.profile") == -1);
146}
147
148ATF_TC_CLEANUP(unlink_perm, tc)
149{
150 (void)unlink(path);
151}
152
153ATF_TP_ADD_TCS(tp)
154{
155
156 ATF_TP_ADD_TC(tp, unlink_basic);
157 ATF_TP_ADD_TC(tp, unlink_err);
158 ATF_TP_ADD_TC(tp, unlink_fifo);
159 ATF_TP_ADD_TC(tp, unlink_perm);
160
161 return atf_no_error();
162}
diff --git a/src/regress/lib/libc/sys/t_write.c b/src/regress/lib/libc/sys/t_write.c
new file mode 100644
index 0000000000..d22f32383a
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_write.c
@@ -0,0 +1,287 @@
1/* $OpenBSD: t_write.c,v 1.1.1.1 2019/11/19 19:57:04 bluhm Exp $ */
2/* $NetBSD: t_write.c,v 1.6 2017/07/09 22:18:43 christos Exp $ */
3
4/*-
5 * Copyright (c) 2001, 2008 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "macros.h"
31
32#include <sys/cdefs.h>
33__COPYRIGHT("@(#) Copyright (c) 2008\
34 The NetBSD Foundation, inc. All rights reserved.");
35__RCSID("$NetBSD: t_write.c,v 1.6 2017/07/09 22:18:43 christos Exp $");
36
37#include <sys/uio.h>
38#include <sys/mman.h>
39
40#include "atf-c.h"
41#include <errno.h>
42#include <fcntl.h>
43#include <signal.h>
44#include <limits.h>
45#include <stdio.h>
46#include <stdint.h>
47#include <string.h>
48#include <unistd.h>
49#include <paths.h>
50
51static void sighandler(int);
52
53static bool fail = false;
54static const char *path = "write";
55
56static void
57sighandler(int signo __unused)
58{
59 fail = false;
60}
61
62ATF_TC_WITH_CLEANUP(write_err);
63ATF_TC_HEAD(write_err, tc)
64{
65 atf_tc_set_md_var(tc, "descr", "Checks errors from write(2)");
66}
67
68ATF_TC_BODY(write_err, tc)
69{
70 char rbuf[3] = { 'a', 'b', 'c' };
71 char wbuf[3] = { 'x', 'y', 'z' };
72 int fd;
73
74 errno = 0;
75 ATF_REQUIRE_ERRNO(EBADF, write(-1, wbuf, sizeof(wbuf)) == -1);
76
77 fd = open(path, O_RDWR | O_CREAT);
78
79 if (fd >= 0) {
80
81 errno = 0;
82 ATF_REQUIRE_ERRNO(0, write(fd, wbuf, 3) == 3);
83
84 errno = 0;
85 ATF_REQUIRE_ERRNO(EINVAL, write(fd, wbuf, SIZE_MAX) == -1);
86
87 errno = 0;
88 ATF_REQUIRE_ERRNO(EFAULT, write(fd, (void *)-1, 1) == -1);
89
90 /*
91 * Check that the above bogus write(2)
92 * calls did not corrupt the file.
93 */
94 ATF_REQUIRE(lseek(fd, 0, SEEK_SET) == 0);
95 ATF_REQUIRE(read(fd, rbuf, 3) == 3);
96 ATF_REQUIRE(memcmp(rbuf, wbuf, 3) == 0);
97
98 (void)close(fd);
99 (void)unlink(path);
100 }
101}
102
103ATF_TC_CLEANUP(write_err, tc)
104{
105 (void)unlink(path);
106}
107
108ATF_TC(write_pipe);
109ATF_TC_HEAD(write_pipe, tc)
110{
111 atf_tc_set_md_var(tc, "descr", "Checks for EPIPE from write(2)");
112}
113
114ATF_TC_BODY(write_pipe, tc)
115{
116 int fds[2];
117
118 ATF_REQUIRE(pipe(fds) == 0);
119 ATF_REQUIRE(signal(SIGPIPE, sighandler) == 0);
120
121 ATF_REQUIRE(write(fds[1], "x", 1) != -1);
122 ATF_REQUIRE(close(fds[0]) == 0);
123
124 errno = 0;
125 fail = true;
126
127 if (write(fds[1], "x", 1) != -1 || errno != EPIPE)
128 atf_tc_fail_nonfatal("expected EPIPE but write(2) succeeded");
129
130 ATF_REQUIRE(close(fds[1]) == 0);
131
132 if (fail != false)
133 atf_tc_fail_nonfatal("SIGPIPE was not raised");
134}
135
136ATF_TC_WITH_CLEANUP(write_pos);
137ATF_TC_HEAD(write_pos, tc)
138{
139 atf_tc_set_md_var(tc, "descr", "Checks that write(2) "
140 "updates the file position");
141}
142
143ATF_TC_BODY(write_pos, tc)
144{
145 const size_t n = 123;
146 size_t i;
147 int fd;
148
149 fd = open(path, O_RDWR | O_CREAT);
150 ATF_REQUIRE(fd >= 0);
151
152 for (i = 0; i < n; i++) {
153 ATF_REQUIRE(write(fd, "x", 1) == 1);
154 ATF_REQUIRE(lseek(fd, 0, SEEK_CUR) == (off_t)(i + 1));
155 }
156
157 ATF_REQUIRE(close(fd) == 0);
158 ATF_REQUIRE(unlink(path) == 0);
159}
160
161ATF_TC_CLEANUP(write_pos, tc)
162{
163 (void)unlink(path);
164}
165
166ATF_TC_WITH_CLEANUP(write_ret);
167ATF_TC_HEAD(write_ret, tc)
168{
169 atf_tc_set_md_var(tc, "descr", "Checks return values from write(2)");
170}
171
172ATF_TC_BODY(write_ret, tc)
173{
174 const size_t n = 99;
175 char buf[123];
176 size_t i, j;
177 int fd;
178
179 fd = open(path, O_WRONLY | O_CREAT);
180 ATF_REQUIRE(fd >= 0);
181
182 (void)memset(buf, 'x', sizeof(buf));
183
184 for (i = j = 0; i < n; i++)
185 j += write(fd, buf, sizeof(buf));
186
187 if (j != n * 123)
188 atf_tc_fail("inconsistent return values from write(2)");
189
190 (void)close(fd);
191 (void)unlink(path);
192}
193
194ATF_TC_CLEANUP(write_ret, tc)
195{
196 (void)unlink(path);
197}
198
199ATF_TC(writev_iovmax);
200ATF_TC_HEAD(writev_iovmax, tc)
201{
202 atf_tc_set_md_var(tc, "timeout", "10");
203 atf_tc_set_md_var(tc, "descr",
204 "Checks that file descriptor is properly FILE_UNUSE()d "
205 "when iovcnt is greater than IOV_MAX");
206}
207
208ATF_TC_BODY(writev_iovmax, tc)
209{
210 ssize_t retval;
211
212 (void)printf("Calling writev(2, NULL, IOV_MAX + 1)...\n");
213
214 errno = 0;
215 retval = writev(2, NULL, IOV_MAX + 1);
216
217 ATF_REQUIRE_EQ_MSG(retval, -1, "got: %zd", retval);
218 ATF_REQUIRE_EQ_MSG(errno, EINVAL, "got: %s", strerror(errno));
219}
220
221ATF_TC(write_fault);
222
223ATF_TC_HEAD(write_fault, tc)
224{
225 atf_tc_set_md_var(tc, "descr",
226 "Check that writing to non-permitted space returns EFAULT");
227}
228
229#define SIZE 8192
230
231ATF_TC_BODY(write_fault, tc)
232{
233 int fd[2];
234 ATF_REQUIRE(pipe(fd) != -1);
235 // Can't use /dev/null cause it doesn't access the buffer.
236
237 void *map = mmap(NULL, SIZE, PROT_NONE, MAP_ANON | MAP_PRIVATE, -1, 0);
238 ATF_REQUIRE(map != MAP_FAILED);
239
240 ssize_t retval = write(fd[1], map, SIZE);
241
242 ATF_REQUIRE_EQ_MSG(retval, -1, "got: %zd", retval);
243 ATF_REQUIRE_EQ_MSG(errno, EFAULT, "got: %s", strerror(errno));
244
245 munmap(map, SIZE);
246 close(fd[0]);
247 close(fd[1]);
248}
249
250ATF_TC(read_fault);
251
252ATF_TC_HEAD(read_fault, tc)
253{
254 atf_tc_set_md_var(tc, "descr",
255 "Check that reading from non-permitted space returns EFAULT");
256}
257
258ATF_TC_BODY(read_fault, tc)
259{
260 int fd = open(_PATH_DEVZERO, O_RDONLY);
261 ATF_REQUIRE(fd != -1);
262
263 void *map = mmap(NULL, SIZE, PROT_NONE, MAP_ANON | MAP_PRIVATE, -1, 0);
264 ATF_REQUIRE(map != MAP_FAILED);
265
266 ssize_t retval = read(fd, map, SIZE);
267
268 ATF_REQUIRE_EQ_MSG(retval, -1, "got: %zd", retval);
269 ATF_REQUIRE_EQ_MSG(errno, EFAULT, "got: %s", strerror(errno));
270
271 munmap(map, SIZE);
272 close(fd);
273}
274
275ATF_TP_ADD_TCS(tp)
276{
277
278 ATF_TP_ADD_TC(tp, write_err);
279 ATF_TP_ADD_TC(tp, write_pipe);
280 ATF_TP_ADD_TC(tp, write_pos);
281 ATF_TP_ADD_TC(tp, write_ret);
282 ATF_TP_ADD_TC(tp, writev_iovmax);
283 ATF_TP_ADD_TC(tp, write_fault);
284 ATF_TP_ADD_TC(tp, read_fault);
285
286 return atf_no_error();
287}