Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Christian Brauner <brauner@kernel.org>
To: linux-fsdevel@vger.kernel.org
Cc: Alexander Viro <viro@zeniv.linux.org.uk>, Jan Kara <jack@suse.cz>,
	 Kees Cook <kees@kernel.org>,
	linux-mm@kvack.org,  linux-kernel@vger.kernel.org,
	bpf@vger.kernel.org,  linux-doc@vger.kernel.org,
	Farid Zakaria <farid.m.zakaria@gmail.com>,
	 "Christian Brauner (Amutable)" <brauner@kernel.org>
Subject: [PATCH 2/3] selftests/exec: test delimiter restrictions
Date: Wed, 26 Aug 2026 17:55:47 +0200	[thread overview]
Message-ID: <20260826-work-binfmt_misc-delim-v1-2-43618adf8599@kernel.org> (raw)
In-Reply-To: <20260826-work-binfmt_misc-delim-v1-0-43618adf8599@kernel.org>

Test that the new delimiter restrictions work.

Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
---
 tools/testing/selftests/exec/Makefile            |   4 +
 tools/testing/selftests/exec/binfmt_misc_delim.c | 127 +++++++++++++++++++++++
 2 files changed, 131 insertions(+)

diff --git a/tools/testing/selftests/exec/Makefile b/tools/testing/selftests/exec/Makefile
index b640af8f02b5..2220ed345e92 100644
--- a/tools/testing/selftests/exec/Makefile
+++ b/tools/testing/selftests/exec/Makefile
@@ -45,6 +45,10 @@ TEST_GEN_FILES += binfmt_transparent_interp
 TEST_GEN_PROGS += binfmt_misc_loader
 TEST_GEN_FILES += binfmt_loader_payload binfmt_loader_payload_static
 
+# Only ASCII punctuation delimits the fields of a register string, so a new
+# flag character cannot change which strings register. No bpf toolchain.
+TEST_GEN_PROGS += binfmt_misc_delim
+
 # binfmt_misc bpf-backed ('B') handler test: a libbpf harness plus its
 # struct_ops objects and the test interpreter/app it routes between. Only
 # built when clang, bpftool, the vmlinux BTF and libbpf are all present
diff --git a/tools/testing/selftests/exec/binfmt_misc_delim.c b/tools/testing/selftests/exec/binfmt_misc_delim.c
new file mode 100644
index 000000000000..ffc17cb78545
--- /dev/null
+++ b/tools/testing/selftests/exec/binfmt_misc_delim.c
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Test which characters may delimit the fields of a register string.
+ */
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "binfmt_misc_common.h"
+#include "kselftest_harness.h"
+
+#define ENTRY	"bmdelim"
+/* Shares no character with the sets below, or a refusal proves nothing. */
+#define MAGIC	"bmmagic"
+#define INTERP	"/bin/true"
+
+/*
+ * ASCII punctuation without '\' and '/'. The backslash is refused because
+ * it would cut a magic that uses \x to escape short. '/' is accepted
+ * but cannot delimit a rule that names an absolute interpreter.
+ */
+#define PUNCTUATION	"!\"#$%&'()*+,-.:;<=>?@[]^_`{|}~"
+
+/* 'M', 'E' and 'B' name types, 'P' through 'D' are the flags. */
+#define LETTERS		"MEBPOCFTLDqz"
+#define DIGITS		"0157"
+#define WHITESPACE	" \t\n"
+#define CONTROL		"\001\033\177"
+#define NON_ASCII	"\200\244\377"
+
+/* ':bmdelim:E::bmmagic::/bin/true:' with @del in place of every ':'. */
+static int register_with(char del)
+{
+	char rule[128];
+
+	snprintf(rule, sizeof(rule), "%c%s%cE%c%c%s%c%c%s%c", del, ENTRY, del,
+		 del, del, MAGIC, del, del, INTERP, del);
+	return write_reg(rule);
+}
+
+/* No character of @set may delimit a register string. */
+static void expect_refused(struct __test_metadata *_metadata, const char *set)
+{
+	const char *d;
+
+	for (d = set; *d; d++) {
+		int rc = register_with(*d);
+
+		EXPECT_EQ(rc, -1)
+			TH_LOG("%#x delimited a register string",
+			       (unsigned char)*d);
+		if (rc == 0) {
+			unregister(ENTRY);
+			continue;
+		}
+		EXPECT_EQ(errno, EINVAL);
+	}
+}
+
+FIXTURE(delim) {
+};
+
+FIXTURE_SETUP(delim)
+{
+	if (getuid() != 0)
+		SKIP(return, "test must be run as root");
+	if (!binfmt_misc_available())
+		SKIP(return, "no binfmt_misc");
+
+	/* A kernel without the allow-list takes any character but a flag. */
+	if (register_with('q') == 0) {
+		unregister(ENTRY);
+		SKIP(return, "kernel without the delimiter allow-list");
+	}
+}
+
+FIXTURE_TEARDOWN(delim)
+{
+	unregister(ENTRY);
+}
+
+/* Punctuation delimits, which is all anything deployed ever uses. */
+TEST_F(delim, punctuation_accepted)
+{
+	const char *d;
+
+	for (d = PUNCTUATION; *d; d++) {
+		EXPECT_EQ(register_with(*d), 0)
+			TH_LOG("'%c' refused with errno %d", *d, errno);
+		unregister(ENTRY);
+	}
+}
+
+/* Letters name the types and the flags, so none of them can delimit. */
+TEST_F(delim, letters_refused)
+{
+	expect_refused(_metadata, LETTERS);
+}
+
+/* The offset field is written in digits. */
+TEST_F(delim, digits_refused)
+{
+	expect_refused(_metadata, DIGITS);
+}
+
+TEST_F(delim, whitespace_refused)
+{
+	expect_refused(_metadata, WHITESPACE);
+}
+
+TEST_F(delim, control_refused)
+{
+	expect_refused(_metadata, CONTROL);
+}
+
+TEST_F(delim, non_ascii_refused)
+{
+	expect_refused(_metadata, NON_ASCII);
+}
+
+/* The escape character would cut every magic that uses one short. */
+TEST_F(delim, backslash_refused)
+{
+	expect_refused(_metadata, "\\");
+}
+
+TEST_HARNESS_MAIN

-- 
2.53.0



  parent reply	other threads:[~2026-08-26 15:56 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-26 15:55 [PATCH 0/3] binfmt_misc: only let punctuation delimit a register string Christian Brauner
2026-08-26 15:55 ` [PATCH 1/3] " Christian Brauner
2026-08-28  3:50   ` Farid Zakaria
2026-08-26 15:55 ` Christian Brauner [this message]
2026-08-26 15:55 ` [PATCH 3/3] binfmt_misc: document the field delimiter Christian Brauner
2026-08-28  3:50   ` Farid Zakaria
2026-08-28  3:50 ` [PATCH 0/3] binfmt_misc: only let punctuation delimit a register string Farid Zakaria

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=20260826-work-binfmt_misc-delim-v1-2-43618adf8599@kernel.org \
    --to=brauner@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=farid.m.zakaria@gmail.com \
    --cc=jack@suse.cz \
    --cc=kees@kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=viro@zeniv.linux.org.uk \
    /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