on Ubuntu 26.04 and 26.10, with
ls --version
ls (uutils coreutils) 0.8.0
ls -dl <link> returns the ACL bit ( + ) from the referenced inode rather than the link itself. This is reproducible with the following
# ensure acl is installed
sudo apt update && sudo apt install acl
umask 022
mkdir d
setfacl -m d:u:bin:rwx d
ln -s d l
ls -dl l
> lrwxrwxrwx+ 1 root root 1 Jun 30 11:17 l -> d
This mimics the behaviour of passing in -L , which appropriately dereferences. Compare to a system running gnu-coreutils (such as debian/unstable)
ls --version
> ls (GNU coreutils) 9.10
> Packaged by Debian (9.10-1)
sudo apt update && sudo apt install acl
umask 022
mkdir d
setfacl -m d:u:bin:rwx d
ln -s d l
ls -dl l
lrwxrwxrwx 1 root root 1 Jun 30 11:16 l -> d
root cause and call chain
From entry to calls :
uumain(args)
|-> ls.rs:119 -- ls entrypoint
|-> ls.rs:122 -- sets config. Correctly sets config for -dl to Dereference::None and Format::Long
|-> ls.rs:128 -- list(locs, &config) with correct config
|-> ls.rs:1470-1471 -- TextOuput created and list_with_output called with correct config
|-> ls.rs:1180 -- for each location, call PathData::new with correct config. the PathData sets must_dereference=false
|-> ls.rs:821-914 -- PathData implementation. fn metadata
|-> ls.rs: 923 -- get_metadata_with_deref_opt correctly gets symlink metadata at ls.rs:1547
# so at this point, we've collected the correct metadata from [std::fs.symlink_metadata](https://doc.rust-lang.org/std/fs
# fn.symlink_metadata.html). onto long-format
|-> ls.rs:1217 -- not in stream mode, will call output.write_entries
|-> ls.rs:1071 -- calls display_items with all entries and passes config (same config with Dereference::None)
|-> display.rs:377 -- config.format matches, drops into calculate_padding_collection
|-> display.rs:1342 -- for each item, a call to `has_acl(item.path()`
|-> uucore/src/lib/fsxattr.rs:164 -- has_acl only takes a path. Always calls xattr::list_deref(file)
# BUG HIT ONE
|-> display.rs:389 -- then each item calls display_long_item with item and config
|-> display.rs:937 -- in display_item_long another call to has_acl
# BUG HIT TWO
at this point we've made a couple calls to has_acl, a function that doesn't accept configuration for deferencing. So a couple possible bugs
- padding may be set incorrectly due to incorrect
acl assumption
- long display will show an
acl that is not present in the item metadata
My gut is that there is a bigger root here -- it looks like in display.rs has other calls that are similar. It seems like there's duplication in calls, where instead of referencing the metadata there are calls to get the information again. The simple fix is for has_acl to have a switch but that does not feel like the correct approach. it's a quick fix, but getting into the broader architectural issue of a) either not using metadata that's present or; b) not having all the metadata and therefore querying for it in display.rs.
on Ubuntu 26.04 and 26.10, with
ls -dl <link>returns the ACL bit (+) from the referenced inode rather than the link itself. This is reproducible with the followingThis mimics the behaviour of passing in -L , which appropriately dereferences. Compare to a system running gnu-coreutils (such as debian/unstable)
root cause and call chain
From entry to calls :
at this point we've made a couple calls to
has_acl, a function that doesn't accept configuration for deferencing. So a couple possible bugsaclassumptionaclthat is not present in the item metadataMy gut is that there is a bigger root here -- it looks like in
display.rshas other calls that are similar. It seems like there's duplication in calls, where instead of referencing themetadatathere are calls to get the information again. The simple fix is forhas_aclto have a switch but that does not feel like the correct approach. it's a quick fix, but getting into the broader architectural issue of a) either not using metadata that's present or; b) not having all the metadata and therefore querying for it indisplay.rs.