acl_* API in presence of NFSv4-branded ACLs

From: Gleb Popov <>
Date: Sat, 31 Jul 2021 20:27:58 UTC
Hello hackers.

While working on some Linux code that uses acl_* functions it turned out
that some of them are failing for NFSv4-branded ACLs we have in FreeBSD.
This looks correct in theory, as NFSv4 ACLs are not part of POSIX 1e, but
in practice there is some software that assumes that "no POSIX ALCs" == "no
ACLs at all".

For instance, [1]:

    acl_t acl = acl_get_file(, ACL_TYPE_ACCESS);
    if (acl || defaultAcl) {
    // some work on acl

On FreeBSD when run on an NFSv4-branded file, the `acl_get_file` returns
NULL, which makes the code believe that the file has no ACL at all. I
worked this around by trying `acl_get_file` with ACL_TYPE_NFS4 first, and
retrying with ACL_TYPE_ACCESS in case of failure.

Another, more complicated example [2]:

    acl_t temp = acl_from_text(aclStr.toLatin1().constData());
    if (acl_valid(temp) != 0) {
        // error out
    } else {
       // do useful things with temp

Reading NFSv4-branded ACL succeeds in `acl_from_text`, however, passing it
into `acl_valid` results in failure, because it works only on POSIX-branded
ACLs. I worked this around by checking the brand with `acl_get_brand_np`
and shortcutting to 0 in !POSIX case.

For both these examples I'm interested if my workarounds seem sane. Maybe
something needs to be changed in our libc, instead?

Thanks in advance.