Skip to content

Commit df579e4

Browse files
cypharbrauner
authored andcommitted
selftests/filesystems: add basic fscontext log tests
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com> Link: https://lore.kernel.org/20250807-fscontext-log-cleanups-v3-2-8d91d6242dc3@cyphar.com Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent 72d271a commit df579e4

3 files changed

Lines changed: 132 additions & 1 deletion

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# SPDX-License-Identifier: GPL-2.0-only
22
dnotify_test
33
devpts_pts
4+
fclog
45
file_stressor
56
anon_inode_test
67
kernfs_test
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# SPDX-License-Identifier: GPL-2.0
22

33
CFLAGS += $(KHDR_INCLUDES)
4-
TEST_GEN_PROGS := devpts_pts file_stressor anon_inode_test kernfs_test
4+
TEST_GEN_PROGS := devpts_pts file_stressor anon_inode_test kernfs_test fclog
55
TEST_GEN_PROGS_EXTENDED := dnotify_test
66

77
include ../lib.mk
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
/*
3+
* Author: Aleksa Sarai <cyphar@cyphar.com>
4+
* Copyright (C) 2025 SUSE LLC.
5+
*/
6+
7+
#include <assert.h>
8+
#include <errno.h>
9+
#include <sched.h>
10+
#include <stdio.h>
11+
#include <stdlib.h>
12+
#include <string.h>
13+
#include <unistd.h>
14+
#include <sys/mount.h>
15+
16+
#include "../kselftest_harness.h"
17+
18+
#define ASSERT_ERRNO(expected, _t, seen) \
19+
__EXPECT(expected, #expected, \
20+
({__typeof__(seen) _tmp_seen = (seen); \
21+
_tmp_seen >= 0 ? _tmp_seen : -errno; }), #seen, _t, 1)
22+
23+
#define ASSERT_ERRNO_EQ(expected, seen) \
24+
ASSERT_ERRNO(expected, ==, seen)
25+
26+
#define ASSERT_SUCCESS(seen) \
27+
ASSERT_ERRNO(0, <=, seen)
28+
29+
FIXTURE(ns)
30+
{
31+
int host_mntns;
32+
};
33+
34+
FIXTURE_SETUP(ns)
35+
{
36+
/* Stash the old mntns. */
37+
self->host_mntns = open("/proc/self/ns/mnt", O_RDONLY|O_CLOEXEC);
38+
ASSERT_SUCCESS(self->host_mntns);
39+
40+
/* Create a new mount namespace and make it private. */
41+
ASSERT_SUCCESS(unshare(CLONE_NEWNS));
42+
ASSERT_SUCCESS(mount(NULL, "/", NULL, MS_PRIVATE|MS_REC, NULL));
43+
}
44+
45+
FIXTURE_TEARDOWN(ns)
46+
{
47+
ASSERT_SUCCESS(setns(self->host_mntns, CLONE_NEWNS));
48+
ASSERT_SUCCESS(close(self->host_mntns));
49+
}
50+
51+
TEST_F(ns, fscontext_log_enodata)
52+
{
53+
int fsfd = fsopen("tmpfs", FSOPEN_CLOEXEC);
54+
ASSERT_SUCCESS(fsfd);
55+
56+
/* A brand new fscontext has no log entries. */
57+
char buf[128] = {};
58+
for (int i = 0; i < 16; i++)
59+
ASSERT_ERRNO_EQ(-ENODATA, read(fsfd, buf, sizeof(buf)));
60+
61+
ASSERT_SUCCESS(close(fsfd));
62+
}
63+
64+
TEST_F(ns, fscontext_log_errorfc)
65+
{
66+
int fsfd = fsopen("tmpfs", FSOPEN_CLOEXEC);
67+
ASSERT_SUCCESS(fsfd);
68+
69+
ASSERT_ERRNO_EQ(-EINVAL, fsconfig(fsfd, FSCONFIG_SET_STRING, "invalid-arg", "123", 0));
70+
71+
char buf[128] = {};
72+
ASSERT_SUCCESS(read(fsfd, buf, sizeof(buf)));
73+
EXPECT_STREQ("e tmpfs: Unknown parameter 'invalid-arg'\n", buf);
74+
75+
/* The message has been consumed. */
76+
ASSERT_ERRNO_EQ(-ENODATA, read(fsfd, buf, sizeof(buf)));
77+
ASSERT_SUCCESS(close(fsfd));
78+
}
79+
80+
TEST_F(ns, fscontext_log_errorfc_after_fsmount)
81+
{
82+
int fsfd = fsopen("tmpfs", FSOPEN_CLOEXEC);
83+
ASSERT_SUCCESS(fsfd);
84+
85+
ASSERT_ERRNO_EQ(-EINVAL, fsconfig(fsfd, FSCONFIG_SET_STRING, "invalid-arg", "123", 0));
86+
87+
ASSERT_SUCCESS(fsconfig(fsfd, FSCONFIG_CMD_CREATE, NULL, NULL, 0));
88+
int mfd = fsmount(fsfd, FSMOUNT_CLOEXEC, MOUNT_ATTR_NOEXEC | MOUNT_ATTR_NOSUID);
89+
ASSERT_SUCCESS(mfd);
90+
ASSERT_SUCCESS(move_mount(mfd, "", AT_FDCWD, "/tmp", MOVE_MOUNT_F_EMPTY_PATH));
91+
92+
/*
93+
* The fscontext log should still contain data even after
94+
* FSCONFIG_CMD_CREATE and fsmount().
95+
*/
96+
char buf[128] = {};
97+
ASSERT_SUCCESS(read(fsfd, buf, sizeof(buf)));
98+
EXPECT_STREQ("e tmpfs: Unknown parameter 'invalid-arg'\n", buf);
99+
100+
/* The message has been consumed. */
101+
ASSERT_ERRNO_EQ(-ENODATA, read(fsfd, buf, sizeof(buf)));
102+
ASSERT_SUCCESS(close(fsfd));
103+
}
104+
105+
TEST_F(ns, fscontext_log_emsgsize)
106+
{
107+
int fsfd = fsopen("tmpfs", FSOPEN_CLOEXEC);
108+
ASSERT_SUCCESS(fsfd);
109+
110+
ASSERT_ERRNO_EQ(-EINVAL, fsconfig(fsfd, FSCONFIG_SET_STRING, "invalid-arg", "123", 0));
111+
112+
char buf[128] = {};
113+
/*
114+
* Attempting to read a message with too small a buffer should not
115+
* result in the message getting consumed.
116+
*/
117+
ASSERT_ERRNO_EQ(-EMSGSIZE, read(fsfd, buf, 0));
118+
ASSERT_ERRNO_EQ(-EMSGSIZE, read(fsfd, buf, 1));
119+
for (int i = 0; i < 16; i++)
120+
ASSERT_ERRNO_EQ(-EMSGSIZE, read(fsfd, buf, 16));
121+
122+
ASSERT_SUCCESS(read(fsfd, buf, sizeof(buf)));
123+
EXPECT_STREQ("e tmpfs: Unknown parameter 'invalid-arg'\n", buf);
124+
125+
/* The message has been consumed. */
126+
ASSERT_ERRNO_EQ(-ENODATA, read(fsfd, buf, sizeof(buf)));
127+
ASSERT_SUCCESS(close(fsfd));
128+
}
129+
130+
TEST_HARNESS_MAIN

0 commit comments

Comments
 (0)