Commit e540ad97 authored by Rodrigo Campos's avatar Rodrigo Campos Committed by Kees Cook
Browse files

selftests/seccomp: Add test for atomic addfd+send



This just adds a test to verify that when using the new introduced flag
to ADDFD, a valid fd is added and returned as the syscall result.

Signed-off-by: default avatarRodrigo Campos <rodrigo@kinvolk.io>
Signed-off-by: default avatarSargun Dhillon <sargun@sargun.me>
Acked-by: default avatarTycho Andersen <tycho@tycho.pizza>
Acked-by: default avatarChristian Brauner <christian.brauner@ubuntu.com>
Signed-off-by: default avatarKees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/20210517193908.3113-5-sargun@sargun.me
parent 0ae71c77
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line
@@ -235,6 +235,10 @@ struct seccomp_notif_addfd {
};
#endif

#ifndef SECCOMP_ADDFD_FLAG_SEND
#define SECCOMP_ADDFD_FLAG_SEND	(1UL << 1) /* Addfd and return it, atomically */
#endif

struct seccomp_notif_addfd_small {
	__u64 id;
	char weird[4];
@@ -3976,8 +3980,14 @@ TEST(user_notification_addfd)
	ASSERT_GE(pid, 0);

	if (pid == 0) {
		/* fds will be added and this value is expected */
		if (syscall(__NR_getppid) != USER_NOTIF_MAGIC)
			exit(1);

		/* Atomic addfd+send is received here. Check it is a valid fd */
		if (fcntl(syscall(__NR_getppid), F_GETFD) == -1)
			exit(1);

		exit(syscall(__NR_getppid) != USER_NOTIF_MAGIC);
	}

@@ -4056,6 +4066,30 @@ TEST(user_notification_addfd)
	ASSERT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0);
	ASSERT_EQ(addfd.id, req.id);

	/* Verify we can do an atomic addfd and send */
	addfd.newfd = 0;
	addfd.flags = SECCOMP_ADDFD_FLAG_SEND;
	fd = ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd);

	/* Child has fds 0-6 and 42 used, we expect the lower fd available: 7 */
	EXPECT_EQ(fd, 7);
	EXPECT_EQ(filecmp(getpid(), pid, memfd, fd), 0);

	/*
	 * This sets the ID of the ADD FD to the last request plus 1. The
	 * notification ID increments 1 per notification.
	 */
	addfd.id = req.id + 1;

	/* This spins until the underlying notification is generated */
	while (ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd) != -1 &&
	       errno != -EINPROGRESS)
		nanosleep(&delay, NULL);

	memset(&req, 0, sizeof(req));
	ASSERT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0);
	ASSERT_EQ(addfd.id, req.id);

	resp.id = req.id;
	resp.error = 0;
	resp.val = USER_NOTIF_MAGIC;
@@ -4116,6 +4150,10 @@ TEST(user_notification_addfd_rlimit)
	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd), -1);
	EXPECT_EQ(errno, EMFILE);

	addfd.flags = SECCOMP_ADDFD_FLAG_SEND;
	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd), -1);
	EXPECT_EQ(errno, EMFILE);

	addfd.newfd = 100;
	addfd.flags = SECCOMP_ADDFD_FLAG_SETFD;
	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd), -1);