All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [LTP] syscalls/cachestat05: Add test for permission checks
  2026-11-05 10:46 [LTP] [PATCH] " Xuewen Wang
@ 2026-11-05 15:58 ` linuxtestproject.agent
  0 siblings, 0 replies; 3+ messages in thread
From: linuxtestproject.agent @ 2026-11-05 15:58 UTC (permalink / raw)
  To: Xuewen Wang; +Cc: ltp

Hi Xuewen,

On Thu Nov 5 18:46:17 2026 +0800, Xuewen Wang <wangxuewen@kylinos.cn> wrote:
> syscalls/cachestat05: Add test for permission checks

> +/*\
> + * Verify that cachestat() is only allowed on file descriptors with write
> + * access to the underlying file.

Use :manpage:`cachestat(2)` when referring to the syscall in the
documentation comment block.

> +static struct tcase {
> +	const char *file;
> +	int open_flags;
> +	int exp_errno;
> +	int needs_fix;
> +	const char *desc;
> +} tcases[] = {
> +	{FILE_RDWR, O_RDWR, 0, 0, "descriptor open for writing"},
> +	{FILE_OWNED, O_RDONLY, 0, 0, "file owned by the caller"},
> +	{FILE_RDWR, O_RDONLY, 0, 0, "file writable by the caller"},
> +	{FILE_RDONLY, O_RDONLY, EPERM, 1, "file read-only for the caller"},
> +};
> +
> +static void verify_cachestat(unsigned int n)
> +{
> +	struct tcase *tc = &tcases[n];
> +	int fd;
> +
> +	if (tc->needs_fix && tst_kvercmp(6, 14, 0) < 0) {
> +		tst_res(TCONF, "cachestat() permission check added in v6.14");
> +		return;
> +	}

Remove the kernel version check and tc->needs_fix. Commit 5f537664e705 is a
bug fix already recorded in .tags, so unpatched kernels should fail and print
the missing-fix hint rather than skipping with TCONF.

> +	SAFE_SETGROUPS(0, NULL);
> +	SAFE_SETGID(gid);
> +	SAFE_SETUID(uid);
> +
> +	fd = SAFE_OPEN(tc->file, tc->open_flags);

Opening FILE_RDWR (mode 0666) after dropping privileges means the caller also
has write permission on the file, so the FMODE_WRITE check in
can_do_cachestat() is not isolated from file_permission(f, MAY_WRITE). Open
tc->file before dropping privileges and use FILE_RDONLY with O_RDWR for the
first test case.

> +	fd = SAFE_OPEN(FILE_OWNED, O_CREAT | O_RDWR, 0600);
> +	SAFE_CLOSE(fd);
> +	SAFE_CHOWN(FILE_OWNED, uid, -1);

FILE_OWNED is created with mode 0600, which gives the owner write permission
and satisfies file_permission(f, MAY_WRITE) in addition to
file_owner_or_capable(). Create FILE_OWNED with mode 0400 so the ownership
check is tested without write permission.

Verdict - Needs revision

---
Note:

The agent can sometimes produce false positives although often its
findings are genuine. If you find issues with the review, please
comment this email or ignore the suggestions.

Regards,
LTP AI Reviewer

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [LTP] [PATCH v2] syscalls/cachestat05: Add test for permission checks
@ 2026-11-06  3:29 Xuewen Wang
  2026-11-06 11:34 ` [LTP] " linuxtestproject.agent
  0 siblings, 1 reply; 3+ messages in thread
From: Xuewen Wang @ 2026-11-06  3:29 UTC (permalink / raw)
  To: ltp; +Cc: Xuewen Wang

From: Xuewen Wang <wangxuewen@kylinos.cn>

Verify that cachestat() only reveals page cache statistics for files the
calling process has write access to, owns, or has open for writing, as
required by the permission check added in 5f537664e705 ("cachestat: fix
page cache statistics permission checking") to prevent page cache
residency information leaks.

A child process opens the test files as write accessor, owner, writer
and reader, drops privileges and calls cachestat(), which either
succeeds or fails with EPERM. The write-accessor descriptor is opened
on a read-only file before the privileges are dropped and the owned
file is read-only for its owner, so that each of the three permission
conditions is tested in isolation. Kernels without the fix fail the
read-only case and the test prints the missing fix hint.

Tested on 6.6.160 (with the fix backported) and 7.3.0-rc5, x86_64:
4/4 TPASS.

Signed-off-by: Xuewen Wang <wangxuewen@kylinos.cn>
---
Changes in v2 (addressing the AI review):

- Use :manpage:`cachestat(2)` for the syscall references in the doc
  comment
- Remove the kernel version check and tc->needs_fix: kernels without
  the fix fail the read-only case and the .tags linux-git hint points
  to the fix commit
- Open the test file before dropping privileges and use the read-only
  file with O_RDWR for the write-accessor case, so that the
  FMODE_WRITE condition is not confounded with the file write
  permission
- Create the owned file with mode 0400 so that the ownership condition
  is not confounded with the owner write permission
- Reword the summary to cover all three permission conditions: files
  the caller has write access to, owns, or has open for writing

 runtest/syscalls                              |   1 +
 .../kernel/syscalls/cachestat/.gitignore      |   1 +
 .../kernel/syscalls/cachestat/cachestat05.c   | 133 ++++++++++++++++++
 3 files changed, 135 insertions(+)
 create mode 100644 testcases/kernel/syscalls/cachestat/cachestat05.c

diff --git a/runtest/syscalls b/runtest/syscalls
index ff3de1b15..3bd2c98d8 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -66,6 +66,7 @@ cachestat01 cachestat01
 cachestat02 cachestat02
 cachestat03 cachestat03
 cachestat04 cachestat04
+cachestat05 cachestat05
 
 chdir01 chdir01
 chdir02 chdir02
diff --git a/testcases/kernel/syscalls/cachestat/.gitignore b/testcases/kernel/syscalls/cachestat/.gitignore
index a3611a533..76e0d90a8 100644
--- a/testcases/kernel/syscalls/cachestat/.gitignore
+++ b/testcases/kernel/syscalls/cachestat/.gitignore
@@ -2,3 +2,4 @@ cachestat01
 cachestat02
 cachestat03
 cachestat04
+/cachestat05
diff --git a/testcases/kernel/syscalls/cachestat/cachestat05.c b/testcases/kernel/syscalls/cachestat/cachestat05.c
new file mode 100644
index 000000000..c3b5ffcc0
--- /dev/null
+++ b/testcases/kernel/syscalls/cachestat/cachestat05.c
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Xuewen Wang <wangxuewen@kylinos.cn>
+ */
+
+/*\
+ * Verify that :manpage:`cachestat(2)` only reveals page cache statistics for
+ * files the calling process has write access to, owns, or has open for
+ * writing.
+ *
+ * This is a test for the permission check implemented in
+ * 5f537664e705 ("cachestat: fix page cache statistics permission checking")
+ *
+ * Before the fix, :manpage:`cachestat(2)` could be used to query page cache
+ * statistics of arbitrary readable files, which leaks information about the
+ * file access patterns of other users. Since v6.14 the call fails with EPERM
+ * unless one of these applies:
+ *
+ * - the file descriptor was open for writing
+ * - the caller owns the file
+ * - the caller has write permission to the file
+ *
+ * The descriptor for the write-access case is opened while the child is
+ * still root, so that it refers to a file the unprivileged caller could
+ * not open for writing.
+ *
+ * [Algorithm]
+ *
+ * - fork a child which opens a test file with the open flags of the test
+ *   case, then drops all privileges to an unassigned uid and gid
+ * - the child calls :manpage:`cachestat(2)` on the file descriptor
+ * - the call either succeeds, or fails with EPERM if the descriptor is not
+ *   open for writing and the child neither owns the file nor has write
+ *   permission to it
+ */
+
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include "tst_test.h"
+#include "tst_uid.h"
+#include "cachestat.h"
+
+#define FILE_RDWR   "cachestat05_rw"
+#define FILE_OWNED  "cachestat05_owned"
+#define FILE_RDONLY "cachestat05_ro"
+
+static uid_t uid;
+static gid_t gid;
+static struct cachestat *cs;
+static struct cachestat_range *cs_range;
+
+static struct tcase {
+	const char *file;
+	int open_flags;
+	int exp_errno;
+	const char *desc;
+} tcases[] = {
+	{FILE_RDONLY, O_RDWR, 0, "descriptor open for writing"},
+	{FILE_OWNED, O_RDONLY, 0, "file owned by the caller"},
+	{FILE_RDWR, O_RDONLY, 0, "file writable by the caller"},
+	{FILE_RDONLY, O_RDONLY, EPERM, "file read-only for the caller"},
+};
+
+static void verify_cachestat(unsigned int n)
+{
+	struct tcase *tc = &tcases[n];
+	int fd;
+
+	if (SAFE_FORK())
+		return;
+
+	fd = SAFE_OPEN(tc->file, tc->open_flags);
+
+	SAFE_SETGROUPS(0, NULL);
+	SAFE_SETGID(gid);
+	SAFE_SETUID(uid);
+
+	if (tc->exp_errno) {
+		TST_EXP_FAIL(cachestat(fd, cs_range, cs, 0), tc->exp_errno,
+			     "%s", tc->desc);
+	} else {
+		TST_EXP_PASS(cachestat(fd, cs_range, cs, 0), "%s", tc->desc);
+		print_cachestat(cs);
+	}
+
+	SAFE_CLOSE(fd);
+}
+
+static void setup(void)
+{
+	int fd;
+
+	uid = tst_get_free_uid(0);
+	gid = tst_get_free_gid(0);
+
+	umask(0);
+
+	/* len == 0 queries the whole file */
+	cs_range->off = 0;
+	cs_range->len = 0;
+
+	if (cachestat(-1, cs_range, cs, 0) != -1)
+		tst_brk(TBROK, "cachestat(-1) unexpectedly succeeded");
+
+	fd = SAFE_OPEN(FILE_RDWR, O_CREAT | O_RDWR, 0666);
+	SAFE_CLOSE(fd);
+
+	fd = SAFE_OPEN(FILE_OWNED, O_CREAT | O_RDWR, 0400);
+	SAFE_CLOSE(fd);
+	SAFE_CHOWN(FILE_OWNED, uid, -1);
+
+	fd = SAFE_OPEN(FILE_RDONLY, O_CREAT | O_RDONLY, 0444);
+	SAFE_CLOSE(fd);
+}
+
+static struct tst_test test = {
+	.setup = setup,
+	.test = verify_cachestat,
+	.tcnt = ARRAY_SIZE(tcases),
+	.needs_root = 1,
+	.forks_child = 1,
+	.needs_tmpdir = 1,
+	.bufs = (struct tst_buffers []) {
+		{&cs, .size = sizeof(struct cachestat)},
+		{&cs_range, .size = sizeof(struct cachestat_range)},
+		{}
+	},
+	.tags = (const struct tst_tag[]) {
+		{"linux-git", "5f537664e705"},
+		{}
+	},
+};
-- 
2.25.1


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [LTP] syscalls/cachestat05: Add test for permission checks
  2026-11-06  3:29 [LTP] [PATCH v2] syscalls/cachestat05: Add test for permission checks Xuewen Wang
@ 2026-11-06 11:34 ` linuxtestproject.agent
  0 siblings, 0 replies; 3+ messages in thread
From: linuxtestproject.agent @ 2026-11-06 11:34 UTC (permalink / raw)
  To: Xuewen Wang; +Cc: ltp

Hi Xuewen,

On Fri Nov 6 11:29:29 2026 +0800, Xuewen Wang <wangxuewen@kylinos.cn> wrote:
> syscalls/cachestat05: Add test for permission checks

Verdict - Reviewed

---
Note:

The agent can sometimes produce false positives although often its
findings are genuine. If you find issues with the review, please
comment this email or ignore the suggestions.

Regards,
LTP AI Reviewer

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-11-06 11:35 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-06  3:29 [LTP] [PATCH v2] syscalls/cachestat05: Add test for permission checks Xuewen Wang
2026-11-06 11:34 ` [LTP] " linuxtestproject.agent
  -- strict thread matches above, loose matches on Subject: below --
2026-11-05 10:46 [LTP] [PATCH] " Xuewen Wang
2026-11-05 15:58 ` [LTP] " linuxtestproject.agent

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.