summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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}