Hi Andreas, Thanks, that clears it up. I was expecting the fd to take precedence after the rename. I understand now that the filename and fd need to refer to the same file, and that Gnulib also needs to support systems without fd-based operations.
So my rename tests were expecting a guarantee these helpers do not provide. Thanks also for letting us know about your existing patch for the acl_*_at functions. Thanks, Eric Cai On Sun, 25 Oct 2026 18:27:59 +0100, Andreas Gruenbacher <[email protected]> wrote: On Sun, Oct 25, 2026 at 2:15 AM <[email protected]> wrote: > Hi Bruno and Andreas, > > Sorry, my previous message was unclear. Here are four separate scenarios. > > I repeated these tests on Linux aarch64, using Gnulib > 8f5547126aedc70a9c2cdb7c63829c87c3d71df1, libacl 2.3.2-2+b1 and > libattr 2.5.2-3, with USE_ACL=1 and USE_XATTR=1. All files and directories > were owned by the same unprivileged user (UID 1000). All supplied file > descriptors were valid positive numbers, except the explicit -1 in case 4. > > For each test, create fresh entries in an otherwise empty directory. > Use these initial ACLs (the numeric user IDs are only test data): > > source access: user::rwx,user:2001:r-x,group::r-x,mask::r-x,other::--- > target/other access: user::rwx,user:2002:rw-,group::r--,mask::rw-,other::--- > source default: user::rwx,user:2003:r--,group::r-x,mask::r-x,other::--- > target/other default: user::rwx,user:2004:rw-,group::r--,mask::rw-,other::--- > > 1. Reading a directory's default ACL > > Steps: Create directories source and other with the ACLs above. Open > source and save its fd and st_mode. Rename source to source-open, then > create the symlink source -> other. Call > get_permissions("source", source_fd, source_mode, &ctx). > > Expected: Both ACLs in ctx come from source-open: access contains user > 2001, and default contains user 2003. > > Actual: The function returns 0. The access ACL contains user 2001, but > the default ACL contains user 2004, from other. source-open still has > default user 2003. gnulib functions like get_permissions() do expect the file to be available under the specified filename and the file descriptor, when it is not -1, to refer to the same file. There is no guarantee that those functions will only use the file descriptor, and there never will be. This is because the gnulib functions are supposed to work on all systems, whether they support file descriptor based operations or not. That being said, I do have a patch around that adds support for the acl_.*_at functions. I should dust that off and send it sometime soon. > 2. Setting a directory's default ACL > > Steps: Create directories source, target and other. Open source and > target. Save source's st_mode and read its ACLs with > get_permissions("source", source_fd, source_mode, &ctx). Then rename > target to target-open and create target -> other. Call > set_permissions(&ctx, "target", target_fd). > > Expected: target-open receives both source ACLs; other is unchanged. > > Actual: The function returns 0. target-open receives access user 2001, > but keeps default user 2004. other receives default user 2003 instead. > > 3. Deleting a directory's default ACL > > Steps: Repeat case 2, but start with no default ACL on source. target > and other still start with the default ACL containing user 2004. > > Expected: target-open has no default ACL after set_permissions; other > keeps its default ACL. > > Actual: The function returns 0. target-open keeps its default ACL, > while other's default ACL is deleted. > > 4. A source pathname with an open destination fd > > Steps: Create regular files source, target and other, using only the > access ACLs above. Save source's st_mode (0100750) and open target. > Rename target to target-open and create target -> other. Call > qcopy_acl("source", -1, "target", target_fd, source_mode). > > Expected, assuming this mixed call is supported: Copy source's access > ACL to target-open through target_fd; leave other unchanged; return 0. > > Actual: return=-1, errno=95 (Operation not supported). target-open still > has user 2002, but its mask has already changed from rw- to r-x. > other is unchanged. This is a failed copy with a partial change, not a > successful copy to other. > > All four tests pass if the names are left unchanged. Case 4 also passes > with the replaced target name when both source and target have valid > positive fds. Applying only the separate fd=0 patch leaves all four > results above unchanged. > > These tests call the helpers directly; they do not demonstrate an > exploit through cp, mv, install, sed or tar. > > Are cases 1-3 expected limitations with this libacl version, or should > Gnulib use the newer libacl APIs when available? Is the mixed call in > case 4 intended to honor the valid destination fd? > > Thanks, > Eric Cai > > > On Sun, 25 Oct 2026 01:01:07 +0200, Bruno Haible <[email protected]> wrote: > > Hi, > > > > Eric Cai wrote: > > > This AI-assisted message is an RFC and test report > > > > I don't understand your message. It uses words like "object", "contract", > > "decoy", "baseline", "blanket". > > > > Please write a message by hand, that humans can understand. Ideally with > > one or more separate "how to reproduce" scenarios. > > > > Also please CC Andreas Gruenbacher. > > > > Bruno Andreas
