Skip to content

Commit db2a52d

Browse files
committed
tests: verify the auxstr of setns(2) when --namespace=switch is given
Signed-off-by: Masatake YAMATO <[email protected]>
1 parent e267803 commit db2a52d

File tree

3 files changed

+123
-0
lines changed

3 files changed

+123
-0
lines changed

tests/gen_tests.in

+1
Original file line numberDiff line numberDiff line change
@@ -985,6 +985,7 @@ setgroups -s2 -a17
985985
setgroups32 -s2 -a19
986986
sethostname -a22
987987
setns -a21
988+
setns-report-ns-id -a11 -e trace=setns -e namespace=switch -e signal=none
988989
setregid -a15
989990
setregid32 -a17
990991
setresgid -a19

tests/pure_executables.list

+1
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,7 @@ setgroups
716716
setgroups32
717717
sethostname
718718
setns
719+
setns-report-ns-id
719720
setregid
720721
setregid32
721722
setresgid

tests/setns-report-ns-id.c

+121
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/*
2+
* Check appending auxstr of setns(2) when --namespace=switch is given
3+
*
4+
* Copyright (c) 2024 The strace developers.
5+
* All rights reserved.
6+
*
7+
* SPDX-License-Identifier: GPL-2.0-or-later
8+
*/
9+
10+
#include "tests.h"
11+
#include "scno.h"
12+
#include "xmalloc.h"
13+
14+
#include <limits.h>
15+
#include <stdio.h>
16+
#include <stdlib.h>
17+
#include <unistd.h>
18+
#include <signal.h>
19+
#include <sys/wait.h>
20+
#include <fcntl.h>
21+
#include <errno.h>
22+
#include <sys/socket.h>
23+
24+
typedef struct msg {
25+
enum {
26+
MSG_OK = 0,
27+
MSG_ERR_CLOSE,
28+
MSG_ERR_UNSHARE,
29+
} type;
30+
int err;
31+
} msg_t;
32+
33+
int
34+
main(void)
35+
{
36+
int sv[2];
37+
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) < 0)
38+
perror_msg_and_skip("pipe");
39+
40+
pid_t pid = fork();
41+
if (pid == 0) {
42+
msg_t msg;
43+
char c;
44+
45+
if (syscall(__NR_unshare, 0x10000000) < 0) {
46+
msg.type = MSG_ERR_UNSHARE;
47+
msg.err = errno;
48+
write(sv[1], &msg, sizeof(msg));
49+
return 1;
50+
}
51+
52+
msg.type = MSG_OK;
53+
write(sv[1], &msg, sizeof(msg));
54+
read(sv[1], &c, 1);
55+
} else if (pid > 0) {
56+
ssize_t r;
57+
msg_t msg;
58+
59+
r = read(sv[0], &msg, sizeof(msg));
60+
if (r < 0)
61+
perror_msg_and_skip("read");
62+
if (r == 0)
63+
error_msg_and_skip("unexpected EOF");
64+
else if (r != sizeof(msg))
65+
error_msg_and_skip("data from the child it too short");
66+
67+
if (msg.type != MSG_OK) {
68+
errno = msg.err;
69+
perror_msg_and_skip("%s",
70+
(msg.type == MSG_ERR_CLOSE)? "close":
71+
(msg.type == MSG_ERR_UNSHARE)? "unshare":
72+
"unknown");
73+
}
74+
75+
char *ns_path = xasprintf("/proc/%u/ns/user", pid);
76+
int ns_fd = open(ns_path, O_RDONLY);
77+
if (ns_fd < 0) {
78+
int e = errno;
79+
write(sv[0], (char[]){'\n'}, 1);
80+
wait(NULL);
81+
errno = e;
82+
perror_msg_and_skip("open");
83+
}
84+
85+
long rc = syscall(__NR_setns, ns_fd, 0x10000000);
86+
printf("setns(%d, CLONE_NEWUSER) = %s%s",
87+
ns_fd, sprintrc(rc), rc == 0? "": "\n");
88+
89+
if (rc == 0) {
90+
char buf[PATH_MAX + 1];
91+
int n = readlink(ns_path, buf, sizeof(buf));
92+
if (n < 0) {
93+
int e = errno;
94+
write(sv[0], (char[]){'\n'}, 1);
95+
wait(NULL);
96+
errno = e;
97+
perror_msg_and_skip("readlink");
98+
}
99+
else if ((size_t)n >= sizeof(buf)) {
100+
write(sv[0], (char[]){'\n'}, 1);
101+
wait(NULL);
102+
error_msg_and_skip("too large readlink result");
103+
}
104+
buf[n] = '\0';
105+
printf(" (%s)\n", buf);
106+
}
107+
108+
write(sv[0], (char[]){'\n'}, 1);
109+
wait(NULL);
110+
111+
/* Verify that strace doen't print a namespace when an error occurs. */
112+
rc = syscall(__NR_setns, -1, 0x10000000);
113+
printf("setns(-1, CLONE_NEWUSER) = %s\n", sprintrc(rc));
114+
115+
puts("+++ exited with 0 +++");
116+
117+
} else
118+
perror_msg_and_skip("fork");
119+
120+
return 0;
121+
}

0 commit comments

Comments
 (0)