From: Sachin Sant <sachinp@linux.ibm.com>
To: ltp@lists.linux.it
Subject: [LTP] [PATCH v8 5/8] fs/acl: Add chmod/chown ACL interaction tests
Date: Sat, 13 Jun 2026 14:35:40 +0530 [thread overview]
Message-ID: <20260613090543.78643-6-sachinp@linux.ibm.com> (raw)
In-Reply-To: <20260613090543.78643-1-sachinp@linux.ibm.com>
Add acl_file_ops01 test to verify that standard file operations
(chmod, chown) interact correctly with POSIX ACLs using direct
xattr manipulation.
Test coverage:
- chmod updates ACL_USER_OBJ, ACL_GROUP_OBJ, and ACL_OTHER entries
- chown changes file owner/group without affecting ACL permissions
- ACL permissions are preserved after ownership changes
The test uses arbitrary UIDs without creating actual users, testing
only the kernel ACL implementation. It runs on ext2/ext3/ext4 (with
acl mount option), XFS, and Btrfs filesystems.
Suggested-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Sachin Sant <sachinp@linux.ibm.com>
---
V8 changes:
- Use RST manpage documentation format for syscalls
- remove forks_child since it is not required.
- v7 link https://lore.kernel.org/ltp/20260612171930.11964-1-sachinp@linux.ibm.com/T/#t
V7 changes:
- No change
V6 changes:
- Added HAVE_SYS_XATTR_H guard
- Removed redundant error checking, relying on library functions
- Updated algorithm documentation with correct format
- v5 link https://lore.kernel.org/ltp/20260608092200.92827-1-sachinp@linux.ibm.com/T/#t
V5 changes:
- Switch to kernel only test validation to remove dependency on libacl
and useradd/del commands.
- v3 link https://lore.kernel.org/ltp/20260604065417.25924-1-sachinp@linux.ibm.com/T/#t
V4 changes:
- No change
V3 changes:
- Updated copyright header as per LTP format.
- v1 link https://lore.kernel.org/ltp/20260602121958.27494-1-sachinp@linux.ibm.com/T/#t
V2 changes:
- No change
V1 changes:
- Use HAVE_LIBACL guards in .c code
- Report TCONF when libacl is not available
- rfc link https://lore.kernel.org/ltp/477836fd-80c8-4168-bfe6-00b374bb2534@linux.ibm.com/T/#t
---
runtest/fs | 1 +
testcases/kernel/fs/acl/.gitignore | 1 +
testcases/kernel/fs/acl/acl_file_ops01.c | 256 +++++++++++++++++++++++
3 files changed, 258 insertions(+)
create mode 100644 testcases/kernel/fs/acl/acl_file_ops01.c
diff --git a/runtest/fs b/runtest/fs
index fd295edc7..f1eea055b 100644
--- a/runtest/fs
+++ b/runtest/fs
@@ -93,3 +93,4 @@ acl_user_obj01 acl_user_obj01
acl_mask01 acl_mask01
acl_other01 acl_other01
acl_inherit01 acl_inherit01
+acl_file_ops01 acl_file_ops01
diff --git a/testcases/kernel/fs/acl/.gitignore b/testcases/kernel/fs/acl/.gitignore
index bc03ba1fd..eb4b4a227 100644
--- a/testcases/kernel/fs/acl/.gitignore
+++ b/testcases/kernel/fs/acl/.gitignore
@@ -2,3 +2,4 @@
/acl_mask01
/acl_other01
/acl_inherit01
+/acl_file_ops01
diff --git a/testcases/kernel/fs/acl/acl_file_ops01.c b/testcases/kernel/fs/acl/acl_file_ops01.c
new file mode 100644
index 000000000..323090497
--- /dev/null
+++ b/testcases/kernel/fs/acl/acl_file_ops01.c
@@ -0,0 +1,256 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 IBM
+ *
+ * Original shell test by Kai Zhao (ltcd3@cn.ibm.com)
+ * Converted to C by Sachin Sant <sachinp@linux.ibm.com>
+ */
+
+/*\
+ * Test :manpage:`chmod(2)` and :manpage:`chown(2)` interaction
+ * with ACLs using direct xattr manipulation.
+ *
+ * Verify that standard file operations interact correctly
+ * with ACLs:
+ * - :manpage:`chmod(2)` should update ACL_USER_OBJ, ACL_GROUP_OBJ,
+ * and ACL_OTHER entries
+ * - :manpage:`chown(2)` should change file owner/group without
+ * affecting ACL entries
+ * - ACL permissions should be preserved after ownership changes
+ *
+ * This test uses arbitrary UIDs without creating actual users, testing
+ * only the kernel ACL implementation.
+ *
+ * [Algorithm]
+ *
+ * Test 1 - :manpage:`chmod(2)` interaction:
+ * - Create file with read-only ACL entries
+ * - Use :manpage:`chmod(2)` to set permissions to 0777
+ * - Verify ACL entries are updated to rwx for user, group, and other
+ *
+ * Test 2 - :manpage:`chown(2)` interaction:
+ * - Create file with specific ACL entries (rw for user, r for group/other)
+ * - Use :manpage:`chown(2)` to change owner and group
+ * - Verify ownership changed correctly
+ * - Verify ACL entries preserved their permissions after
+ * :manpage:`chown(2)`
+ */
+
+#include "acl_lib.h"
+
+#ifdef HAVE_SYS_XATTR_H
+
+#define TEST_UID 1000
+#define TEST_GID 1000
+#define USER2_UID 2000
+#define USER2_GID 2000
+
+/*
+ * Test chmod interaction with ACLs.
+ * chmod should update ACL_USER_OBJ, ACL_GROUP_OBJ, and ACL_OTHER.
+ */
+static void test_chmod_acl(void)
+{
+ struct acl *acl;
+ int fd = -1;
+ int user_ok = 0, group_ok = 0, other_ok = 0;
+
+ tst_res(TINFO, "Testing chmod interaction with ACLs");
+ reset_test_path();
+
+ fd = SAFE_OPEN(TESTFILE, O_CREAT | O_WRONLY, 0644);
+ SAFE_CLOSE(fd);
+
+ acl = acl_init();
+
+ acl_add_entry(acl, ACL_USER_OBJ, ACL_READ, 0);
+ acl_add_entry(acl, ACL_GROUP_OBJ, ACL_READ, 0);
+ acl_add_entry(acl, ACL_OTHER, ACL_READ, 0);
+
+ if (acl_set_file(TESTFILE, ACL_TYPE_ACCESS, acl) < 0) {
+ if (errno == EOPNOTSUPP) {
+ acl_free(acl);
+ cleanup_testfile();
+ tst_brk(TCONF | TERRNO, "ACL not supported");
+ }
+ acl_free(acl);
+ cleanup_testfile();
+ tst_brk(TBROK | TERRNO, "ACL setup failed");
+ }
+
+ acl_free(acl);
+
+ SAFE_CHMOD(TESTFILE, 0777);
+
+ acl = acl_get_file(TESTFILE, ACL_TYPE_ACCESS);
+ if (!acl) {
+ cleanup_testfile();
+ tst_brk(TBROK | TERRNO, "acl_get_file failed");
+ }
+
+ /* Check if all entries have rwx permissions */
+ for (int i = 0; i < acl->count; i++) {
+ struct acl_entry *entry = &acl->entries[i];
+
+ if (entry->tag == ACL_USER_OBJ) {
+ if (acl_entry_has_rwx(entry))
+ user_ok = 1;
+ } else if (entry->tag == ACL_GROUP_OBJ) {
+ if (acl_entry_has_rwx(entry))
+ group_ok = 1;
+ } else if (entry->tag == ACL_OTHER) {
+ if (acl_entry_has_rwx(entry))
+ other_ok = 1;
+ }
+ }
+
+ acl_free(acl);
+ cleanup_testfile();
+
+ if (user_ok && group_ok && other_ok)
+ tst_res(TPASS, "chmod correctly updated ACL entries");
+ else
+ tst_res(TFAIL, "chmod did not update ACL entries correctly");
+}
+
+/*
+ * Test chown interaction with ACLs.
+ * chown should change file owner and group without affecting ACL entries.
+ */
+static void test_chown_acl(void)
+{
+ struct acl *acl;
+ struct stat st;
+ int fd = -1;
+ int found_user_obj = 0, found_group_obj = 0, found_other = 0;
+
+ tst_res(TINFO, "Testing chown interaction with ACLs");
+ reset_test_path();
+
+ fd = SAFE_OPEN(TESTFILE, O_CREAT | O_WRONLY, 0644);
+ SAFE_CLOSE(fd);
+
+ acl = acl_init();
+
+ acl_add_entry(acl, ACL_USER_OBJ, ACL_READ | ACL_WRITE, 0);
+ acl_add_entry(acl, ACL_GROUP_OBJ, ACL_READ, 0);
+ acl_add_entry(acl, ACL_OTHER, ACL_READ, 0);
+
+ if (acl_set_file(TESTFILE, ACL_TYPE_ACCESS, acl) < 0) {
+ acl_free(acl);
+ cleanup_testfile();
+ if (errno == EOPNOTSUPP)
+ tst_brk(TCONF | TERRNO, "ACL not supported");
+ tst_brk(TBROK | TERRNO, "acl_set_file failed");
+ }
+
+ acl_free(acl);
+
+ SAFE_CHOWN(TESTFILE, USER2_UID, USER2_GID);
+
+ SAFE_STAT(TESTFILE, &st);
+
+ if (st.st_uid != USER2_UID || st.st_gid != USER2_GID) {
+ cleanup_testfile();
+ tst_res(TFAIL, "chown did not change owner/group correctly");
+ return;
+ }
+
+ /* Verify ACL entries are preserved after chown */
+ acl = acl_get_file(TESTFILE, ACL_TYPE_ACCESS);
+ if (!acl) {
+ cleanup_testfile();
+ tst_brk(TBROK | TERRNO, "acl_get_file failed");
+ }
+
+ for (int i = 0; i < acl->count; i++) {
+ struct acl_entry *entry = &acl->entries[i];
+
+ if (entry->tag == ACL_USER_OBJ) {
+ found_user_obj = 1;
+ if (!acl_entry_has_perm(entry, ACL_READ) ||
+ !acl_entry_has_perm(entry, ACL_WRITE)) {
+ acl_free(acl);
+ cleanup_testfile();
+ tst_res(TFAIL,
+ "ACL_USER_OBJ perms changed after chown");
+ return;
+ }
+ } else if (entry->tag == ACL_GROUP_OBJ) {
+ found_group_obj = 1;
+ if (!acl_entry_has_perm(entry, ACL_READ) ||
+ acl_entry_has_perm(entry, ACL_WRITE)) {
+ acl_free(acl);
+ cleanup_testfile();
+ tst_res(TFAIL,
+ "ACL_GROUP_OBJ perms changed after chown");
+ return;
+ }
+ } else if (entry->tag == ACL_OTHER) {
+ found_other = 1;
+ if (!acl_entry_has_perm(entry, ACL_READ) ||
+ acl_entry_has_perm(entry, ACL_WRITE)) {
+ acl_free(acl);
+ cleanup_testfile();
+ tst_res(TFAIL,
+ "ACL_OTHER perms changed after chown");
+ return;
+ }
+ }
+ }
+
+ acl_free(acl);
+
+ if (!found_user_obj || !found_group_obj || !found_other) {
+ cleanup_testfile();
+ tst_res(TFAIL, "ACL entries missing after chown");
+ return;
+ }
+
+ cleanup_testfile();
+ tst_res(TPASS, "chown preserved ACL entries correctly");
+}
+
+static void setup(void)
+{
+ reset_test_path();
+}
+
+static void cleanup(void)
+{
+ cleanup_test_paths();
+}
+
+static void run(unsigned int n)
+{
+ switch (n) {
+ case 0:
+ test_chmod_acl();
+ break;
+ case 1:
+ test_chown_acl();
+ break;
+ }
+}
+
+static struct tst_test test = {
+ .test = run,
+ .tcnt = 2,
+ .setup = setup,
+ .cleanup = cleanup,
+ .needs_root = 1,
+ .mount_device = 1,
+ .mntpoint = MNTPOINT,
+ .filesystems = (struct tst_fs[]) {
+ {.type = "ext2", .mnt_data = "acl"},
+ {.type = "ext3", .mnt_data = "acl"},
+ {.type = "ext4", .mnt_data = "acl"},
+ {.type = "xfs"},
+ {.type = "btrfs"},
+ {}
+ }
+};
+
+#else
+ TST_TEST_TCONF("sys/xattr.h is not available");
+#endif
--
2.39.1
--
Mailing list info: https://lists.linux.it/listinfo/ltp
next prev parent reply other threads:[~2026-06-13 9:07 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-13 9:05 [LTP] [PATCH v8 0/8] Convert shell-based ACL test (tacl_xattr.sh) to C Sachin Sant
2026-06-13 9:05 ` [LTP] [PATCH v8 1/8] fs/acl: Add ACL_USER_OBJ permission test Sachin Sant
2026-06-13 10:36 ` [LTP] " linuxtestproject.agent
2026-06-13 9:05 ` [LTP] [PATCH v8 2/8] fs/acl: Add ACL mask interaction tests Sachin Sant
2026-06-13 9:05 ` [LTP] [PATCH v8 3/8] fs/acl: Add ACL_OTHER permission test Sachin Sant
2026-06-13 9:05 ` [LTP] [PATCH v8 4/8] fs/acl: Add default ACL inheritance test Sachin Sant
2026-06-13 9:05 ` Sachin Sant [this message]
2026-06-13 9:05 ` [LTP] [PATCH v8 6/8] fs/acl: Add ACL symlink operations test Sachin Sant
2026-06-13 9:05 ` [LTP] [PATCH v8 7/8] fs/acl: Add extended attributes test Sachin Sant
2026-06-13 9:05 ` [LTP] [PATCH v8 8/8] fs/acl: Remove old shell-based ACL test Sachin Sant
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260613090543.78643-6-sachinp@linux.ibm.com \
--to=sachinp@linux.ibm.com \
--cc=ltp@lists.linux.it \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.