[LTP] [PATCH v12 2/3] lib: New library function tst_get_free_uid
Wei Gao via ltp <[email protected]> Wed, 22 Jul 2026 04:47:28 +0000
| Newsgroups | it.linux.lists.ltp |
|---|---|
| Message-ID | <[email protected]> |
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 <[email protected]> --- include/tst_uid.h | 29 +++++++++++++++++++++++++---- lib/tst_uid.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/include/tst_uid.h b/include/tst_uid.h index 2237ddcbf..c73450956 100644 --- a/include/tst_uid.h +++ b/include/tst_uid.h @@ -7,12 +7,33 @@ #include <sys/types.h> -/* - * 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 - * do not need to skip any specific gid, simply set it to 0. +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)) + gid_t tst_get_free_gid_(const char *file, const int lineno, gid_t skip); + +/** + * tst_get_free_gid() - Find a GID not assigned to any group. + * @skip: GID value to skip (pass 0 to skip none). + * + * Scans the group database for the first unused GID starting from 1, + * skipping @skip. 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. + * Calls tst_brk(TBROK) if no free GID is found or a lookup error occurs. + * + * Return: An unused gid_t value. + */ #define tst_get_free_gid(skip) tst_get_free_gid_(__FILE__, __LINE__, (skip)) /* 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.54.0 -- Mailing list info: https://lists.linux.it/listinfo/ltp