Linux Test Project
 help / color / mirror / Atom feed
* [LTP] [PATCH v16 0/2] open16: allow restricted O_CREAT of FIFOs and regular files
@ 2026-10-22  2:28 Wei Gao via ltp
  2026-10-22  2:28 ` [LTP] [PATCH v16 1/2] lib: New library function tst_get_free_uid Wei Gao via ltp
  2026-10-22  2:28 ` [LTP] [PATCH v16 2/2] open16: allow restricted O_CREAT of FIFOs and regular files Wei Gao via ltp
  0 siblings, 2 replies; 9+ messages in thread
From: Wei Gao via ltp @ 2026-10-22  2:28 UTC (permalink / raw)
  To: ltp

v15->v16:
Remove change for tst_get_free_gid_

Wei Gao (2):
  lib: New library function tst_get_free_uid
  open16: allow restricted O_CREAT of FIFOs and regular files

 include/tst_path_defs.h                   |   2 +
 include/tst_uid.h                         |  14 +++
 lib/tst_uid.c                             |  28 +++++
 runtest/syscalls                          |   1 +
 testcases/kernel/syscalls/open/.gitignore |   1 +
 testcases/kernel/syscalls/open/open16.c   | 143 ++++++++++++++++++++++
 6 files changed, 189 insertions(+)
 create mode 100644 testcases/kernel/syscalls/open/open16.c

-- 
2.55.0


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

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

* [LTP] [PATCH v16 1/2] lib: New library function tst_get_free_uid
  2026-10-22  2:28 [LTP] [PATCH v16 0/2] open16: allow restricted O_CREAT of FIFOs and regular files Wei Gao via ltp
@ 2026-10-22  2:28 ` Wei Gao via ltp
  2026-10-22  7:12   ` [LTP] " linuxtestproject.agent
  2026-10-22 15:25   ` [LTP] [PATCH v16 1/2] " Petr Vorel
  2026-10-22  2:28 ` [LTP] [PATCH v16 2/2] open16: allow restricted O_CREAT of FIFOs and regular files Wei Gao via ltp
  1 sibling, 2 replies; 9+ messages in thread
From: Wei Gao via ltp @ 2026-10-22  2:28 UTC (permalink / raw)
  To: ltp

Add tst_get_free_uid() to dynamically find unused UIDs for tests.

Some tests need a completely unassigned, unused UID. This is used by
open16 to verify restricted O_CREAT in sticky directories by running
as a sandboxed user with no file ownership or privileges.

Signed-off-by: Wei Gao <wegao@suse.com>
Reviewed-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
 include/tst_uid.h | 14 ++++++++++++++
 lib/tst_uid.c     | 28 ++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/include/tst_uid.h b/include/tst_uid.h
index 2237ddcbf..03f9dc073 100644
--- a/include/tst_uid.h
+++ b/include/tst_uid.h
@@ -7,6 +7,20 @@
 
 #include <sys/types.h>
 
+uid_t tst_get_free_uid_(const char *file, const int lineno, uid_t skip);
+
+/**
+ * tst_get_free_uid() - Find a UID not assigned to any user.
+ * @skip: UID value to skip (pass 0 to skip none).
+ *
+ * Scans the password database for the first unused UID starting
+ * from 1, skipping @skip. Calls tst_brk(TBROK) if no free UID
+ * is found or a lookup error occurs.
+ *
+ * Return: An unused uid_t value.
+ */
+#define tst_get_free_uid(skip) tst_get_free_uid_(__FILE__, __LINE__, (skip))
+
 /*
  * Find unassigned gid. The skip argument can be used to ignore e.g. the main
  * group of a specific user in case it's not listed in the group file. If you
diff --git a/lib/tst_uid.c b/lib/tst_uid.c
index b0b087362..47c267bc4 100644
--- a/lib/tst_uid.c
+++ b/lib/tst_uid.c
@@ -5,6 +5,7 @@
 
 #include <sys/types.h>
 #include <grp.h>
+#include <pwd.h>
 #include <errno.h>
 
 #define TST_NO_DEFAULT_MAIN
@@ -12,6 +13,33 @@
 #include "tst_uid.h"
 
 #define MAX_GID 32767
+#define MAX_UID 32767
+
+uid_t tst_get_free_uid_(const char *file, const int lineno, uid_t skip)
+{
+	uid_t ret;
+
+	for (ret = 1; ret < MAX_UID; ret++) {
+		if (ret == skip)
+			continue;
+
+		errno = 0;
+		if (getpwuid(ret))
+			continue;
+
+		if (errno == 0 || errno == ENOENT || errno == ESRCH) {
+			tst_res_(file, lineno, TINFO,
+				"Found unused UID %d", (int)ret);
+			return ret;
+		}
+
+		tst_brk_(file, lineno, TBROK | TERRNO, "User ID lookup failed");
+		return (uid_t)-1;
+	}
+
+	tst_brk_(file, lineno, TBROK, "No free user ID found");
+	return (uid_t)-1;
+}
 
 gid_t tst_get_free_gid_(const char *file, const int lineno, gid_t skip)
 {
-- 
2.55.0


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

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

* [LTP] [PATCH v16 2/2] open16: allow restricted O_CREAT of FIFOs and regular files
  2026-10-22  2:28 [LTP] [PATCH v16 0/2] open16: allow restricted O_CREAT of FIFOs and regular files Wei Gao via ltp
  2026-10-22  2:28 ` [LTP] [PATCH v16 1/2] lib: New library function tst_get_free_uid Wei Gao via ltp
@ 2026-10-22  2:28 ` Wei Gao via ltp
  2026-10-22 15:44   ` Petr Vorel
  1 sibling, 1 reply; 9+ messages in thread
From: Wei Gao via ltp @ 2026-10-22  2:28 UTC (permalink / raw)
  To: ltp

Add LTP coverage for kernel commit 30aba6656f61 (Linux 4.19), which
introduced protection against spoofing attacks via O_CREAT of FIFOs
and regular files in world-writable or group-writable sticky
directories.

This commit adds test cases to verify these security restrictions
(values 1 and 2 for protected_fifos and protected_regular) for opening
FIFOs and regular files in world-writable or group-writable sticky
directories when the file is not owned by the opener.

Signed-off-by: Wei Gao <wegao@suse.com>
Reviewed-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
 include/tst_path_defs.h                   |   2 +
 runtest/syscalls                          |   1 +
 testcases/kernel/syscalls/open/.gitignore |   1 +
 testcases/kernel/syscalls/open/open16.c   | 143 ++++++++++++++++++++++
 4 files changed, 147 insertions(+)
 create mode 100644 testcases/kernel/syscalls/open/open16.c

diff --git a/include/tst_path_defs.h b/include/tst_path_defs.h
index 1a60028d3..2995150be 100644
--- a/include/tst_path_defs.h
+++ b/include/tst_path_defs.h
@@ -47,6 +47,8 @@
 #define PATH_FS_PIPE_MAX_PAGES			"/proc/sys/fs/pipe-max-pages"
 #define PATH_FS_MAX_USER_GROUPS			"/proc/sys/fs/fanotify/max_user_groups"
 #define PATH_FS_MAX_USER_MARKS			"/proc/sys/fs/fanotify/max_user_marks"
+#define PATH_FS_PROTECTED_REGULAR		"/proc/sys/fs/protected_regular"
+#define PATH_FS_PROTECTED_FIFOS			"/proc/sys/fs/protected_fifos"
 
 /* VM */
 #define PATH_VM_DROP_CACHES			"/proc/sys/vm/drop_caches"
diff --git a/runtest/syscalls b/runtest/syscalls
index a021c79da..4fd62efa8 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -1008,6 +1008,7 @@ open12 open12
 open13 open13
 open14 open14
 open15 open15
+open16 open16
 
 openat01 openat01
 openat02 openat02
diff --git a/testcases/kernel/syscalls/open/.gitignore b/testcases/kernel/syscalls/open/.gitignore
index af5997572..d2cacc02e 100644
--- a/testcases/kernel/syscalls/open/.gitignore
+++ b/testcases/kernel/syscalls/open/.gitignore
@@ -13,3 +13,4 @@
 /open13
 /open14
 /open15
+/open16
diff --git a/testcases/kernel/syscalls/open/open16.c b/testcases/kernel/syscalls/open/open16.c
new file mode 100644
index 000000000..a8d33870f
--- /dev/null
+++ b/testcases/kernel/syscalls/open/open16.c
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Wei Gao <wegao@suse.com>
+ */
+
+/*\
+ * Verify restricted opening (:manpage:`open(2)` and :manpage:`openat(2)`) of
+ * FIFOs and regular files in sticky directories. This protection is controlled via
+ * ``/proc/sys/fs/protected_fifos`` and ``/proc/sys/fs/protected_regular`` sysctl values:
+ *
+ * - When set to "0", writing/opening is unrestricted.
+ * - When set to "1", O_CREAT open on FIFOs/regular files we don't own in world-writable
+ *   sticky directories is disallowed, unless they are owned by the owner of the directory.
+ * - When set to "2", the same restriction also applies to group-writable sticky directories.
+ *
+ * This test requires root to modify ``/proc/sys/fs/protected_*`` sysctls and
+ * to manage file ownership and permissions in sticky directories.
+ */
+
+#include <pwd.h>
+#include <stdlib.h>
+#include "tst_test.h"
+#include "tst_safe_file_at.h"
+#include "tst_uid.h"
+
+#define DIR "ltp_tmp_check1"
+#define TEST_FILE "test_file_1"
+#define TEST_FIFO "test_fifo_1"
+#define TEST_FIFO_PATH DIR "/" TEST_FIFO
+
+static int dir_fd = -1;
+static uid_t uid1, uid2;
+static gid_t gid1;
+
+static struct tcase {
+	int exp_errno;
+	uid_t owner_uid;
+	int use_nobody_gid;
+	mode_t dir_mode;
+} tcases[] = {
+	{
+		.dir_mode = 0777 | S_ISVTX,
+	},
+	{
+		.exp_errno = EACCES,
+		.dir_mode = 0777 | S_ISVTX,
+	},
+	{
+		.exp_errno = EACCES,
+		.owner_uid = -1,
+		.use_nobody_gid = 1,
+		.dir_mode = 0030 | S_ISVTX,
+	},
+};
+
+static void verify_open(unsigned int n)
+{
+	struct tcase *tc = &tcases[n];
+
+	SAFE_FILE_PRINTF(PATH_FS_PROTECTED_REGULAR, "%u", n);
+	SAFE_FILE_PRINTF(PATH_FS_PROTECTED_FIFOS, "%u", n);
+
+	if (tc->owner_uid != (uid_t)-1 || tc->use_nobody_gid) {
+		gid_t gid = tc->use_nobody_gid ? gid1 : 0;
+
+		SAFE_CHOWN(DIR, tc->owner_uid, gid);
+	}
+
+	if (tc->dir_mode)
+		SAFE_CHMOD(DIR, tc->dir_mode);
+
+	if (SAFE_FORK())
+		return;
+
+	SAFE_SETGID(gid1);
+	SAFE_SETUID(uid2);
+
+	TST_EXP_FD_OR_FAIL(openat(dir_fd, TEST_FILE, O_RDWR | O_CREAT, 0777),
+			   tc->exp_errno, "openat %s (sysctl_val=%u)", TEST_FILE, n);
+	if (TST_RET != -1)
+		SAFE_CLOSE(TST_RET);
+
+	TST_EXP_FD_OR_FAIL(open(TEST_FIFO_PATH, O_RDWR | O_CREAT, 0777),
+			   tc->exp_errno, "open %s (sysctl_val=%u)", TEST_FIFO, n);
+	if (TST_RET != -1)
+		SAFE_CLOSE(TST_RET);
+
+	exit(0);
+}
+
+static void setup(void)
+{
+	struct passwd *pw;
+
+	pw = SAFE_GETPWNAM("nobody");
+	uid1 = pw->pw_uid;
+	gid1 = pw->pw_gid;
+	uid2 = tst_get_free_uid(uid1);
+
+	umask(0);
+	SAFE_MKDIR(DIR, 0777 | S_ISVTX);
+	dir_fd = SAFE_OPEN(DIR, O_DIRECTORY);
+
+	int fd = SAFE_OPENAT(dir_fd, TEST_FILE, O_CREAT | O_RDWR, 0777);
+
+	SAFE_CLOSE(fd);
+	SAFE_MKFIFO(TEST_FIFO_PATH, 0777);
+	SAFE_CHOWN(TEST_FIFO_PATH, uid1, gid1);
+	SAFE_CHOWN(DIR "/" TEST_FILE, uid1, gid1);
+}
+
+static void cleanup(void)
+{
+	if (dir_fd != -1)
+		SAFE_CLOSE(dir_fd);
+}
+
+static struct tst_test test = {
+	.setup = setup,
+	.cleanup = cleanup,
+	.needs_root = 1,
+	.tcnt = ARRAY_SIZE(tcases),
+	.test = verify_open,
+	.needs_tmpdir = 1,
+	.forks_child = 1,
+	.save_restore = (const struct tst_path_val[]) {
+		{PATH_FS_PROTECTED_REGULAR, NULL, TST_SR_TCONF},
+		{PATH_FS_PROTECTED_FIFOS, NULL, TST_SR_TCONF},
+		{}
+	},
+	.tags = (const struct tst_tag[]) {
+		{"linux-git", "30aba6656f61"},
+		{"CVE", "2000-1134"},
+		{"CVE", "2007-3852"},
+		{"CVE", "2008-0525"},
+		{"CVE", "2009-0416"},
+		{"CVE", "2011-4834"},
+		{"CVE", "2015-1838"},
+		{"CVE", "2015-7442"},
+		{"CVE", "2016-7489"},
+		{}
+	}
+};
-- 
2.55.0


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

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

* Re: [LTP] lib: New library function tst_get_free_uid
  2026-10-22  2:28 ` [LTP] [PATCH v16 1/2] lib: New library function tst_get_free_uid Wei Gao via ltp
@ 2026-10-22  7:12   ` linuxtestproject.agent
  2026-10-22 15:25   ` [LTP] [PATCH v16 1/2] " Petr Vorel
  1 sibling, 0 replies; 9+ messages in thread
From: linuxtestproject.agent @ 2026-10-22  7:12 UTC (permalink / raw)
  To: Wei Gao; +Cc: ltp

Hi Wei,

On 22 Oct 2026, Wei Gao wrote:
> lib: New library function tst_get_free_uid

Verdict - Reviewed

Runtime validation was not performed because access to the required
sysctls was denied.

---
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] 9+ messages in thread

* Re: [LTP] [PATCH v16 1/2] lib: New library function tst_get_free_uid
  2026-10-22  2:28 ` [LTP] [PATCH v16 1/2] lib: New library function tst_get_free_uid Wei Gao via ltp
  2026-10-22  7:12   ` [LTP] " linuxtestproject.agent
@ 2026-10-22 15:25   ` Petr Vorel
  2026-10-22 15:32     ` Petr Vorel
  1 sibling, 1 reply; 9+ messages in thread
From: Petr Vorel @ 2026-10-22 15:25 UTC (permalink / raw)
  To: Wei Gao; +Cc: Martin Doucha, ltp

Hi Wei,

> +uid_t tst_get_free_uid_(const char *file, const int lineno, uid_t skip);
> +
> +/**
> + * tst_get_free_uid() - Find a UID not assigned to any user.
> + * @skip: UID value to skip (pass 0 to skip none).
> + *
> + * Scans the password database for the first unused UID starting
> + * from 1, skipping @skip. Calls tst_brk(TBROK) if no free UID
> + * is found or a lookup error occurs.
> + *
> + * Return: An unused uid_t value.
> + */
> +#define tst_get_free_uid(skip) tst_get_free_uid_(__FILE__, __LINE__, (skip))
> +
>  /*
>   * Find unassigned gid. The skip argument can be used to ignore e.g. the main
>   * group of a specific user in case it's not listed in the group file. If you
> diff --git a/lib/tst_uid.c b/lib/tst_uid.c
> index b0b087362..47c267bc4 100644
> --- a/lib/tst_uid.c
> +++ b/lib/tst_uid.c
> @@ -5,6 +5,7 @@

>  #include <sys/types.h>
>  #include <grp.h>
> +#include <pwd.h>
>  #include <errno.h>

>  #define TST_NO_DEFAULT_MAIN
> @@ -12,6 +13,33 @@
>  #include "tst_uid.h"

>  #define MAX_GID 32767
> +#define MAX_UID 32767
> +
> +uid_t tst_get_free_uid_(const char *file, const int lineno, uid_t skip)
> +{
> +	uid_t ret;
> +
> +	for (ret = 1; ret < MAX_UID; ret++) {
> +		if (ret == skip)
> +			continue;
> +
> +		errno = 0;
> +		if (getpwuid(ret))
> +			continue;


If you don't mind I'd prefer to use the same approach which is on
tst_get_free_gid_(), e.g. set errno first:

	errno = 0;

	for (ret = 1; ret < MAX_UID; ret++) {
		if (ret == skip || getpwuid(ret))
			continue;

Reviewed-by: Petr Vorel <pvorel@suse.cz>

Other than that LGTM.

Cc Martin in case he wants to add his ack before I merge.

Kind regards,
Petr

> +
> +		if (errno == 0 || errno == ENOENT || errno == ESRCH) {
> +			tst_res_(file, lineno, TINFO,
> +				"Found unused UID %d", (int)ret);
> +			return ret;
> +		}
> +
> +		tst_brk_(file, lineno, TBROK | TERRNO, "User ID lookup failed");
> +		return (uid_t)-1;
> +	}
> +
> +	tst_brk_(file, lineno, TBROK, "No free user ID found");
> +	return (uid_t)-1;
> +}

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

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

* Re: [LTP] [PATCH v16 1/2] lib: New library function tst_get_free_uid
  2026-10-22 15:25   ` [LTP] [PATCH v16 1/2] " Petr Vorel
@ 2026-10-22 15:32     ` Petr Vorel
  2026-10-23  2:44       ` Wei Gao via ltp
  0 siblings, 1 reply; 9+ messages in thread
From: Petr Vorel @ 2026-10-22 15:32 UTC (permalink / raw)
  To: Wei Gao, ltp, Andrea Cervesato, Martin Doucha

> Hi Wei,

> > +uid_t tst_get_free_uid_(const char *file, const int lineno, uid_t skip);
> > +
> > +/**
> > + * tst_get_free_uid() - Find a UID not assigned to any user.
> > + * @skip: UID value to skip (pass 0 to skip none).
> > + *
> > + * Scans the password database for the first unused UID starting
> > + * from 1, skipping @skip. Calls tst_brk(TBROK) if no free UID
> > + * is found or a lookup error occurs.
> > + *
> > + * Return: An unused uid_t value.
> > + */
> > +#define tst_get_free_uid(skip) tst_get_free_uid_(__FILE__, __LINE__, (skip))
> > +
> >  /*
> >   * Find unassigned gid. The skip argument can be used to ignore e.g. the main
> >   * group of a specific user in case it's not listed in the group file. If you
> > diff --git a/lib/tst_uid.c b/lib/tst_uid.c
> > index b0b087362..47c267bc4 100644
> > --- a/lib/tst_uid.c
> > +++ b/lib/tst_uid.c
> > @@ -5,6 +5,7 @@

> >  #include <sys/types.h>
> >  #include <grp.h>
> > +#include <pwd.h>
> >  #include <errno.h>

> >  #define TST_NO_DEFAULT_MAIN
> > @@ -12,6 +13,33 @@
> >  #include "tst_uid.h"

> >  #define MAX_GID 32767
> > +#define MAX_UID 32767
> > +
> > +uid_t tst_get_free_uid_(const char *file, const int lineno, uid_t skip)
> > +{
> > +	uid_t ret;
> > +
> > +	for (ret = 1; ret < MAX_UID; ret++) {
> > +		if (ret == skip)
> > +			continue;
> > +
> > +		errno = 0;
> > +		if (getpwuid(ret))
> > +			continue;


> If you don't mind I'd prefer to use the same approach which is on
> tst_get_free_gid_(), e.g. set errno first:

> 	errno = 0;

> 	for (ret = 1; ret < MAX_UID; ret++) {
> 		if (ret == skip || getpwuid(ret))
> 			continue;

> Reviewed-by: Petr Vorel <pvorel@suse.cz>

> Other than that LGTM.

> Cc Martin in case he wants to add his ack before I merge.

> Kind regards,
> Petr

> > +
> > +		if (errno == 0 || errno == ENOENT || errno == ESRCH) {
> > +			tst_res_(file, lineno, TINFO,
Actually also here TERRNO probably makes sense.

I suggest to merge with following diff:

+++ lib/tst_uid.c
@@ -19,16 +19,14 @@ uid_t tst_get_free_uid_(const char *file, const int lineno, uid_t skip)
 {
 	uid_t ret;
 
-	for (ret = 1; ret < MAX_UID; ret++) {
-		if (ret == skip)
-			continue;
+	errno = 0;
 
-		errno = 0;
-		if (getpwuid(ret))
+	for (ret = 1; ret < MAX_UID; ret++) {
+		if (ret == skip || getpwuid(ret))
 			continue;
 
 		if (errno == 0 || errno == ENOENT || errno == ESRCH) {
-			tst_res_(file, lineno, TINFO,
+			tst_res_(file, lineno, TINFO | TERRNO,
 				"Found unused UID %d", (int)ret);
 			return ret;
 		}

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

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

* Re: [LTP] [PATCH v16 2/2] open16: allow restricted O_CREAT of FIFOs and regular files
  2026-10-22  2:28 ` [LTP] [PATCH v16 2/2] open16: allow restricted O_CREAT of FIFOs and regular files Wei Gao via ltp
@ 2026-10-22 15:44   ` Petr Vorel
  2026-10-23  2:46     ` Wei Gao via ltp
  0 siblings, 1 reply; 9+ messages in thread
From: Petr Vorel @ 2026-10-22 15:44 UTC (permalink / raw)
  To: Wei Gao; +Cc: ltp

Hi Wei,

...
> +static void verify_open(unsigned int n)
> +{
> +	struct tcase *tc = &tcases[n];
> +
> +	SAFE_FILE_PRINTF(PATH_FS_PROTECTED_REGULAR, "%u", n);
> +	SAFE_FILE_PRINTF(PATH_FS_PROTECTED_FIFOS, "%u", n);
> +
> +	if (tc->owner_uid != (uid_t)-1 || tc->use_nobody_gid) {
> +		gid_t gid = tc->use_nobody_gid ? gid1 : 0;
> +
> +		SAFE_CHOWN(DIR, tc->owner_uid, gid);
> +	}
> +
> +	if (tc->dir_mode)
> +		SAFE_CHMOD(DIR, tc->dir_mode);
> +
> +	if (SAFE_FORK())
> +		return;
> +
> +	SAFE_SETGID(gid1);
> +	SAFE_SETUID(uid2);
> +
> +	TST_EXP_FD_OR_FAIL(openat(dir_fd, TEST_FILE, O_RDWR | O_CREAT, 0777),
> +			   tc->exp_errno, "openat %s (sysctl_val=%u)", TEST_FILE, n);
> +	if (TST_RET != -1)
> +		SAFE_CLOSE(TST_RET);
> +
> +	TST_EXP_FD_OR_FAIL(open(TEST_FIFO_PATH, O_RDWR | O_CREAT, 0777),
> +			   tc->exp_errno, "open %s (sysctl_val=%u)", TEST_FIFO, n);
> +	if (TST_RET != -1)
> +		SAFE_CLOSE(TST_RET);
> +
> +	exit(0);

Do we need this explicit exit?

The rest LGTM.
Reviewed-by: Petr Vorel <pvorel@suse.cz>

Kind regards,
Petr

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

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

* Re: [LTP] [PATCH v16 1/2] lib: New library function tst_get_free_uid
  2026-10-22 15:32     ` Petr Vorel
@ 2026-10-23  2:44       ` Wei Gao via ltp
  0 siblings, 0 replies; 9+ messages in thread
From: Wei Gao via ltp @ 2026-10-23  2:44 UTC (permalink / raw)
  To: Petr Vorel; +Cc: Martin Doucha, ltp

On Thu, Oct 22, 2026 at 05:32:49PM +0200, Petr Vorel wrote:
> > Hi Wei,
> 
> > > +uid_t tst_get_free_uid_(const char *file, const int lineno, uid_t skip);
> > > +
> > > +/**
> > > + * tst_get_free_uid() - Find a UID not assigned to any user.
> > > + * @skip: UID value to skip (pass 0 to skip none).
> > > + *
> > > + * Scans the password database for the first unused UID starting
> > > + * from 1, skipping @skip. Calls tst_brk(TBROK) if no free UID
> > > + * is found or a lookup error occurs.
> > > + *
> > > + * Return: An unused uid_t value.
> > > + */
> > > +#define tst_get_free_uid(skip) tst_get_free_uid_(__FILE__, __LINE__, (skip))
> > > +
> > >  /*
> > >   * Find unassigned gid. The skip argument can be used to ignore e.g. the main
> > >   * group of a specific user in case it's not listed in the group file. If you
> > > diff --git a/lib/tst_uid.c b/lib/tst_uid.c
> > > index b0b087362..47c267bc4 100644
> > > --- a/lib/tst_uid.c
> > > +++ b/lib/tst_uid.c
> > > @@ -5,6 +5,7 @@
> 
> > >  #include <sys/types.h>
> > >  #include <grp.h>
> > > +#include <pwd.h>
> > >  #include <errno.h>
> 
> > >  #define TST_NO_DEFAULT_MAIN
> > > @@ -12,6 +13,33 @@
> > >  #include "tst_uid.h"
> 
> > >  #define MAX_GID 32767
> > > +#define MAX_UID 32767
> > > +
> > > +uid_t tst_get_free_uid_(const char *file, const int lineno, uid_t skip)
> > > +{
> > > +	uid_t ret;
> > > +
> > > +	for (ret = 1; ret < MAX_UID; ret++) {
> > > +		if (ret == skip)
> > > +			continue;
> > > +
> > > +		errno = 0;
> > > +		if (getpwuid(ret))
> > > +			continue;
> 
> 
> > If you don't mind I'd prefer to use the same approach which is on
> > tst_get_free_gid_(), e.g. set errno first:
> 
> > 	errno = 0;
> 
> > 	for (ret = 1; ret < MAX_UID; ret++) {
> > 		if (ret == skip || getpwuid(ret))
> > 			continue;
> 
> > Reviewed-by: Petr Vorel <pvorel@suse.cz>
> 
> > Other than that LGTM.
> 
> > Cc Martin in case he wants to add his ack before I merge.
> 
> > Kind regards,
> > Petr
> 
> > > +
> > > +		if (errno == 0 || errno == ENOENT || errno == ESRCH) {
> > > +			tst_res_(file, lineno, TINFO,
> Actually also here TERRNO probably makes sense.
> 
> I suggest to merge with following diff:
Thanks. That's ok for me, will use your suggest on next patch once Martin give feedback.
> 
> +++ lib/tst_uid.c
> @@ -19,16 +19,14 @@ uid_t tst_get_free_uid_(const char *file, const int lineno, uid_t skip)
>  {
>  	uid_t ret;
>  
> -	for (ret = 1; ret < MAX_UID; ret++) {
> -		if (ret == skip)
> -			continue;
> +	errno = 0;
>  
> -		errno = 0;
> -		if (getpwuid(ret))
> +	for (ret = 1; ret < MAX_UID; ret++) {
> +		if (ret == skip || getpwuid(ret))
>  			continue;
>  
>  		if (errno == 0 || errno == ENOENT || errno == ESRCH) {
> -			tst_res_(file, lineno, TINFO,
> +			tst_res_(file, lineno, TINFO | TERRNO,
>  				"Found unused UID %d", (int)ret);
>  			return ret;
>  		}

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

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

* Re: [LTP] [PATCH v16 2/2] open16: allow restricted O_CREAT of FIFOs and regular files
  2026-10-22 15:44   ` Petr Vorel
@ 2026-10-23  2:46     ` Wei Gao via ltp
  0 siblings, 0 replies; 9+ messages in thread
From: Wei Gao via ltp @ 2026-10-23  2:46 UTC (permalink / raw)
  To: Petr Vorel; +Cc: ltp

On Thu, Oct 22, 2026 at 05:44:36PM +0200, Petr Vorel wrote:
> Hi Wei,
> 
> ...
> > +static void verify_open(unsigned int n)
> > +{
> > +	struct tcase *tc = &tcases[n];
> > +
> > +	SAFE_FILE_PRINTF(PATH_FS_PROTECTED_REGULAR, "%u", n);
> > +	SAFE_FILE_PRINTF(PATH_FS_PROTECTED_FIFOS, "%u", n);
> > +
> > +	if (tc->owner_uid != (uid_t)-1 || tc->use_nobody_gid) {
> > +		gid_t gid = tc->use_nobody_gid ? gid1 : 0;
> > +
> > +		SAFE_CHOWN(DIR, tc->owner_uid, gid);
> > +	}
> > +
> > +	if (tc->dir_mode)
> > +		SAFE_CHMOD(DIR, tc->dir_mode);
> > +
> > +	if (SAFE_FORK())
> > +		return;
> > +
> > +	SAFE_SETGID(gid1);
> > +	SAFE_SETUID(uid2);
> > +
> > +	TST_EXP_FD_OR_FAIL(openat(dir_fd, TEST_FILE, O_RDWR | O_CREAT, 0777),
> > +			   tc->exp_errno, "openat %s (sysctl_val=%u)", TEST_FILE, n);
> > +	if (TST_RET != -1)
> > +		SAFE_CLOSE(TST_RET);
> > +
> > +	TST_EXP_FD_OR_FAIL(open(TEST_FIFO_PATH, O_RDWR | O_CREAT, 0777),
> > +			   tc->exp_errno, "open %s (sysctl_val=%u)", TEST_FIFO, n);
> > +	if (TST_RET != -1)
> > +		SAFE_CLOSE(TST_RET);
> > +
> > +	exit(0);
> 
> Do we need this explicit exit?
Yes i think exit(0) is necessary because only the child process reaches this point.
> 
> The rest LGTM.
> Reviewed-by: Petr Vorel <pvorel@suse.cz>
> 
> Kind regards,
> Petr

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

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

end of thread, other threads:[~2026-10-23  2:47 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-22  2:28 [LTP] [PATCH v16 0/2] open16: allow restricted O_CREAT of FIFOs and regular files Wei Gao via ltp
2026-10-22  2:28 ` [LTP] [PATCH v16 1/2] lib: New library function tst_get_free_uid Wei Gao via ltp
2026-10-22  7:12   ` [LTP] " linuxtestproject.agent
2026-10-22 15:25   ` [LTP] [PATCH v16 1/2] " Petr Vorel
2026-10-22 15:32     ` Petr Vorel
2026-10-23  2:44       ` Wei Gao via ltp
2026-10-22  2:28 ` [LTP] [PATCH v16 2/2] open16: allow restricted O_CREAT of FIFOs and regular files Wei Gao via ltp
2026-10-22 15:44   ` Petr Vorel
2026-10-23  2:46     ` Wei Gao via ltp

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox