When setting the NT ACL vfs_acl_xattr will wipe an existing NT ACL xattr in the sys_acl_set_file_xattr().
We do three things in the code that handles setting the ACL:
- first we set the POSIX ACL
- as part of that, we remove the NT ACL xattr
- then we set the new NT ACL xattr via
The problem is, if we hit ENOSPC in the last step, we have deleted the NT ACL xattr in the step before.
The code that deletes the NT ACL xattr is from 2008 and predates the new version 4 from 2012 of the ACL xattr that stores the hash of the filesystem POSIX ACL.
If all ACL xattr blob on a system contain the that hash, it's safe to skip deleting the ACL xattr when setting the POSIX ACL. But as systems may contain data with older versions, we cannot unconditionally remove that code.
The correct fix for this is to use a fsp extension in the module to transfer the knowledge across the codepath, that it's safe to skip the removal. That however requires an fsp and so doesn't work in the path based SMB_VFS_SYS_ACL_SET_FILE().
With the upcoming O_PATH changes it will be possible to change all callers of SMB_VFS_SYS_ACL_SET_FILE() to use the handle based SMB_VFS_SYS_ACL_SET_FD() instead. So once the O_PATH code hits master, I can do this change and then add the fsp extension logic.
This bug was referenced in samba master:
Fixed in master for 4.14.