@@ -58,6 +58,50 @@ typedef enum monitored_t {
5858// For the time being we just keep a char.
5959typedef char inode_value_t ;
6060
61+ // Generic xattr values are capped at XATTR_SIZE_MAX (64KiB), which bounds
62+ // a POSIX ACL xattr (4 byte header + 8 bytes per entry) to ~8191 entries
63+ // in theory:
64+ // https://github.com/torvalds/linux/blob/d2c9a99135da931377240942d44f3dea104cedb8/include/uapi/linux/limits.h#L16
65+ // In practice, individual filesystems impose much lower limits tied to
66+ // their own xattr/block storage (e.g. ext4 caps out in the low hundreds
67+ // for a typical 4K xattr block). 32 comfortably covers real-world ACLs
68+ // (a handful of named users/groups plus the standard entries); raise it
69+ // if we ever see it hit in practice.
70+ #define FACT_MAX_ACL_ENTRIES 32
71+
72+ // Sentinel used by the kernel for ACL entries that don't carry a uid/gid
73+ // (USER_OBJ, GROUP_OBJ, MASK, OTHER). Kernel defines this as (-1), which
74+ // is 0xFFFFFFFF once read as the unsigned e_id we store it in.
75+ // https://github.com/torvalds/linux/blob/d2c9a99135da931377240942d44f3dea104cedb8/include/uapi/linux/posix_acl.h#L21
76+ #define ACL_UNDEFINED_ID 0xFFFFFFFF
77+
78+ // ACL type, matching the xattr name the change came in on:
79+ // "system.posix_acl_access" vs "system.posix_acl_default". These are the
80+ // only two POSIX ACL xattrs the kernel supports, so a small enum is
81+ // sufficient here rather than keeping the full xattr name around.
82+ typedef enum acl_type_t {
83+ FACT_ACL_TYPE_ACCESS = 0 ,
84+ FACT_ACL_TYPE_DEFAULT = 1 ,
85+ } acl_type_t ;
86+
87+ // Mirrors the kernel's ACL tag bit values so we can encode/compare
88+ // against them without magic numbers, both here and on the Rust side.
89+ // https://github.com/torvalds/linux/blob/d2c9a99135da931377240942d44f3dea104cedb8/include/uapi/linux/posix_acl.h#L28-L33
90+ typedef enum acl_tag_t {
91+ FACT_ACL_TAG_USER_OBJ = 0x01 ,
92+ FACT_ACL_TAG_USER = 0x02 ,
93+ FACT_ACL_TAG_GROUP_OBJ = 0x04 ,
94+ FACT_ACL_TAG_GROUP = 0x08 ,
95+ FACT_ACL_TAG_MASK = 0x10 ,
96+ FACT_ACL_TAG_OTHER = 0x20 ,
97+ } acl_tag_t ;
98+
99+ struct acl_entry_t {
100+ acl_tag_t e_tag ;
101+ unsigned short e_perm ;
102+ unsigned int e_id ;
103+ };
104+
61105typedef enum file_activity_type_t {
62106 FILE_ACTIVITY_INIT = -1 ,
63107 FILE_ACTIVITY_OPEN = 0 ,
@@ -70,6 +114,7 @@ typedef enum file_activity_type_t {
70114 DIR_ACTIVITY_UNLINK ,
71115 FILE_ACTIVITY_SETXATTR ,
72116 FILE_ACTIVITY_REMOVEXATTR ,
117+ FILE_ACTIVITY_ACL_SET ,
73118} file_activity_type_t ;
74119
75120struct event_t {
@@ -99,6 +144,11 @@ struct event_t {
99144 struct {
100145 char name [XATTR_NAME_MAX_LEN ];
101146 } xattr ;
147+ struct {
148+ unsigned int count ;
149+ acl_type_t acl_type ;
150+ struct acl_entry_t entries [FACT_MAX_ACL_ENTRIES ];
151+ } acl ;
102152 };
103153};
104154
@@ -143,4 +193,5 @@ struct metrics_t {
143193 struct metrics_by_hook_t path_rmdir ;
144194 struct metrics_by_hook_t inode_setxattr ;
145195 struct metrics_by_hook_t inode_removexattr ;
196+ struct metrics_by_hook_t inode_set_acl ;
146197};
0 commit comments