From: Sachin Sant <sachinp@linux.ibm.com>
To: ltp@lists.linux.it
Subject: [LTP] [PATCH v8 1/8] fs/acl: Add ACL_USER_OBJ permission test
Date: Sat, 13 Jun 2026 14:35:36 +0530 [thread overview]
Message-ID: <20260613090543.78643-2-sachinp@linux.ibm.com> (raw)
In-Reply-To: <20260613090543.78643-1-sachinp@linux.ibm.com>
Add acl_user_obj01 test to validate ACL_USER_OBJ permissions:
- Owner permissions correctly control file/directory access
- ACL_USER_OBJ=rwx via setxattr() overrides chmod restrictions
- Owner permissions work independently of group/other permissions
- Tests use arbitrary UIDs without requiring actual user creation
The patch also adds acl_lib.h containing shared helpers for ACL
manipulation via xattr API, including:
- ACL structure management (acl_init, acl_free, acl_add_entry)
- ACL serialization/deserialization for kernel xattr format
- ACL get/set operations using getxattr/setxattr
- permission testing and file operations
- Support for both ACCESS and DEFAULT ACL types
The implementation uses direct xattr API (getxattr/setxattr) to
test kernel ACL behavior directly. Tests run on ext2/3/4,
XFS, and Btrfs filesystems with ACL support.
Suggested-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Sachin Sant <sachinp@linux.ibm.com>
---
V8 changes:
- Removed no chown variant of reset_test_path
- Use RST manpage formatted documentation
- v7 link https://lore.kernel.org/ltp/20260612171930.11964-1-sachinp@linux.ibm.com/T/#t
V7 changes:
- Use SAFE_ variants of setresgid/setresuid
- Replace TST_EXP_FAIL with TST_EXP_FAIL2
- v6 link https://lore.kernel.org/ltp/20260612102502.24071-1-sachinp@linux.ibm.com/T/#t
V6 changes:
- Added HAVE_SYS_XATTR_H guards for systems without xattr support
- Removed unnecessary error paths and manual status checking
- Uses SAFE_MALLOC() and new helper macros
- Added acl_type_to_name() helper to eliminate duplication
- 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.
- v4 link https://lore.kernel.org/ltp/20260604065417.25924-1-sachinp@linux.ibm.com/T/#t
V4 changes:
- Add -U flag in create_user_if_needed() to useradd for guaranteed
user-private groups.
- Move EOPNOTSUPP handling into set_acl_file() helper
- v3 link https://lore.kernel.org/ltp/20260603140147.50738-1-sachinp@linux.ibm.com/T/#t
V3 changes:
- Updated copyright header as per LTP format.
- v2 link https://lore.kernel.org/ltp/20260603065744.47106-1-sachinp@linux.ibm.com/T/#t
V2 changes:
- Added no chown variant of reset_test_path to skip chown step.
acl_link01 and xattr_test01 tests are updated to use this
variant.
- Updated acl_user_obj01.c to correct incorrect description
- v1 link https://lore.kernel.org/ltp/20260602121958.27494-1-sachinp@linux.ibm.com/T/#t
V1 changes:
- Use ACL_LIBS variable instead of hardcoded -lacl in Makefile
- Move ACL header includes inside feature guards in acl_lib.h
- 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 | 3 +
testcases/kernel/fs/acl/.gitignore | 1 +
testcases/kernel/fs/acl/Makefile | 8 +
testcases/kernel/fs/acl/acl_lib.h | 507 +++++++++++++++++++++++
testcases/kernel/fs/acl/acl_user_obj01.c | 126 ++++++
5 files changed, 645 insertions(+)
create mode 100644 testcases/kernel/fs/acl/.gitignore
create mode 100644 testcases/kernel/fs/acl/Makefile
create mode 100644 testcases/kernel/fs/acl/acl_lib.h
create mode 100644 testcases/kernel/fs/acl/acl_user_obj01.c
diff --git a/runtest/fs b/runtest/fs
index 1d753e0dd..2a878744b 100644
--- a/runtest/fs
+++ b/runtest/fs
@@ -87,3 +87,6 @@ binfmt_misc01 binfmt_misc01.sh
binfmt_misc02 binfmt_misc02.sh
squashfs01 squashfs01
+
+# Run the acl tests
+acl_user_obj01 acl_user_obj01
diff --git a/testcases/kernel/fs/acl/.gitignore b/testcases/kernel/fs/acl/.gitignore
new file mode 100644
index 000000000..d9c46db11
--- /dev/null
+++ b/testcases/kernel/fs/acl/.gitignore
@@ -0,0 +1 @@
+/acl_user_obj01
diff --git a/testcases/kernel/fs/acl/Makefile b/testcases/kernel/fs/acl/Makefile
new file mode 100644
index 000000000..2d9cba46d
--- /dev/null
+++ b/testcases/kernel/fs/acl/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2026 IBM
+
+top_srcdir ?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/fs/acl/acl_lib.h b/testcases/kernel/fs/acl/acl_lib.h
new file mode 100644
index 000000000..7fe68aa59
--- /dev/null
+++ b/testcases/kernel/fs/acl/acl_lib.h
@@ -0,0 +1,507 @@
+/* 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>
+ *
+ * Common library for ACL and extended attribute tests using xattr API
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#ifndef ACL_LIB_H
+#define ACL_LIB_H
+
+#include "config.h"
+
+#include <pwd.h>
+#include <grp.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdint.h>
+#include <endian.h>
+#include <sys/fsuid.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#ifdef HAVE_SYS_XATTR_H
+#include <sys/xattr.h>
+#endif
+#include "tst_test.h"
+#include "tst_safe_stdio.h"
+#include "tst_capability.h"
+
+#define MNTPOINT "mntpoint"
+#define TESTDIR MNTPOINT "/testdir"
+#define TESTFILE TESTDIR "/testfile"
+#define TESTSYMLINK TESTDIR "/testsymlink"
+#define XATTR_BACKUP_FILE MNTPOINT "/xattr_backup.txt"
+
+/* Extended attribute test values */
+#define XATTR_TEST_DIR_NAME "user.test_attr"
+#define XATTR_TEST_DIR_VALUE "test_value"
+#define XATTR_TEST_DIR_SIZE 10
+#define XATTR_TEST_FILE_NAME "user.file_attr"
+#define XATTR_TEST_FILE_VALUE "file_val"
+#define XATTR_TEST_FILE_SIZE 8
+#define XATTR_TEST1_NAME "user.test1"
+#define XATTR_TEST1_VALUE "value1"
+#define XATTR_TEST1_SIZE 6
+#define XATTR_TEST2_NAME "user.test2"
+#define XATTR_TEST2_VALUE "value2"
+#define XATTR_TEST2_SIZE 6
+
+/*
+ * POSIX ACL xattr format definitions
+ * These match the kernel's internal representation
+ */
+#define POSIX_ACL_XATTR_VERSION 0x0002
+
+/* ACL entry tag types */
+#define ACL_UNDEFINED_TAG 0x00
+#define ACL_USER_OBJ 0x01
+#define ACL_USER 0x02
+#define ACL_GROUP_OBJ 0x04
+#define ACL_GROUP 0x08
+#define ACL_MASK 0x10
+#define ACL_OTHER 0x20
+
+/* ACL permissions */
+#define ACL_READ 0x04
+#define ACL_WRITE 0x02
+#define ACL_EXECUTE 0x01
+
+/* ACL xattr names */
+#define XATTR_NAME_POSIX_ACL_ACCESS "system.posix_acl_access"
+#define XATTR_NAME_POSIX_ACL_DEFAULT "system.posix_acl_default"
+
+/* ACL type for set/get operations */
+#define ACL_TYPE_ACCESS 1
+#define ACL_TYPE_DEFAULT 2
+
+/* Convert host to little-endian */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define cpu_to_le16(x) (x)
+#define cpu_to_le32(x) (x)
+#define le16_to_cpu(x) (x)
+#define le32_to_cpu(x) (x)
+#else
+#define cpu_to_le16(x) __builtin_bswap16(x)
+#define cpu_to_le32(x) __builtin_bswap32(x)
+#define le16_to_cpu(x) __builtin_bswap16(x)
+#define le32_to_cpu(x) __builtin_bswap32(x)
+#endif
+
+/*
+ * POSIX ACL xattr format as stored in kernel
+ * This is the on-disk/in-xattr representation
+ */
+struct posix_acl_xattr_header {
+ uint32_t a_version;
+};
+
+struct posix_acl_xattr_entry {
+ uint16_t e_tag;
+ uint16_t e_perm;
+ uint32_t e_id;
+};
+
+/*
+ * Combined xattr structure for ACL operations
+ */
+struct acl_xattr {
+ struct posix_acl_xattr_header header;
+ struct posix_acl_xattr_entry entries[];
+};
+
+/*
+ * In-memory ACL representation for building ACLs
+ */
+#define MAX_ACL_ENTRIES 32
+
+struct acl_entry {
+ uint16_t tag;
+ uint16_t perm;
+ uint32_t id;
+};
+
+struct acl {
+ int count;
+ struct acl_entry entries[MAX_ACL_ENTRIES];
+};
+
+/*
+ * SAFE_TRY_UNLINK - unlink a file, ignoring ENOENT
+ * Won't TBROK if file doesn't exist
+ */
+#define SAFE_TRY_UNLINK(path) do { \
+ if (unlink(path) == -1 && errno != ENOENT) \
+ tst_brk(TBROK | TERRNO, "unlink(%s) failed", path); \
+} while (0)
+
+/*
+ * SAFE_TRY_RMDIR - remove a directory, ignoring ENOENT
+ * Won't TBROK if directory doesn't exist
+ */
+#define SAFE_TRY_RMDIR(path) do { \
+ if (rmdir(path) == -1 && errno != ENOENT) \
+ tst_brk(TBROK | TERRNO, "rmdir(%s) failed", path); \
+} while (0)
+
+static inline void reset_test_path(void)
+{
+ SAFE_TRY_UNLINK(TESTSYMLINK);
+ SAFE_TRY_UNLINK(TESTFILE);
+ SAFE_TRY_RMDIR(TESTDIR);
+
+ SAFE_MKDIR(TESTDIR, 0755);
+}
+
+static inline void cleanup_testfile(void)
+{
+ SAFE_TRY_UNLINK(TESTFILE);
+}
+
+#ifdef HAVE_SYS_XATTR_H
+
+/*
+ * Initialize an empty ACL structure
+ */
+static inline struct acl *acl_init(void)
+{
+ struct acl *acl = SAFE_MALLOC(sizeof(struct acl));
+
+ acl->count = 0;
+ return acl;
+}
+
+/*
+ * Free an ACL structure
+ */
+static inline void acl_free(struct acl *acl)
+{
+ free(acl);
+}
+
+/*
+ * Add an ACL entry to the ACL structure
+ */
+static inline int acl_add_entry(struct acl *acl, uint16_t tag, uint16_t perm,
+ uint32_t id)
+{
+ if (acl->count >= MAX_ACL_ENTRIES) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ acl->entries[acl->count].tag = tag;
+ acl->entries[acl->count].perm = perm;
+ acl->entries[acl->count].id = id;
+ acl->count++;
+ return 0;
+}
+
+/*
+ * Convert ACL type to xattr name
+ */
+static inline const char *acl_type_to_name(int type)
+{
+ if (type == ACL_TYPE_ACCESS)
+ return XATTR_NAME_POSIX_ACL_ACCESS;
+ else if (type == ACL_TYPE_DEFAULT)
+ return XATTR_NAME_POSIX_ACL_DEFAULT;
+ else
+ return NULL;
+}
+
+/*
+ * Set ACL on a file using xattr.
+ *
+ * The kernel stores access ACLs only when they differ from the file mode.
+ * If the ACL is equivalent to st_mode, the xattr is removed and future
+ * getxattr() calls return ENODATA. Mirror libacl semantics by treating
+ * ENODATA as a valid minimal ACL derived from st_mode.
+ */
+static inline int acl_set_file(const char *path, int type, struct acl *acl)
+{
+ const char *xattr_name;
+ size_t size;
+ char *buf;
+ struct posix_acl_xattr_header *header;
+ struct posix_acl_xattr_entry *entries;
+ int i, ret;
+
+ xattr_name = acl_type_to_name(type);
+ if (!xattr_name) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ size = sizeof(struct posix_acl_xattr_header) +
+ acl->count * sizeof(struct posix_acl_xattr_entry);
+
+ buf = malloc(size);
+ if (!buf)
+ return -1;
+
+ header = (struct posix_acl_xattr_header *)buf;
+ header->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
+
+ entries = (struct posix_acl_xattr_entry *)(buf + sizeof(*header));
+
+ for (i = 0; i < acl->count; i++) {
+ entries[i].e_tag = cpu_to_le16(acl->entries[i].tag);
+ entries[i].e_perm = cpu_to_le16(acl->entries[i].perm);
+ entries[i].e_id = cpu_to_le32(acl->entries[i].id);
+ }
+
+ ret = setxattr(path, xattr_name, buf, size, 0);
+ free(buf);
+
+ return ret;
+}
+
+static inline void acl_add_mode_entries(struct acl *acl, mode_t mode)
+{
+ acl_add_entry(acl, ACL_USER_OBJ, (mode >> 6) & 07, 0);
+ acl_add_entry(acl, ACL_GROUP_OBJ, (mode >> 3) & 07, 0);
+ acl_add_entry(acl, ACL_OTHER, mode & 07, 0);
+}
+
+/*
+ * Synthesize an ACL from file mode bits.
+ * Used when no xattr exists for an access ACL.
+ */
+static inline struct acl *acl_from_mode(const char *path)
+{
+ struct acl *acl;
+ struct stat st;
+
+ if (stat(path, &st) < 0)
+ return NULL;
+
+ acl = acl_init();
+ acl_add_mode_entries(acl, st.st_mode);
+
+ return acl;
+}
+
+/*
+ * Get ACL from a file using xattr.
+ *
+ * Access ACLs equivalent to file mode may not have a backing xattr at all.
+ * In that case synthesize the base ACL from st_mode so callers observe the
+ * same behavior as acl_get_file(3).
+ */
+static inline struct acl *acl_get_file(const char *path, int type)
+{
+ const char *xattr_name;
+ ssize_t size;
+ struct acl_xattr *ax;
+ struct acl *acl;
+ int i, count;
+
+ xattr_name = acl_type_to_name(type);
+ if (!xattr_name) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ size = getxattr(path, xattr_name, NULL, 0);
+ if (size < 0) {
+ if (errno != ENODATA || type != ACL_TYPE_ACCESS)
+ return NULL;
+
+ return acl_from_mode(path);
+ }
+
+ /* Handle race: xattr removed between size check and actual read */
+ if (size == 0)
+ return acl_from_mode(path);
+
+ ax = malloc(size);
+ if (!ax)
+ return NULL;
+
+ size = getxattr(path, xattr_name, ax, size);
+ if (size < 0) {
+ free(ax);
+ /* Handle race: xattr removed between size check and read */
+ if (errno == ENODATA && type == ACL_TYPE_ACCESS)
+ return acl_from_mode(path);
+ return NULL;
+ }
+
+ if (le32_to_cpu(ax->header.a_version) != POSIX_ACL_XATTR_VERSION) {
+ free(ax);
+ errno = EINVAL;
+ return NULL;
+ }
+
+ count = (size - sizeof(ax->header)) /
+ sizeof(struct posix_acl_xattr_entry);
+
+ acl = acl_init();
+ if (!acl) {
+ free(ax);
+ return NULL;
+ }
+
+ for (i = 0; i < count; i++) {
+ uint16_t tag = le16_to_cpu(ax->entries[i].e_tag);
+ uint16_t perm = le16_to_cpu(ax->entries[i].e_perm);
+ uint32_t id = le32_to_cpu(ax->entries[i].e_id);
+
+ if (acl_add_entry(acl, tag, perm, id) < 0) {
+ acl_free(acl);
+ free(ax);
+ return NULL;
+ }
+ }
+
+ free(ax);
+ return acl;
+}
+
+/*
+ * Check if an ACL entry has a specific permission
+ */
+static inline int acl_entry_has_perm(struct acl_entry *entry, uint16_t perm)
+{
+ return (entry->perm & perm) == perm;
+}
+
+/*
+ * Check if an ACL entry has all rwx permissions
+ */
+static inline int acl_entry_has_rwx(struct acl_entry *entry)
+{
+ return acl_entry_has_perm(entry,
+ ACL_READ | ACL_WRITE | ACL_EXECUTE);
+}
+
+/*
+ * Find an ACL entry by tag type
+ */
+static inline struct acl_entry *acl_find_entry(struct acl *acl, uint16_t tag,
+ uint32_t id)
+{
+ int i;
+
+ for (i = 0; i < acl->count; i++) {
+ if (acl->entries[i].tag == tag) {
+ if (tag == ACL_USER || tag == ACL_GROUP) {
+ if (acl->entries[i].id == id)
+ return &acl->entries[i];
+ } else {
+ return &acl->entries[i];
+ }
+ }
+ }
+
+ return NULL;
+}
+
+/*
+ * Update ACL mask permissions
+ */
+static inline int acl_set_mask_perms(struct acl *acl, uint16_t perm)
+{
+ struct acl_entry *mask_entry = acl_find_entry(acl, ACL_MASK, 0);
+
+ if (!mask_entry) {
+ errno = ENOENT;
+ return -1;
+ }
+
+ mask_entry->perm = perm;
+ return 0;
+}
+
+static inline void create_file_as(uid_t uid, gid_t gid, mode_t mode,
+ int use_umask, mode_t mask, int exp_errno)
+{
+ pid_t pid;
+
+ pid = SAFE_FORK();
+ if (!pid) {
+ uid_t fsuid;
+ gid_t fsgid;
+ struct tst_cap_user_header hdr = {
+ .version = 0x20080522,
+ .pid = 0,
+ };
+ struct tst_cap_user_data data[2] = {};
+
+ SAFE_SETGROUPS(0, NULL);
+ SAFE_SETRESGID(gid, gid, gid);
+ SAFE_SETRESUID(uid, uid, uid);
+
+ /* Drop all capabilities to ensure DAC checks are enforced */
+ if (tst_capset(&hdr, data) < 0)
+ tst_brk(TBROK | TERRNO, "capset failed");
+
+ /*
+ * setfsuid()/setfsgid() return the previous value, not -1 on
+ * failure. Verify the effective filesystem credentials by
+ * reading them back.
+ */
+ setfsuid(uid);
+ fsuid = setfsuid((uid_t)-1);
+ if (fsuid != uid)
+ tst_brk(TBROK,
+ "setfsuid verification failed, expected %u got %u",
+ (unsigned int)uid, (unsigned int)fsuid);
+
+ setfsgid(gid);
+ fsgid = setfsgid((gid_t)-1);
+ if (fsgid != gid)
+ tst_brk(TBROK,
+ "setfsgid verification failed, expected %u got %u",
+ (unsigned int)gid, (unsigned int)fsgid);
+
+ if (use_umask)
+ umask(mask);
+
+ if (exp_errno) {
+ TST_EXP_FAIL2(open(TESTFILE, O_CREAT | O_WRONLY, mode),
+ exp_errno, "open(%s)", TESTFILE);
+ } else {
+ TST_EXP_FD(open(TESTFILE, O_CREAT | O_WRONLY, mode),
+ "open(%s)", TESTFILE);
+ if (TST_RET >= 0)
+ SAFE_CLOSE(TST_RET);
+ }
+
+ exit(0);
+ }
+
+ tst_reap_children();
+}
+
+static inline void try_create_as(uid_t uid, gid_t gid, mode_t mode,
+ int exp_errno)
+{
+ create_file_as(uid, gid, mode, 0, 0, exp_errno);
+}
+
+static inline void create_with_umask_as(uid_t uid, gid_t gid, mode_t mode,
+ mode_t mask, int exp_errno)
+{
+ create_file_as(uid, gid, mode, 1, mask, exp_errno);
+}
+
+static inline void cleanup_test_paths(void)
+{
+ SAFE_TRY_UNLINK(TESTSYMLINK);
+ SAFE_TRY_UNLINK(TESTFILE);
+ SAFE_TRY_RMDIR(TESTDIR);
+}
+
+#endif /* HAVE_SYS_XATTR_H */
+
+#endif /* ACL_LIB_H */
diff --git a/testcases/kernel/fs/acl/acl_user_obj01.c b/testcases/kernel/fs/acl/acl_user_obj01.c
new file mode 100644
index 000000000..a442f1131
--- /dev/null
+++ b/testcases/kernel/fs/acl/acl_user_obj01.c
@@ -0,0 +1,126 @@
+// 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 ACL_USER_OBJ permissions using direct xattr manipulation.
+ *
+ * Verify that owner permissions (ACL_USER_OBJ) correctly control access
+ * to files and directories. The test validates that:
+ * - ACL_USER_OBJ permissions are applied directly as the owner bits
+ * - Setting ACL_USER_OBJ=rwx via :manpage:`setxattr(2)` overrides
+ * a previous :manpage:`chmod(2)` restriction
+ * - Owner permissions work independently of group and other permissions
+ *
+ * This test uses arbitrary UIDs without creating actual users, testing
+ * only the kernel ACL implementation.
+ */
+
+#include "acl_lib.h"
+
+#ifdef HAVE_SYS_XATTR_H
+
+#define TEST_UID 1000
+#define TEST_GID 1000
+
+/*
+ * Test permission bits deny access.
+ * Owner should be denied file creation when directory mode is 0555.
+ */
+static void test_deny_by_mode(void)
+{
+ tst_res(TINFO, "Testing permission bits deny access");
+ reset_test_path();
+
+ SAFE_CHOWN(TESTDIR, TEST_UID, TEST_GID);
+ SAFE_CHMOD(TESTDIR, 0555);
+
+ try_create_as(TEST_UID, TEST_GID, 0644, EACCES);
+}
+
+/*
+ * Test ACL_USER_OBJ grants access.
+ * Setting ACL_USER_OBJ=rwx should restore owner write permission and
+ * allow file creation after the restrictive mode baseline.
+ */
+static void test_grant_by_acl(void)
+{
+ struct acl *acl;
+
+ tst_res(TINFO, "Testing ACL_USER_OBJ grants access");
+ reset_test_path();
+
+ SAFE_CHOWN(TESTDIR, TEST_UID, TEST_GID);
+ SAFE_CHMOD(TESTDIR, 0555);
+
+ acl = acl_init();
+
+ acl_add_entry(acl, ACL_USER_OBJ,
+ ACL_READ | ACL_WRITE | ACL_EXECUTE, 0);
+ acl_add_entry(acl, ACL_GROUP_OBJ, 0, 0);
+ acl_add_entry(acl, ACL_OTHER, 0, 0);
+
+ if (acl_set_file(TESTDIR, ACL_TYPE_ACCESS, acl) < 0) {
+ if (errno == EOPNOTSUPP) {
+ acl_free(acl);
+ tst_brk(TCONF | TERRNO, "ACL not supported");
+ }
+ acl_free(acl);
+ tst_brk(TBROK | TERRNO, "ACL setup failed");
+ }
+
+ acl_free(acl);
+
+ try_create_as(TEST_UID, TEST_GID, 0644, 0);
+
+ cleanup_testfile();
+}
+
+static void run(unsigned int n)
+{
+ switch (n) {
+ case 0:
+ test_deny_by_mode();
+ break;
+ case 1:
+ test_grant_by_acl();
+ break;
+ }
+}
+
+static void setup(void)
+{
+ reset_test_path();
+}
+
+static void cleanup(void)
+{
+ cleanup_test_paths();
+}
+
+static struct tst_test test = {
+ .test = run,
+ .tcnt = 2,
+ .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"},
+ {}
+ }
+};
+
+#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:06 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 ` Sachin Sant [this message]
2026-06-13 10:36 ` [LTP] fs/acl: Add ACL_USER_OBJ permission test 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 ` [LTP] [PATCH v8 5/8] fs/acl: Add chmod/chown ACL interaction tests Sachin Sant
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-2-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox