[LTP] [PATCH v5 4/4] syscalls: lchown03: Merge into lchown02

Ricardo B. Marlière rbm@suse.com
Tue Sep 9 16:48:52 CEST 2025


On Tue Sep 2, 2025 at 11:27 AM -03, Cyril Hrubis wrote:
> Hi!
>>  static void run(unsigned int i)
>> @@ -70,8 +77,14 @@ static void setup(void)
>>  {
>>  	bad_addr = tst_get_bad_addr(NULL);
>>  
>> -	memset(longpath, 'a', LONGPATHSIZE - 1);
>> -	longpath[LONGPATHSIZE-1] = 0;
>> +	memset(maxpath, 'a', MAXPATH - 1);
>> +	maxpath[MAXPATH-1] = 0;
>> +
>> +	snprintf(longpath, sizeof(longpath), ".");
>> +	SAFE_MKDIR("longpath", 0755);
>> +	SAFE_SYMLINK("../longpath", "longpath/longpath");
>> +	for (int i = 0; i < 43; i++)
>> +		strcat(longpath, "/longpath");
>
> There is much more easier way how to get ELOOP, just create two symlinks
> pointing to each other.
>
> 	SAFE_SYMLINK("infinte_loop_a", "infinite_loop_b");
> 	SAFE_SYMLINK("infinte_loop_b", "infinite_loop_a");
>
> Trying to resolve either of these ends up in ELOOP.

I don't think that will work for lchown, from it's man page:

       •  lchown() is like chown(), but does not dereference symbolic links.

I guess the original code works because the final component is not a link.

Here's the diff (fails with EPERM):


diff --git a/testcases/kernel/syscalls/lchown/lchown02.c b/testcases/kernel/syscalls/lchown/lchown02.c
index db068865acdc..db8b29c61d07 100644
--- a/testcases/kernel/syscalls/lchown/lchown02.c
+++ b/testcases/kernel/syscalls/lchown/lchown02.c
@@ -33,6 +33,7 @@
 #define SFILE2 "testdir_1/sfile_2"
 #define TFILE3 "t_file"
 #define SFILE3 "t_file/sfile"
+#define EFILE1 "eloop"
 #define TEST_EROFS "mntpoint"
 #define MAXPATH (PATH_MAX+2)
 
@@ -42,7 +43,7 @@ static char *bad_addr;
 static char *maxpath;
 static char *sfile3;
 static char *empty;
-static char *longpath;
+static char *eloop;
 static char *erofs;
 static struct passwd *ltpuser;
 
@@ -57,20 +58,15 @@ static struct test_case_t {
 	{ &maxpath, "Pathname too long", ENAMETOOLONG },
 	{ &sfile3, "Path contains regular file", ENOTDIR },
 	{ &empty, "Pathname is empty", ENOENT },
-	{ &longpath, "Too many symlinks", ELOOP },
+	{ &eloop, "Too many symlinks", ELOOP },
 	{ &erofs, "Read-only filesystem", EROFS },
 };
 
 static void run(unsigned int i)
 {
-	uid_t user_id;
-	gid_t group_id;
 	struct test_case_t *tc = &test_cases[i];
 
-	UID16_CHECK((user_id = geteuid()), "lchown");
-	GID16_CHECK((group_id = getegid()), "lchown");
-
-	TST_EXP_FAIL(lchown(*tc->pathname, user_id, group_id), tc->exp_errno, "%s", tc->desc);
+	TST_EXP_FAIL(lchown(*tc->pathname, ltpuser->pw_uid, ltpuser->pw_gid), tc->exp_errno, "%s", tc->desc);
 }
 
 static void setup(void)
@@ -80,15 +76,21 @@ static void setup(void)
 	memset(maxpath, 'a', MAXPATH - 1);
 	maxpath[MAXPATH-1] = 0;
 
-	snprintf(longpath, sizeof(longpath), ".");
-	SAFE_MKDIR("longpath", 0755);
-	SAFE_SYMLINK("../longpath", "longpath/longpath");
-	for (int i = 0; i < 43; i++)
-		strcat(longpath, "/longpath");
+	// snprintf(longpath, sizeof(longpath), ".");
+	// SAFE_MKDIR("longpath", 0755);
+	// SAFE_SYMLINK("../longpath", "longpath/longpath");
+	// for (int i = 0; i < 43; i++)
+	// 	strcat(longpath, "/longpath");
+
+	SAFE_SYMLINK(EFILE1, "infinite_loop");
+	SAFE_SYMLINK("infinite_loop", EFILE1);
 
 	ltpuser = SAFE_GETPWNAM(TEST_USER);
 	SAFE_SETGID(ltpuser->pw_uid);
 
+	UID16_CHECK(ltpuser->pw_uid, "lchown");
+	GID16_CHECK(ltpuser->pw_gid, "lchown");
+
 	SAFE_TOUCH(TFILE1, 0666, NULL);
 	SAFE_SETEUID(0);
 	SAFE_SYMLINK(TFILE1, SFILE1);
@@ -115,7 +117,7 @@ static struct tst_test test = {
 		{&sfile1, .str = SFILE1},
 		{&sfile2, .str = SFILE2},
 		{&sfile3, .str = SFILE3},
-		{&longpath, .size = PATH_MAX},
+		{&eloop, .str = EFILE1},
 		{&empty, .str = ""},
 		{ &erofs, .str = TEST_EROFS },
 		{}




More information about the ltp mailing list