1*1a54b3c7Skre /* $NetBSD: t_msgctl.c,v 1.7 2017/10/07 17:15:44 kre Exp $ */
23440ea09Sjruoho
33440ea09Sjruoho /*-
43440ea09Sjruoho * Copyright (c) 2011 The NetBSD Foundation, Inc.
53440ea09Sjruoho * All rights reserved.
63440ea09Sjruoho *
73440ea09Sjruoho * This code is derived from software contributed to The NetBSD Foundation
83440ea09Sjruoho * by Jukka Ruohonen.
93440ea09Sjruoho *
103440ea09Sjruoho * Redistribution and use in source and binary forms, with or without
113440ea09Sjruoho * modification, are permitted provided that the following conditions
123440ea09Sjruoho * are met:
133440ea09Sjruoho * 1. Redistributions of source code must retain the above copyright
143440ea09Sjruoho * notice, this list of conditions and the following disclaimer.
153440ea09Sjruoho * 2. Redistributions in binary form must reproduce the above copyright
163440ea09Sjruoho * notice, this list of conditions and the following disclaimer in the
173440ea09Sjruoho * documentation and/or other materials provided with the distribution.
183440ea09Sjruoho *
193440ea09Sjruoho * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
203440ea09Sjruoho * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
213440ea09Sjruoho * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
223440ea09Sjruoho * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
233440ea09Sjruoho * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
243440ea09Sjruoho * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
253440ea09Sjruoho * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
263440ea09Sjruoho * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
273440ea09Sjruoho * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
283440ea09Sjruoho * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
293440ea09Sjruoho * POSSIBILITY OF SUCH DAMAGE.
303440ea09Sjruoho */
313440ea09Sjruoho #include <sys/cdefs.h>
32*1a54b3c7Skre __RCSID("$NetBSD: t_msgctl.c,v 1.7 2017/10/07 17:15:44 kre Exp $");
333440ea09Sjruoho
343440ea09Sjruoho #include <sys/msg.h>
353440ea09Sjruoho #include <sys/stat.h>
363440ea09Sjruoho #include <sys/sysctl.h>
373440ea09Sjruoho #include <sys/wait.h>
383440ea09Sjruoho
393440ea09Sjruoho #include <atf-c.h>
403440ea09Sjruoho #include <errno.h>
417f3cf0deSchristos #include <limits.h>
423440ea09Sjruoho #include <pwd.h>
438484134bSkre #include <signal.h>
443440ea09Sjruoho #include <stdio.h>
453440ea09Sjruoho #include <stdlib.h>
463440ea09Sjruoho #include <string.h>
473440ea09Sjruoho #include <sysexits.h>
483440ea09Sjruoho #include <time.h>
493440ea09Sjruoho #include <unistd.h>
503440ea09Sjruoho
513440ea09Sjruoho #define MSG_KEY 12345689
523440ea09Sjruoho #define MSG_MTYPE_1 0x41
533440ea09Sjruoho
543440ea09Sjruoho struct msg {
553440ea09Sjruoho long mtype;
563440ea09Sjruoho char buf[3];
573440ea09Sjruoho };
583440ea09Sjruoho
593440ea09Sjruoho static void clean(void);
603440ea09Sjruoho
613440ea09Sjruoho static void
clean(void)623440ea09Sjruoho clean(void)
633440ea09Sjruoho {
643440ea09Sjruoho int id;
653440ea09Sjruoho
663440ea09Sjruoho if ((id = msgget(MSG_KEY, 0)) != -1)
673440ea09Sjruoho (void)msgctl(id, IPC_RMID, 0);
683440ea09Sjruoho }
693440ea09Sjruoho
703440ea09Sjruoho ATF_TC_WITH_CLEANUP(msgctl_err);
ATF_TC_HEAD(msgctl_err,tc)713440ea09Sjruoho ATF_TC_HEAD(msgctl_err, tc)
723440ea09Sjruoho {
733440ea09Sjruoho atf_tc_set_md_var(tc, "descr", "Test errors from msgctl(2)");
743440ea09Sjruoho }
753440ea09Sjruoho
ATF_TC_BODY(msgctl_err,tc)763440ea09Sjruoho ATF_TC_BODY(msgctl_err, tc)
773440ea09Sjruoho {
783440ea09Sjruoho const int cmd[] = { IPC_STAT, IPC_SET, IPC_RMID };
793440ea09Sjruoho struct msqid_ds msgds;
803440ea09Sjruoho size_t i;
813440ea09Sjruoho int id;
823440ea09Sjruoho
833440ea09Sjruoho (void)memset(&msgds, 0, sizeof(struct msqid_ds));
843440ea09Sjruoho
853440ea09Sjruoho id = msgget(MSG_KEY, IPC_CREAT | 0600);
863440ea09Sjruoho ATF_REQUIRE(id != -1);
873440ea09Sjruoho
883440ea09Sjruoho errno = 0;
893440ea09Sjruoho ATF_REQUIRE_ERRNO(EINVAL, msgctl(id, INT_MAX, &msgds) == -1);
903440ea09Sjruoho
913440ea09Sjruoho errno = 0;
923440ea09Sjruoho ATF_REQUIRE_ERRNO(EFAULT, msgctl(id, IPC_STAT, (void *)-1) == -1);
933440ea09Sjruoho
943440ea09Sjruoho for (i = 0; i < __arraycount(cmd); i++) {
953440ea09Sjruoho errno = 0;
963440ea09Sjruoho ATF_REQUIRE_ERRNO(EINVAL, msgctl(-1, cmd[i], &msgds) == -1);
973440ea09Sjruoho }
983440ea09Sjruoho
993440ea09Sjruoho ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
1003440ea09Sjruoho }
1013440ea09Sjruoho
ATF_TC_CLEANUP(msgctl_err,tc)1023440ea09Sjruoho ATF_TC_CLEANUP(msgctl_err, tc)
1033440ea09Sjruoho {
1043440ea09Sjruoho clean();
1053440ea09Sjruoho }
1063440ea09Sjruoho
1073440ea09Sjruoho ATF_TC_WITH_CLEANUP(msgctl_perm);
ATF_TC_HEAD(msgctl_perm,tc)1083440ea09Sjruoho ATF_TC_HEAD(msgctl_perm, tc)
1093440ea09Sjruoho {
11085177a7aSjruoho atf_tc_set_md_var(tc, "descr", "Test permissions with msgctl(2)");
1113440ea09Sjruoho atf_tc_set_md_var(tc, "require.user", "root");
1123440ea09Sjruoho }
1133440ea09Sjruoho
ATF_TC_BODY(msgctl_perm,tc)1143440ea09Sjruoho ATF_TC_BODY(msgctl_perm, tc)
1153440ea09Sjruoho {
1163440ea09Sjruoho struct msqid_ds msgds;
1173440ea09Sjruoho struct passwd *pw;
1183440ea09Sjruoho pid_t pid;
1193440ea09Sjruoho int sta;
1203440ea09Sjruoho int id;
1213440ea09Sjruoho
1223440ea09Sjruoho (void)memset(&msgds, 0, sizeof(struct msqid_ds));
1233440ea09Sjruoho
1243440ea09Sjruoho pw = getpwnam("nobody");
1253440ea09Sjruoho id = msgget(MSG_KEY, IPC_CREAT | 0600);
1263440ea09Sjruoho
1273440ea09Sjruoho ATF_REQUIRE(id != -1);
1283440ea09Sjruoho ATF_REQUIRE(pw != NULL);
1293440ea09Sjruoho ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0);
1303440ea09Sjruoho
1313440ea09Sjruoho pid = fork();
1323440ea09Sjruoho ATF_REQUIRE(pid >= 0);
1333440ea09Sjruoho
1343440ea09Sjruoho if (pid == 0) {
1353440ea09Sjruoho
1363440ea09Sjruoho if (setuid(pw->pw_uid) != 0)
1373440ea09Sjruoho _exit(EX_OSERR);
1383440ea09Sjruoho
1393440ea09Sjruoho msgds.msg_perm.uid = getuid();
1403440ea09Sjruoho msgds.msg_perm.gid = getgid();
1413440ea09Sjruoho
1423440ea09Sjruoho errno = 0;
1433440ea09Sjruoho
1443440ea09Sjruoho if (msgctl(id, IPC_SET, &msgds) == 0)
1453440ea09Sjruoho _exit(EXIT_FAILURE);
1463440ea09Sjruoho
1473440ea09Sjruoho if (errno != EPERM)
1483440ea09Sjruoho _exit(EXIT_FAILURE);
1493440ea09Sjruoho
1503440ea09Sjruoho (void)memset(&msgds, 0, sizeof(struct msqid_ds));
1513440ea09Sjruoho
1523440ea09Sjruoho if (msgctl(id, IPC_STAT, &msgds) != 0)
1533440ea09Sjruoho _exit(EX_OSERR);
1543440ea09Sjruoho
1553440ea09Sjruoho msgds.msg_qbytes = 1;
1563440ea09Sjruoho
1573440ea09Sjruoho if (msgctl(id, IPC_SET, &msgds) == 0)
1583440ea09Sjruoho _exit(EXIT_FAILURE);
1593440ea09Sjruoho
1603440ea09Sjruoho if (errno != EPERM)
1613440ea09Sjruoho _exit(EXIT_FAILURE);
1623440ea09Sjruoho
1633440ea09Sjruoho _exit(EXIT_SUCCESS);
1643440ea09Sjruoho }
1653440ea09Sjruoho
1663440ea09Sjruoho (void)wait(&sta);
1673440ea09Sjruoho
1683440ea09Sjruoho if (WIFEXITED(sta) == 0) {
1693440ea09Sjruoho
1703440ea09Sjruoho if (WEXITSTATUS(sta) == EX_OSERR)
1713440ea09Sjruoho atf_tc_fail("system call failed");
1723440ea09Sjruoho
1733440ea09Sjruoho if (WEXITSTATUS(sta) == EXIT_FAILURE)
1743440ea09Sjruoho atf_tc_fail("UID %u manipulated root's "
1753440ea09Sjruoho "message queue", pw->pw_uid);
1763440ea09Sjruoho }
1773440ea09Sjruoho
1783440ea09Sjruoho ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
1793440ea09Sjruoho }
1803440ea09Sjruoho
ATF_TC_CLEANUP(msgctl_perm,tc)1813440ea09Sjruoho ATF_TC_CLEANUP(msgctl_perm, tc)
1823440ea09Sjruoho {
1833440ea09Sjruoho clean();
1843440ea09Sjruoho }
1853440ea09Sjruoho
1863440ea09Sjruoho ATF_TC_WITH_CLEANUP(msgctl_pid);
ATF_TC_HEAD(msgctl_pid,tc)1873440ea09Sjruoho ATF_TC_HEAD(msgctl_pid, tc)
1883440ea09Sjruoho {
1893440ea09Sjruoho atf_tc_set_md_var(tc, "descr", "Test that PIDs are updated");
1903440ea09Sjruoho }
1913440ea09Sjruoho
ATF_TC_BODY(msgctl_pid,tc)1923440ea09Sjruoho ATF_TC_BODY(msgctl_pid, tc)
1933440ea09Sjruoho {
1943440ea09Sjruoho struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
1953440ea09Sjruoho struct msqid_ds msgds;
1963440ea09Sjruoho int id, sta;
1973440ea09Sjruoho pid_t pid;
1983440ea09Sjruoho
1993440ea09Sjruoho id = msgget(MSG_KEY, IPC_CREAT | 0600);
2003440ea09Sjruoho ATF_REQUIRE(id != -1);
2013440ea09Sjruoho
2023440ea09Sjruoho pid = fork();
2033440ea09Sjruoho ATF_REQUIRE(pid >= 0);
2043440ea09Sjruoho
2053440ea09Sjruoho if (pid == 0) {
2063440ea09Sjruoho
2073440ea09Sjruoho (void)msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT);
2083440ea09Sjruoho
2093440ea09Sjruoho _exit(EXIT_SUCCESS);
2103440ea09Sjruoho }
2113440ea09Sjruoho
2123440ea09Sjruoho (void)sleep(1);
2133440ea09Sjruoho (void)wait(&sta);
2143440ea09Sjruoho (void)memset(&msgds, 0, sizeof(struct msqid_ds));
2153440ea09Sjruoho
2163440ea09Sjruoho ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0);
2173440ea09Sjruoho
2183440ea09Sjruoho if (pid != msgds.msg_lspid)
2193440ea09Sjruoho atf_tc_fail("the PID of last msgsnd(2) was not updated");
2203440ea09Sjruoho
2213440ea09Sjruoho pid = fork();
2223440ea09Sjruoho ATF_REQUIRE(pid >= 0);
2233440ea09Sjruoho
2243440ea09Sjruoho if (pid == 0) {
2253440ea09Sjruoho
2263440ea09Sjruoho (void)msgrcv(id, &msg,
2273440ea09Sjruoho sizeof(struct msg), MSG_MTYPE_1, IPC_NOWAIT);
2283440ea09Sjruoho
2293440ea09Sjruoho _exit(EXIT_SUCCESS);
2303440ea09Sjruoho }
2313440ea09Sjruoho
2323440ea09Sjruoho (void)sleep(1);
2333440ea09Sjruoho (void)wait(&sta);
2343440ea09Sjruoho (void)memset(&msgds, 0, sizeof(struct msqid_ds));
2353440ea09Sjruoho
2363440ea09Sjruoho ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0);
2373440ea09Sjruoho
2383440ea09Sjruoho if (pid != msgds.msg_lrpid)
2393440ea09Sjruoho atf_tc_fail("the PID of last msgrcv(2) was not updated");
2403440ea09Sjruoho
2413440ea09Sjruoho ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
2423440ea09Sjruoho }
2433440ea09Sjruoho
ATF_TC_CLEANUP(msgctl_pid,tc)2443440ea09Sjruoho ATF_TC_CLEANUP(msgctl_pid, tc)
2453440ea09Sjruoho {
2463440ea09Sjruoho clean();
2473440ea09Sjruoho }
2483440ea09Sjruoho
2493440ea09Sjruoho ATF_TC_WITH_CLEANUP(msgctl_set);
ATF_TC_HEAD(msgctl_set,tc)2503440ea09Sjruoho ATF_TC_HEAD(msgctl_set, tc)
2513440ea09Sjruoho {
2523440ea09Sjruoho atf_tc_set_md_var(tc, "descr", "Test msgctl(2) with IPC_SET");
2533440ea09Sjruoho atf_tc_set_md_var(tc, "require.user", "root");
2543440ea09Sjruoho }
2553440ea09Sjruoho
ATF_TC_BODY(msgctl_set,tc)2563440ea09Sjruoho ATF_TC_BODY(msgctl_set, tc)
2573440ea09Sjruoho {
2583440ea09Sjruoho struct msqid_ds msgds;
2593440ea09Sjruoho struct passwd *pw;
2603440ea09Sjruoho int id;
2613440ea09Sjruoho
2623440ea09Sjruoho (void)memset(&msgds, 0, sizeof(struct msqid_ds));
2633440ea09Sjruoho
2643440ea09Sjruoho pw = getpwnam("nobody");
2653440ea09Sjruoho id = msgget(MSG_KEY, IPC_CREAT | 0600);
2663440ea09Sjruoho
2673440ea09Sjruoho ATF_REQUIRE(id != -1);
2683440ea09Sjruoho ATF_REQUIRE(pw != NULL);
2693440ea09Sjruoho ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0);
2703440ea09Sjruoho
2713440ea09Sjruoho msgds.msg_perm.uid = pw->pw_uid;
2723440ea09Sjruoho
2733440ea09Sjruoho if (msgctl(id, IPC_SET, &msgds) != 0)
2743440ea09Sjruoho atf_tc_fail("root failed to change the UID of message queue");
2753440ea09Sjruoho
2763440ea09Sjruoho msgds.msg_perm.uid = getuid();
2773440ea09Sjruoho msgds.msg_perm.gid = pw->pw_gid;
2783440ea09Sjruoho
2793440ea09Sjruoho if (msgctl(id, IPC_SET, &msgds) != 0)
2803440ea09Sjruoho atf_tc_fail("root failed to change the GID of message queue");
2813440ea09Sjruoho
2823440ea09Sjruoho /*
2833a2bdf61Sjruoho * Note: setting the qbytes to zero fails even as root.
2843440ea09Sjruoho */
2853440ea09Sjruoho msgds.msg_qbytes = 1;
2863440ea09Sjruoho msgds.msg_perm.gid = getgid();
2873440ea09Sjruoho
2883440ea09Sjruoho if (msgctl(id, IPC_SET, &msgds) != 0)
2893440ea09Sjruoho atf_tc_fail("root failed to change qbytes of message queue");
2903440ea09Sjruoho
2913440ea09Sjruoho ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
2923440ea09Sjruoho }
2933440ea09Sjruoho
ATF_TC_CLEANUP(msgctl_set,tc)2943440ea09Sjruoho ATF_TC_CLEANUP(msgctl_set, tc)
2953440ea09Sjruoho {
2963440ea09Sjruoho clean();
2973440ea09Sjruoho }
2983440ea09Sjruoho
2993440ea09Sjruoho ATF_TC_WITH_CLEANUP(msgctl_time);
ATF_TC_HEAD(msgctl_time,tc)3003440ea09Sjruoho ATF_TC_HEAD(msgctl_time, tc)
3013440ea09Sjruoho {
3023a2bdf61Sjruoho atf_tc_set_md_var(tc, "descr", "Test that access times are updated");
3033440ea09Sjruoho }
3043440ea09Sjruoho
ATF_TC_BODY(msgctl_time,tc)3053440ea09Sjruoho ATF_TC_BODY(msgctl_time, tc)
3063440ea09Sjruoho {
3073440ea09Sjruoho struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
3083440ea09Sjruoho struct msqid_ds msgds;
3093440ea09Sjruoho time_t t;
3103440ea09Sjruoho int id;
3113440ea09Sjruoho
3123440ea09Sjruoho id = msgget(MSG_KEY, IPC_CREAT | 0600);
3133440ea09Sjruoho ATF_REQUIRE(id != -1);
3143440ea09Sjruoho
3153440ea09Sjruoho t = time(NULL);
3163440ea09Sjruoho
3173440ea09Sjruoho (void)memset(&msgds, 0, sizeof(struct msqid_ds));
3183440ea09Sjruoho (void)msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT);
3193440ea09Sjruoho (void)msgctl(id, IPC_STAT, &msgds);
3203440ea09Sjruoho
32161b6ad23Sjoerg if (llabs(t - msgds.msg_stime) > 1)
3223440ea09Sjruoho atf_tc_fail("time of last msgsnd(2) was not updated");
3233440ea09Sjruoho
3243440ea09Sjruoho if (msgds.msg_rtime != 0)
3253440ea09Sjruoho atf_tc_fail("time of last msgrcv(2) was updated incorrectly");
3263440ea09Sjruoho
3273440ea09Sjruoho t = time(NULL);
3283440ea09Sjruoho
3293440ea09Sjruoho (void)memset(&msgds, 0, sizeof(struct msqid_ds));
3303440ea09Sjruoho (void)msgrcv(id, &msg, sizeof(struct msg), MSG_MTYPE_1, IPC_NOWAIT);
3313440ea09Sjruoho (void)msgctl(id, IPC_STAT, &msgds);
3323440ea09Sjruoho
33361b6ad23Sjoerg if (llabs(t - msgds.msg_rtime) > 1)
3343440ea09Sjruoho atf_tc_fail("time of last msgrcv(2) was not updated");
3353440ea09Sjruoho
3363440ea09Sjruoho /*
3373a2bdf61Sjruoho * Note: this is non-zero even after the memset(3).
3383440ea09Sjruoho */
3393440ea09Sjruoho if (msgds.msg_stime == 0)
3403440ea09Sjruoho atf_tc_fail("time of last msgsnd(2) was updated incorrectly");
3413440ea09Sjruoho
3423440ea09Sjruoho ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
3433440ea09Sjruoho }
3443440ea09Sjruoho
ATF_TC_CLEANUP(msgctl_time,tc)3453440ea09Sjruoho ATF_TC_CLEANUP(msgctl_time, tc)
3463440ea09Sjruoho {
3473440ea09Sjruoho clean();
3483440ea09Sjruoho }
3493440ea09Sjruoho
3508484134bSkre static volatile int sig_caught;
3518484134bSkre
3528484134bSkre static void
sigsys_handler(int signum)3538484134bSkre sigsys_handler(int signum)
3548484134bSkre {
3558484134bSkre
3568484134bSkre sig_caught = signum;
3578484134bSkre }
3588484134bSkre
3598484134bSkre static int
no_kernel_sysvmsg(void)3608484134bSkre no_kernel_sysvmsg(void)
3618484134bSkre {
3628484134bSkre int id;
363*1a54b3c7Skre void (*osig)(int);
3648484134bSkre
3658484134bSkre sig_caught = 0;
366*1a54b3c7Skre osig = signal(SIGSYS, sigsys_handler);
3678484134bSkre id = msgget(MSG_KEY, IPC_CREAT | 0600);
3688484134bSkre if (sig_caught || id == -1)
3698484134bSkre return 1;
3708484134bSkre
3718484134bSkre (void)msgctl(id, IPC_RMID, 0);
372*1a54b3c7Skre (void)signal(SIGSYS, osig);
3738484134bSkre
3748484134bSkre return 0;
3758484134bSkre }
3768484134bSkre
3778484134bSkre ATF_TC(msgctl_query);
ATF_TC_HEAD(msgctl_query,tc)3788484134bSkre ATF_TC_HEAD(msgctl_query, tc)
3798484134bSkre {
3808484134bSkre atf_tc_set_md_var(tc, "descr", "Skip msgctl_* tests - no SYSVMSG");
3818484134bSkre }
ATF_TC_BODY(msgctl_query,tc)3828484134bSkre ATF_TC_BODY(msgctl_query, tc)
3838484134bSkre {
3848484134bSkre atf_tc_skip("No SYSVMSG in kernel");
3858484134bSkre }
3868484134bSkre
ATF_TP_ADD_TCS(tp)3873440ea09Sjruoho ATF_TP_ADD_TCS(tp)
3883440ea09Sjruoho {
3893440ea09Sjruoho
3908484134bSkre if (no_kernel_sysvmsg()) {
3918484134bSkre ATF_TP_ADD_TC(tp, msgctl_query);
3928484134bSkre } else {
3933440ea09Sjruoho ATF_TP_ADD_TC(tp, msgctl_err);
3943440ea09Sjruoho ATF_TP_ADD_TC(tp, msgctl_perm);
3953440ea09Sjruoho ATF_TP_ADD_TC(tp, msgctl_pid);
3963440ea09Sjruoho ATF_TP_ADD_TC(tp, msgctl_set);
3973440ea09Sjruoho ATF_TP_ADD_TC(tp, msgctl_time);
3988484134bSkre }
3993440ea09Sjruoho
4003440ea09Sjruoho return atf_no_error();
4013440ea09Sjruoho }
402