From: Aleksa Sarai <cyphar@cyphar.com>
To: Ingo Molnar <mingo@redhat.com>,
Peter Zijlstra <peterz@infradead.org>,
Juri Lelli <juri.lelli@redhat.com>,
Vincent Guittot <vincent.guittot@linaro.org>,
Dietmar Eggemann <dietmar.eggemann@arm.com>,
Steven Rostedt <rostedt@goodmis.org>,
Ben Segall <bsegall@google.com>, Mel Gorman <mgorman@suse.de>,
Valentin Schneider <vschneid@redhat.com>,
Alexander Viro <viro@zeniv.linux.org.uk>,
Christian Brauner <brauner@kernel.org>, Jan Kara <jack@suse.cz>,
Arnd Bergmann <arnd@arndb.de>, Shuah Khan <shuah@kernel.org>
Cc: Kees Cook <kees@kernel.org>, Florian Weimer <fweimer@redhat.com>,
Arnd Bergmann <arnd@arndb.de>,
Mark Rutland <mark.rutland@arm.com>,
linux-kernel@vger.kernel.org, linux-api@vger.kernel.org,
linux-fsdevel@vger.kernel.org, linux-arch@vger.kernel.org,
linux-kselftest@vger.kernel.org,
Aleksa Sarai <cyphar@cyphar.com>
Subject: [PATCH RFC v3 10/10] selftests: mount_setattr: add CHECK_FIELDS selftest
Date: Thu, 10 Oct 2024 07:40:43 +1100 [thread overview]
Message-ID: <20241010-extensible-structs-check_fields-v3-10-d2833dfe6edd@cyphar.com> (raw)
In-Reply-To: <20241010-extensible-structs-check_fields-v3-0-d2833dfe6edd@cyphar.com>
While we're at it -- to make testing for error codes with ASSERT_*
easier, make the sys_* wrappers return -errno in case of an error.
For some reason, the <sys/sysinfo.h> include doesn't correct import
<asm/posix_types.h>, leading to compilation errors -- so just import
<asm/posix_types.h> manually.
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
---
tools/include/uapi/asm-generic/posix_types.h | 101 +++++++++++++++++++++
tools/testing/selftests/mount_setattr/Makefile | 2 +-
.../selftests/mount_setattr/mount_setattr_test.c | 53 ++++++++++-
3 files changed, 153 insertions(+), 3 deletions(-)
diff --git a/tools/include/uapi/asm-generic/posix_types.h b/tools/include/uapi/asm-generic/posix_types.h
new file mode 100644
index 000000000000..b5f7594eee7a
--- /dev/null
+++ b/tools/include/uapi/asm-generic/posix_types.h
@@ -0,0 +1,101 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef __ASM_GENERIC_POSIX_TYPES_H
+#define __ASM_GENERIC_POSIX_TYPES_H
+
+#include <asm/bitsperlong.h>
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.
+ *
+ * First the types that are often defined in different ways across
+ * architectures, so that you can override them.
+ */
+
+#ifndef __kernel_long_t
+typedef long __kernel_long_t;
+typedef unsigned long __kernel_ulong_t;
+#endif
+
+#ifndef __kernel_ino_t
+typedef __kernel_ulong_t __kernel_ino_t;
+#endif
+
+#ifndef __kernel_mode_t
+typedef unsigned int __kernel_mode_t;
+#endif
+
+#ifndef __kernel_pid_t
+typedef int __kernel_pid_t;
+#endif
+
+#ifndef __kernel_ipc_pid_t
+typedef int __kernel_ipc_pid_t;
+#endif
+
+#ifndef __kernel_uid_t
+typedef unsigned int __kernel_uid_t;
+typedef unsigned int __kernel_gid_t;
+#endif
+
+#ifndef __kernel_suseconds_t
+typedef __kernel_long_t __kernel_suseconds_t;
+#endif
+
+#ifndef __kernel_daddr_t
+typedef int __kernel_daddr_t;
+#endif
+
+#ifndef __kernel_uid32_t
+typedef unsigned int __kernel_uid32_t;
+typedef unsigned int __kernel_gid32_t;
+#endif
+
+#ifndef __kernel_old_uid_t
+typedef __kernel_uid_t __kernel_old_uid_t;
+typedef __kernel_gid_t __kernel_old_gid_t;
+#endif
+
+#ifndef __kernel_old_dev_t
+typedef unsigned int __kernel_old_dev_t;
+#endif
+
+/*
+ * Most 32 bit architectures use "unsigned int" size_t,
+ * and all 64 bit architectures use "unsigned long" size_t.
+ */
+#ifndef __kernel_size_t
+#if __BITS_PER_LONG != 64
+typedef unsigned int __kernel_size_t;
+typedef int __kernel_ssize_t;
+typedef int __kernel_ptrdiff_t;
+#else
+typedef __kernel_ulong_t __kernel_size_t;
+typedef __kernel_long_t __kernel_ssize_t;
+typedef __kernel_long_t __kernel_ptrdiff_t;
+#endif
+#endif
+
+#ifndef __kernel_fsid_t
+typedef struct {
+ int val[2];
+} __kernel_fsid_t;
+#endif
+
+/*
+ * anything below here should be completely generic
+ */
+typedef __kernel_long_t __kernel_off_t;
+typedef long long __kernel_loff_t;
+typedef __kernel_long_t __kernel_old_time_t;
+#ifndef __KERNEL__
+typedef __kernel_long_t __kernel_time_t;
+#endif
+typedef long long __kernel_time64_t;
+typedef __kernel_long_t __kernel_clock_t;
+typedef int __kernel_timer_t;
+typedef int __kernel_clockid_t;
+typedef char * __kernel_caddr_t;
+typedef unsigned short __kernel_uid16_t;
+typedef unsigned short __kernel_gid16_t;
+
+#endif /* __ASM_GENERIC_POSIX_TYPES_H */
diff --git a/tools/testing/selftests/mount_setattr/Makefile b/tools/testing/selftests/mount_setattr/Makefile
index 0c0d7b1234c1..3f260506fe60 100644
--- a/tools/testing/selftests/mount_setattr/Makefile
+++ b/tools/testing/selftests/mount_setattr/Makefile
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
# Makefile for mount selftests.
-CFLAGS = -g $(KHDR_INCLUDES) -Wall -O2 -pthread
+CFLAGS = -g $(KHDR_INCLUDES) $(TOOLS_INCLUDES) -Wall -O2 -pthread
TEST_GEN_PROGS := mount_setattr_test
diff --git a/tools/testing/selftests/mount_setattr/mount_setattr_test.c b/tools/testing/selftests/mount_setattr/mount_setattr_test.c
index c6a8c732b802..36b8286e5f43 100644
--- a/tools/testing/selftests/mount_setattr/mount_setattr_test.c
+++ b/tools/testing/selftests/mount_setattr/mount_setattr_test.c
@@ -11,6 +11,7 @@
#include <sys/wait.h>
#include <sys/vfs.h>
#include <sys/statvfs.h>
+#include <asm/posix_types.h> /* get __kernel_* typedefs */
#include <sys/sysinfo.h>
#include <stdlib.h>
#include <unistd.h>
@@ -137,7 +138,8 @@
static inline int sys_mount_setattr(int dfd, const char *path, unsigned int flags,
struct mount_attr *attr, size_t size)
{
- return syscall(__NR_mount_setattr, dfd, path, flags, attr, size);
+ int ret = syscall(__NR_mount_setattr, dfd, path, flags, attr, size);
+ return ret >= 0 ? ret : -errno;
}
#ifndef OPEN_TREE_CLONE
@@ -152,9 +154,24 @@ static inline int sys_mount_setattr(int dfd, const char *path, unsigned int flag
#define AT_RECURSIVE 0x8000 /* Apply to the entire subtree */
#endif
+#define FSMOUNT_VALID_FLAGS \
+ (MOUNT_ATTR_RDONLY | MOUNT_ATTR_NOSUID | MOUNT_ATTR_NODEV | \
+ MOUNT_ATTR_NOEXEC | MOUNT_ATTR__ATIME | MOUNT_ATTR_NODIRATIME | \
+ MOUNT_ATTR_NOSYMFOLLOW)
+
+#define MOUNT_SETATTR_VALID_FLAGS (FSMOUNT_VALID_FLAGS | MOUNT_ATTR_IDMAP)
+
+#define MOUNT_SETATTR_PROPAGATION_FLAGS \
+ (MS_UNBINDABLE | MS_PRIVATE | MS_SLAVE | MS_SHARED)
+
+#ifndef CHECK_FIELDS
+#define CHECK_FIELDS (1ULL << 63)
+#endif
+
static inline int sys_open_tree(int dfd, const char *filename, unsigned int flags)
{
- return syscall(__NR_open_tree, dfd, filename, flags);
+ int ret = syscall(__NR_open_tree, dfd, filename, flags);
+ return ret >= 0 ? ret : -errno;
}
static ssize_t write_nointr(int fd, const void *buf, size_t count)
@@ -1497,4 +1514,36 @@ TEST_F(mount_setattr, mount_attr_nosymfollow)
ASSERT_EQ(close(fd), 0);
}
+TEST_F(mount_setattr, check_fields)
+{
+ struct mount_attr_ext {
+ struct mount_attr inner;
+ uint64_t extra1;
+ uint64_t extra2;
+ uint64_t extra3;
+ } attr;
+
+ /* Set the structure to dummy values. */
+ memset(&attr, 0xAB, sizeof(attr));
+
+ if (!mount_setattr_supported())
+ SKIP(return, "mount_setattr syscall not supported");
+
+ /* Make sure that invalid sizes are detected even with CHECK_FIELDS. */
+ EXPECT_EQ(sys_mount_setattr(-1, "", 0, (struct mount_attr *) &attr, CHECK_FIELDS), -EINVAL);
+ EXPECT_EQ(sys_mount_setattr(-1, "", 0, (struct mount_attr *) &attr, CHECK_FIELDS | 0xF000), -E2BIG);
+
+ /* Actually get the CHECK_FIELDS results. */
+ ASSERT_EQ(sys_mount_setattr(-1, "", 0, (struct mount_attr *) &attr, CHECK_FIELDS | sizeof(attr)), -EEXTSYS_NOOP);
+
+ EXPECT_EQ(attr.inner.attr_set, MOUNT_SETATTR_VALID_FLAGS);
+ EXPECT_EQ(attr.inner.attr_clr, MOUNT_SETATTR_VALID_FLAGS);
+ EXPECT_EQ(attr.inner.propagation, MOUNT_SETATTR_PROPAGATION_FLAGS);
+ EXPECT_EQ(attr.inner.userns_fd, 0xFFFFFFFFFFFFFFFF);
+ /* Trailing fields outside ksize must be zeroed. */
+ EXPECT_EQ(attr.extra1, 0);
+ EXPECT_EQ(attr.extra2, 0);
+ EXPECT_EQ(attr.extra3, 0);
+}
+
TEST_HARNESS_MAIN
--
2.46.1
next prev parent reply other threads:[~2024-10-09 20:42 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-09 20:40 [PATCH RFC v3 00/10] extensible syscalls: CHECK_FIELDS to allow for easier feature detection Aleksa Sarai
2024-10-09 20:40 ` [PATCH RFC v3 01/10] uaccess: add copy_struct_to_user helper Aleksa Sarai
2024-10-09 20:40 ` [PATCH RFC v3 02/10] sched_getattr: port to copy_struct_to_user Aleksa Sarai
2024-12-10 18:14 ` Florian Weimer
2024-12-11 10:23 ` Christian Brauner
2025-01-18 13:02 ` Xi Ruoyao
2025-01-20 5:28 ` Florian Weimer
2025-01-20 9:21 ` Xi Ruoyao
2025-01-20 9:51 ` Florian Weimer
2024-10-09 20:40 ` [PATCH RFC v3 03/10] openat2: explicitly return -E2BIG for (usize > PAGE_SIZE) Aleksa Sarai
2024-10-10 6:24 ` Greg KH
2024-10-10 10:09 ` (subset) " Christian Brauner
2024-10-09 20:40 ` [PATCH RFC v3 04/10] openat2: add CHECK_FIELDS flag to usize argument Aleksa Sarai
2024-10-09 20:40 ` [PATCH RFC v3 05/10] selftests: openat2: add 0xFF poisoned data after misaligned struct Aleksa Sarai
2024-10-09 20:40 ` [PATCH RFC v3 06/10] selftests: openat2: add CHECK_FIELDS selftests Aleksa Sarai
2024-10-09 20:40 ` [PATCH RFC v3 07/10] clone3: add CHECK_FIELDS flag to usize argument Aleksa Sarai
2024-10-09 20:40 ` [PATCH RFC v3 08/10] selftests: clone3: add CHECK_FIELDS selftests Aleksa Sarai
2024-10-09 20:40 ` [PATCH RFC v3 09/10] mount_setattr: add CHECK_FIELDS flag to usize argument Aleksa Sarai
2024-10-09 20:40 ` Aleksa Sarai [this message]
2024-10-10 6:26 ` [PATCH RFC v3 00/10] extensible syscalls: CHECK_FIELDS to allow for easier feature detection Florian Weimer
2024-10-21 14:51 ` (subset) " Christian Brauner
2024-10-21 21:38 ` Aleksa Sarai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241010-extensible-structs-check_fields-v3-10-d2833dfe6edd@cyphar.com \
--to=cyphar@cyphar.com \
--cc=arnd@arndb.de \
--cc=brauner@kernel.org \
--cc=bsegall@google.com \
--cc=dietmar.eggemann@arm.com \
--cc=fweimer@redhat.com \
--cc=jack@suse.cz \
--cc=juri.lelli@redhat.com \
--cc=kees@kernel.org \
--cc=linux-api@vger.kernel.org \
--cc=linux-arch@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=mgorman@suse.de \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
--cc=shuah@kernel.org \
--cc=vincent.guittot@linaro.org \
--cc=viro@zeniv.linux.org.uk \
--cc=vschneid@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).