How can a macOS application establish that an open APFS file has no extended ACL?

On macOS 26.5.2 (build 25F84), which documented API and return conditions, if any, establish that a regular file on APFS has no extended access control list (ACL), using an already-open file descriptor?

We tested three disposable regular files on an APFS volume reporting ACL support.

For each file, we opened a read-only file descriptor and called:

  • acl_get_fd_np(fd, ACL_TYPE_EXTENDED)
  • fgetattrlist() requesting ATTR_CMN_RETURNED_ATTRS | ATTR_CMN_EXTENDED_SECURITY

Before and after inspection, fstat() confirmed stable device, inode, mode, and change timestamp.

Observed results:

1. Newly created file, no ACL explicitly assigned

  • acl_get_fd_np() returned NULL with errno == ENOENT.
  • fgetattrlist() succeeded but omitted ATTR_CMN_EXTENDED_SECURITY from the returned attribute mask.
  • FSOPT_PACK_INVAL_ATTRS also left that bit clear.

2. File with an explicitly assigned empty ACL

  • acl_get_fd_np() returned NULL with errno == ENOENT.
  • fgetattrlist() returned the extended-security attribute with an ACL entry count of zero.

3. File with one explicit ACL entry

  • acl_get_fd_np() returned a non-null ACL.
  • fgetattrlist() returned the extended-security attribute with an ACL entry count of one.

Apple's published XNU attribute-packing implementation appears to use the same omission branch when ACL metadata is unsupported or when the ACL pointer is null.

My question:

Is there a supported descriptor-based API sequence that reliably distinguishes:

  1. Genuine absence of an extended ACL
  2. Unavailable or unsupported per-file ACL metadata
  3. An ACL retrieval failure

If so, which API, capability checks, return values, attribute bits, or error conditions should a caller rely on?

Are there relevant APFS or macOS version limitations?

If the public API cannot establish ACL absence unambiguously in this situation, confirmation of that limitation would also be helpful.

Thank you for your guidance.

Answered by DTS Engineer in 914933022

Is there a supported descriptor-based API sequence that reliably distinguishes:

I'm a bit confused by your question, as it seems to like fgetattrlist is doing exactly what you want, since it returned a distinct result in all three cases. I'll note that for this case:

An ACL retrieval failure

acl_get_fd_np should return "EACCES".

when ACL metadata is unsupported

If you want to check for ACL support, you can check the VOL_CAP_INT_EXTENDED_SECURITY bit of the vol_capabilities_attr_t returned ATTR_VOL_CAPABILITIES in fgetattrlist.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Accepted Answer

Is there a supported descriptor-based API sequence that reliably distinguishes:

I'm a bit confused by your question, as it seems to like fgetattrlist is doing exactly what you want, since it returned a distinct result in all three cases. I'll note that for this case:

An ACL retrieval failure

acl_get_fd_np should return "EACCES".

when ACL metadata is unsupported

If you want to check for ACL support, you can check the VOL_CAP_INT_EXTENDED_SECURITY bit of the vol_capabilities_attr_t returned ATTR_VOL_CAPABILITIES in fgetattrlist.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Thank you, Kevin. That is very helpful.

Just to confirm the precise fail-closed condition: if the volume reports VOL_CAP_INT_EXTENDED_SECURITY as both valid and supported, fgetattrlist() succeeds on a stable file descriptor, but the returned attribute mask omits ATTR_CMN_EXTENDED_SECURITY, can we reliably interpret that as the file having no extended ACL?

Or could this combination still indicate unavailable per-file ACL metadata?

We want to avoid treating an unsupported or indeterminate state as confirmed ACL absence.

Thank you again for clarifying.