File Index
Files and directories
Sign in
FILE

fclog.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/filesystems/fclog.c C
  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
 29FIXTURE(ns)
 30{
 31	int host_mntns;
 32};
 33
 34FIXTURE_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
 45FIXTURE_TEARDOWN(ns)
 46{
 47	ASSERT_SUCCESS(setns(self->host_mntns, CLONE_NEWNS));
 48	ASSERT_SUCCESS(close(self->host_mntns));
 49}
 50
 51TEST_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
 64TEST_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
 80TEST_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
105TEST_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
130TEST_HARNESS_MAIN
~/ Read-only file preview.