Skip to content

Commit 86311de

Browse files
committed
tests: add test 63-live-notify_addfd for C
Signed-off-by: Sudipta Pandit <sudpandit@microsoft.com>
1 parent 46786d5 commit 86311de

File tree

4 files changed

+226
-2
lines changed

4 files changed

+226
-2
lines changed

tests/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,4 @@ util.pyc
7070
60-sim-precompute
7171
61-sim-transactions
7272
62-sim-arch_transactions
73+
63-live-notify_addfd

tests/63-live-notify_addfd.c

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
/**
2+
* Seccomp Library test program
3+
*
4+
* Copyright (c) 2025 Microsoft Corporation <sudpandit@microsoft.com>
5+
* Author: Sudipta Pandit <sudpandit@microsoft.com>
6+
*/
7+
8+
/*
9+
* This library is free software; you can redistribute it and/or modify it
10+
* under the terms of version 2.1 of the GNU Lesser General Public License as
11+
* published by the Free Software Foundation.
12+
*
13+
* This library is distributed in the hope that it will be useful, but WITHOUT
14+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
16+
* for more details.
17+
*
18+
* You should have received a copy of the GNU Lesser General Public License
19+
* along with this library; if not, see <http://www.gnu.org/licenses>.
20+
*/
21+
22+
#include <errno.h>
23+
#include <fcntl.h>
24+
#include <seccomp.h>
25+
#include <string.h>
26+
#include <sys/socket.h>
27+
#include <sys/wait.h>
28+
#include <unistd.h>
29+
30+
31+
int send_fd(int sock, int fd)
32+
{
33+
struct iovec iov = {.iov_base = "F", .iov_len = 1};
34+
char buffer[CMSG_SPACE(sizeof(fd))]; // Do i need to set it to zero?
35+
memset(buffer, 0, sizeof(buffer));
36+
37+
struct msghdr msg = {
38+
.msg_iov = &iov,
39+
.msg_iovlen = 1,
40+
.msg_control = buffer,
41+
.msg_controllen = sizeof(buffer)
42+
};
43+
44+
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
45+
cmsg->cmsg_level = SOL_SOCKET;
46+
cmsg->cmsg_type = SCM_RIGHTS;
47+
cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
48+
49+
memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
50+
51+
return sendmsg(sock, &msg, 0);
52+
}
53+
54+
int recv_fd(int sock)
55+
{
56+
char m_buffer[1];
57+
struct iovec iov = {.iov_base = m_buffer, .iov_len = 1};
58+
59+
char buffer[CMSG_SPACE(sizeof(int))];
60+
struct msghdr msg = {
61+
.msg_iov = &iov,
62+
.msg_iovlen = 1,
63+
.msg_control = buffer,
64+
.msg_controllen = sizeof(buffer)
65+
};
66+
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
67+
68+
if (recvmsg(sock, &msg, 0) < 0)
69+
return -1;
70+
71+
int fd;
72+
memcpy(&fd, CMSG_DATA(cmsg), sizeof(fd));
73+
return fd;
74+
}
75+
76+
int main(int argc, char *argv[])
77+
{
78+
int rc, status;
79+
int sock_pair[2];
80+
int notify_fd = -1, new_fd = -1;
81+
struct seccomp_notif *req = NULL;
82+
struct seccomp_notif_resp *resp = NULL;
83+
struct seccomp_notif_addfd addfd = {0};
84+
scmp_filter_ctx ctx = NULL;
85+
pid_t pid = 0;
86+
87+
ctx = seccomp_init(SCMP_ACT_ALLOW);
88+
if (ctx == NULL)
89+
return ENOMEM;
90+
91+
rc = seccomp_rule_add(ctx, SCMP_ACT_NOTIFY, SCMP_SYS(openat), 0, NULL);
92+
if (rc)
93+
goto out;
94+
95+
// set up socket pair for sending notify_fd
96+
rc = socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sock_pair);
97+
if (rc < 0) {
98+
rc = -errno;
99+
goto out;
100+
}
101+
102+
pid = fork();
103+
if (pid == 0) {
104+
close(sock_pair[0]); // close the parent's end
105+
106+
rc = seccomp_load(ctx);
107+
if (rc < 0)
108+
goto out;
109+
110+
rc = seccomp_notify_fd(ctx);
111+
if (rc < 0)
112+
goto out;
113+
notify_fd = rc;
114+
115+
rc = send_fd(sock_pair[1], notify_fd);
116+
if (rc < 0) {
117+
rc = -errno;
118+
goto out;
119+
}
120+
close(notify_fd);
121+
122+
int ret = openat(AT_FDCWD, "/etc/hostname", O_RDONLY);
123+
if (ret < 0) {
124+
exit(ret);
125+
}
126+
127+
char buf[128];
128+
ssize_t bytes_read = read(ret, buf, sizeof(buf));
129+
130+
close(ret);
131+
close(sock_pair[1]);
132+
exit(bytes_read); // bytes_read should be 0, as it's reading /dev/null
133+
} else {
134+
close(sock_pair[1]); // close the child's end
135+
rc = recv_fd(sock_pair[0]);
136+
if (rc < 0) {
137+
rc = -errno;
138+
goto out;
139+
}
140+
notify_fd = rc;
141+
142+
rc = seccomp_notify_alloc(&req, &resp);
143+
if (rc)
144+
goto out;
145+
146+
rc = seccomp_notify_receive(notify_fd, req);
147+
if (rc)
148+
goto out;
149+
if (req->data.nr != __NR_openat) {
150+
rc = -EFAULT;
151+
goto out;
152+
}
153+
154+
new_fd = openat(AT_FDCWD, "/dev/null", O_RDONLY);
155+
if (new_fd < 0) {
156+
rc = -errno;
157+
goto out;
158+
}
159+
160+
memset(&addfd, 0, sizeof(addfd));
161+
addfd.id = req->id;
162+
addfd.srcfd = new_fd;
163+
addfd.newfd = 0;
164+
addfd.flags = 0;
165+
rc = seccomp_notify_addfd(notify_fd, &addfd);
166+
if (rc < 0)
167+
goto out;
168+
int installed_fd = rc;
169+
170+
rc = seccomp_notify_id_valid(notify_fd, req->id);
171+
if (rc)
172+
goto out;
173+
174+
resp->id = req->id;
175+
resp->val = installed_fd;
176+
resp->error = 0;
177+
resp->flags = 0;
178+
rc = seccomp_notify_respond(notify_fd, resp);
179+
if (rc)
180+
goto out;
181+
182+
if (waitpid(pid, &status, 0) != pid) {
183+
rc = -EFAULT;
184+
goto out;
185+
}
186+
187+
if (!WIFEXITED(status)) {
188+
rc = -EFAULT;
189+
goto out;
190+
}
191+
if (WEXITSTATUS(status)) {
192+
rc = -EFAULT;
193+
goto out;
194+
}
195+
196+
out:
197+
if (notify_fd >= 0)
198+
close(notify_fd);
199+
if (new_fd >= 0)
200+
close(new_fd);
201+
if (pid)
202+
kill(pid, SIGKILL);
203+
seccomp_notify_free(req, resp);
204+
seccomp_release(ctx);
205+
206+
if (rc != 0)
207+
return (rc < 0 ? -rc : rc);
208+
return 160;
209+
}
210+
}

tests/63-live-notify_addfd.tests

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#
2+
# libseccomp regression test automation data
3+
#
4+
# Copyright (c) 2025 Microsoft Corporation <sudpandit@microsoft.com>
5+
# Author: Sudipta Pandit <sudpandit@microsoft.com>
6+
#
7+
8+
test type: live
9+
10+
# Testname API Result
11+
63-live-notify_addfd 5 ALLOW

tests/Makefile.am

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ check_PROGRAMS = \
9797
59-basic-empty_binary_tree \
9898
60-sim-precompute \
9999
61-sim-transactions \
100-
62-sim-arch_transactions
100+
62-sim-arch_transactions \
101+
63-live-notify_addfd
101102

102103
EXTRA_DIST_TESTPYTHON = \
103104
util.py \
@@ -224,7 +225,8 @@ EXTRA_DIST_TESTCFGS = \
224225
59-basic-empty_binary_tree.tests \
225226
60-sim-precompute.tests \
226227
61-sim-transactions.tests \
227-
62-sim-arch_transactions.tests
228+
62-sim-arch_transactions.tests \
229+
63-live-notify_addfd.tests
228230

229231
EXTRA_DIST_TESTSCRIPTS = \
230232
38-basic-pfc_coverage.sh 38-basic-pfc_coverage.pfc \

0 commit comments

Comments
 (0)