[PATCH v4 4/8] fs/acl: Add default ACL inheritance test

Sachin Sant <[email protected]>
Newsgroups gmane.linux.ltp
Message-ID <[email protected]>
Add acl_inherit01 test to validate default ACL inheritance from
parent directory to newly created files.

The test verifies that:
- Default ACLs set on a directory are inherited by new files
- New file permissions reflect the default ACL entries
- File created with umask 0 gets permissions from default ACL

This test sets default ACL with read-only permissions (r--r--r--)
on the parent directory, creates a new file with umask 0, and
verifies the file has 0444 permissions inherited from the
default ACL.

Suggested-by: Cyril Hrubis <[email protected]>
Signed-off-by: Sachin Sant <[email protected]>
---
V4 changes:
- Switch to kernel only test validation to remove dependency on libacl
  and useradd/del commands.
- v3 link https://lore.kernel.org/ltp/[email protected]/T/#t

V3 changes:
- Remove unused acl_get_file() block
- keep mode-bit validation with explanatory comment
- v2 link https://lore.kernel.org/ltp/[email protected]/T/#t

V2 changes:
- Updated copyright header as per LTP format.
- v1 link https://lore.kernel.org/ltp/[email protected]/T/#t

V1 changes:
- Use HAVE_LIBACL guards in .c code
- Report TCONF when libacl is not available
- rfc link https://lore.kernel.org/ltp/[email protected]/T/#t

---
 runtest/fs                              |   1 +
 testcases/kernel/fs/acl/.gitignore      |   1 +
 testcases/kernel/fs/acl/acl_inherit01.c | 125 ++++++++++++++++++++++++
 3 files changed, 127 insertions(+)
 create mode 100644 testcases/kernel/fs/acl/acl_inherit01.c

diff --git a/runtest/fs b/runtest/fs
index f25487a33..fd295edc7 100644
--- a/runtest/fs
+++ b/runtest/fs
@@ -92,3 +92,4 @@ squashfs01 squashfs01
 acl_user_obj01 acl_user_obj01
 acl_mask01 acl_mask01
 acl_other01 acl_other01
+acl_inherit01 acl_inherit01
diff --git a/testcases/kernel/fs/acl/.gitignore b/testcases/kernel/fs/acl/.gitignore
index c3ec0fad3..bc03ba1fd 100644
--- a/testcases/kernel/fs/acl/.gitignore
+++ b/testcases/kernel/fs/acl/.gitignore
@@ -1,3 +1,4 @@
 /acl_user_obj01
 /acl_mask01
 /acl_other01
+/acl_inherit01
diff --git a/testcases/kernel/fs/acl/acl_inherit01.c b/testcases/kernel/fs/acl/acl_inherit01.c
new file mode 100644
index 000000000..76423308b
--- /dev/null
+++ b/testcases/kernel/fs/acl/acl_inherit01.c
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 IBM
+ *
+ * Original shell test by Kai Zhao ([email protected])
+ * Converted to C by Sachin Sant <[email protected]>
+ */
+
+/*\
+ * Test default ACL inheritance using direct xattr manipulation.
+ *
+ * Verify that files created in a directory with default ACLs inherit
+ * those ACLs as their access ACLs. Default ACLs are only applicable
+ * to directories and define the access ACLs that files and subdirectories
+ * created within that directory will inherit.
+ *
+ * This test uses arbitrary UIDs without creating actual users, testing
+ * only the kernel ACL implementation.
+ *
+ * [Algorithm]
+ *
+ * 1. Set default ACL on parent directory with read-only permissions
+ * 2. Create a new file in that directory with umask 0
+ * 3. Verify the file inherits the default ACL as its access ACL
+ * 4. Check that file permissions match the inherited ACL (0444)
+ */
+
+#include "acl_lib.h"
+
+#define TEST_UID 1000
+#define TEST_GID 1000
+
+static void run(void)
+{
+	struct acl *acl = NULL;
+	struct stat st;
+	int err;
+
+	tst_res(TINFO, "Testing default ACL inheritance");
+	reset_test_path();
+
+	SAFE_CHOWN(TESTDIR, TEST_UID, TEST_GID);
+
+	acl = acl_init();
+	if (!acl)
+		tst_brk(TBROK | TERRNO, "acl_init failed");
+
+	if (acl_add_entry(acl, ACL_USER_OBJ, ACL_READ, 0) < 0)
+		goto cleanup_acl;
+
+	if (acl_add_entry(acl, ACL_GROUP_OBJ, ACL_READ, 0) < 0)
+		goto cleanup_acl;
+
+	if (acl_add_entry(acl, ACL_OTHER, ACL_READ, 0) < 0)
+		goto cleanup_acl;
+
+	if (acl_set_file(TESTDIR, ACL_TYPE_DEFAULT, acl) < 0) {
+		if (errno == EOPNOTSUPP) {
+			acl_free(acl);
+			tst_brk(TCONF | TERRNO, "ACL not supported");
+		}
+		goto cleanup_acl;
+	}
+
+	acl_free(acl);
+	acl = NULL;
+
+	err = create_with_umask_as(TEST_UID, TEST_GID, 0666, 0);
+	if (err) {
+		errno = err;
+		tst_res(TFAIL | TERRNO, "Failed to create test file");
+		return;
+	}
+
+	SAFE_STAT(TESTFILE, &st);
+
+	/*
+	 * For a minimal ACL (containing only ACL_USER_OBJ, ACL_GROUP_OBJ,
+	 * and ACL_OTHER), the mode bits are the canonical representation.
+	 * Verifying the mode bits confirms the inherited ACL was applied.
+	 */
+	if ((st.st_mode & 0777) != 0444) {
+		tst_res(TFAIL,
+			"File permissions 0%o, expected 0444 from default ACL",
+			st.st_mode & 0777);
+		cleanup_testfile();
+		return;
+	}
+
+	cleanup_testfile();
+	tst_res(TPASS, "Default ACL inheritance works correctly");
+	return;
+
+cleanup_acl:
+	acl_free(acl);
+	tst_brk(TBROK | TERRNO, "ACL setup failed");
+}
+
+static void setup(void)
+{
+	reset_test_path();
+}
+
+static void cleanup(void)
+{
+	cleanup_test_paths();
+}
+
+static struct tst_test test = {
+	.test_all = run,
+	.setup = setup,
+	.cleanup = cleanup,
+	.needs_root = 1,
+	.mount_device = 1,
+	.mntpoint = MNTPOINT,
+	.forks_child = 1,
+	.filesystems = (struct tst_fs[]) {
+		{.type = "ext2", .mnt_data = "acl"},
+		{.type = "ext3", .mnt_data = "acl"},
+		{.type = "ext4", .mnt_data = "acl"},
+		{.type = "xfs"},
+		{.type = "btrfs"},
+		{}
+	}
+};
-- 
2.39.1


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.