The branch main has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=7fe39bec801a08f541d0111219fe8701a6a20cf1
commit 7fe39bec801a08f541d0111219fe8701a6a20cf1 Author: Dag-Erling Smørgrav <d...@freebsd.org> AuthorDate: 2025-06-23 08:44:12 +0000 Commit: Dag-Erling Smørgrav <d...@freebsd.org> CommitDate: 2025-06-23 08:44:31 +0000 glob: Improve callback tests. Most importantly, they need to run without privileges, since root is allowed to read a directory regardless of its permission bits. PR: 287694 Fixes: 4d7c31bca252 Sponsored by: Klara, Inc. Reviewed by: bnovkov Differential Revision: https://reviews.freebsd.org/D50965 --- lib/libc/tests/gen/glob2_test.c | 47 +++++++++++++++++++++----------- lib/libc/tests/gen/glob_blocks_test.c | 51 ++++++++++++++++++++++------------- 2 files changed, 63 insertions(+), 35 deletions(-) diff --git a/lib/libc/tests/gen/glob2_test.c b/lib/libc/tests/gen/glob2_test.c index 45d17b063593..ff1b36b830b8 100644 --- a/lib/libc/tests/gen/glob2_test.c +++ b/lib/libc/tests/gen/glob2_test.c @@ -30,6 +30,7 @@ #include <errno.h> #include <fcntl.h> #include <glob.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -38,8 +39,6 @@ #include <atf-c.h> -static int glob_callback_invoked; - /* * Derived from Russ Cox' pathological case test program used for the * https://research.swtch.com/glob article. @@ -129,34 +128,50 @@ ATF_TC_BODY(glob_period, tc) "glob(3) should match files starting with a period when using '.*'"); } +static bool glob_callback_invoked; + static int errfunc(const char *path, int err) { - ATF_REQUIRE_STREQ(path, "test/"); - ATF_REQUIRE(err == EACCES); - glob_callback_invoked = 1; + ATF_CHECK_STREQ(path, "test/"); + ATF_CHECK(err == EACCES); + glob_callback_invoked = true; /* Suppress EACCES errors. */ return (0); } -ATF_TC_WITHOUT_HEAD(glob_callback_test); -ATF_TC_BODY(glob_callback_test, tc) +ATF_TC(glob_callback); +ATF_TC_HEAD(glob_callback, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test ability of callback function to suppress errors"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} +ATF_TC_BODY(glob_callback, tc) { - int rv; glob_t g; + int rv; - glob_callback_invoked = 0; - ATF_REQUIRE_EQ(0, mkdir("test", 0007)); + ATF_REQUIRE_EQ(0, mkdir("test", 0755)); + ATF_REQUIRE_EQ(0, symlink("foo", "test/foo")); + ATF_REQUIRE_EQ(0, chmod("test", 0)); + + glob_callback_invoked = false; rv = glob("test/*", 0, errfunc, &g); - ATF_REQUIRE_MSG(glob_callback_invoked == 1, + ATF_CHECK_MSG(glob_callback_invoked, "glob(3) failed to invoke callback function"); - ATF_REQUIRE_MSG(rv == GLOB_NOMATCH, - "error callback function failed to suppress EACCES"); + ATF_CHECK_EQ_MSG(GLOB_NOMATCH, rv, + "callback function failed to suppress EACCES"); + globfree(&g); /* GLOB_ERR should ignore the suppressed error. */ + glob_callback_invoked = false; rv = glob("test/*", GLOB_ERR, errfunc, &g); - ATF_REQUIRE_MSG(rv == GLOB_ABORTED, - "GLOB_ERR didn't override error callback function"); + ATF_CHECK_MSG(glob_callback_invoked, + "glob(3) failed to invoke callback function"); + ATF_CHECK_EQ_MSG(GLOB_ABORTED, rv, + "GLOB_ERR didn't override callback function"); + globfree(&g); } ATF_TP_ADD_TCS(tp) @@ -164,6 +179,6 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, glob_pathological_test); ATF_TP_ADD_TC(tp, glob_period); - ATF_TP_ADD_TC(tp, glob_callback_test); + ATF_TP_ADD_TC(tp, glob_callback); return (atf_no_error()); } diff --git a/lib/libc/tests/gen/glob_blocks_test.c b/lib/libc/tests/gen/glob_blocks_test.c index a20aad17ce31..629b90bee762 100644 --- a/lib/libc/tests/gen/glob_blocks_test.c +++ b/lib/libc/tests/gen/glob_blocks_test.c @@ -8,42 +8,55 @@ #include <errno.h> #include <glob.h> +#include <stdbool.h> #include <atf-c.h> -static int glob_callback_invoked; - -ATF_TC_WITHOUT_HEAD(glob_b_callback_test); -ATF_TC_BODY(glob_b_callback_test, tc) +ATF_TC(glob_b_callback); +ATF_TC_HEAD(glob_b_callback, tc) { - int rv; - glob_t g; - - glob_callback_invoked = 0; - ATF_REQUIRE_EQ(0, mkdir("test", 0007)); - int (^errblk)(const char *, int) = + atf_tc_set_md_var(tc, "descr", + "Test ability of callback block to suppress errors"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} +ATF_TC_BODY(glob_b_callback, tc) +{ + static bool glob_callback_invoked; + static int (^errblk)(const char *, int) = ^(const char *path, int err) { - ATF_REQUIRE_STREQ(path, "test/"); - ATF_REQUIRE(err == EACCES); - glob_callback_invoked = 1; + ATF_CHECK_STREQ(path, "test/"); + ATF_CHECK(err == EACCES); + glob_callback_invoked = true; /* Suppress EACCES errors. */ return (0); }; + glob_t g; + int rv; + ATF_REQUIRE_EQ(0, mkdir("test", 0755)); + ATF_REQUIRE_EQ(0, symlink("foo", "test/foo")); + ATF_REQUIRE_EQ(0, chmod("test", 0)); + + glob_callback_invoked = false; rv = glob_b("test/*", 0, errblk, &g); - ATF_REQUIRE_MSG(glob_callback_invoked == 1, + ATF_CHECK_MSG(glob_callback_invoked, "glob(3) failed to invoke callback block"); - ATF_REQUIRE_MSG(rv == GLOB_NOMATCH, - "error callback function failed to suppress EACCES"); + ATF_CHECK_EQ_MSG(GLOB_NOMATCH, rv, + "callback function failed to suppress EACCES"); + globfree(&g); /* GLOB_ERR should ignore the suppressed error. */ + glob_callback_invoked = false; rv = glob_b("test/*", GLOB_ERR, errblk, &g); - ATF_REQUIRE_MSG(rv == GLOB_ABORTED, - "GLOB_ERR didn't override error callback block"); + ATF_CHECK_MSG(glob_callback_invoked, + "glob(3) failed to invoke callback block"); + ATF_CHECK_EQ_MSG(GLOB_ABORTED, rv, + "GLOB_ERR didn't override callback block"); + globfree(&g); } ATF_TP_ADD_TCS(tp) { - ATF_TP_ADD_TC(tp, glob_b_callback_test); + ATF_TP_ADD_TC(tp, glob_b_callback); return (atf_no_error()); }