Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unprivileged btrfs subvol list #893

Open
wants to merge 7 commits into
base: devel
Choose a base branch
from

Commits on Sep 23, 2024

  1. libbtrfsutil: don't check for UID 0 in subvolume_info()

    btrfs_util_subvolume_info() explicitly checks whether geteuid() == 0 to
    decide whether to use the unprivileged BTRFS_IOC_GET_SUBVOL_INFO ioctl
    or the privileged BTRFS_IOC_TREE_SEARCH ioctl. This breaks in user
    namespaces:
    
      $ unshare -r python3 -c 'import btrfsutil; print(btrfsutil.subvolume_info("/"))'
      Traceback (most recent call last):
        File "<string>", line 1, in <module>
      btrfsutil.BtrfsUtilError: [BtrfsUtilError 12 Errno 1] Could not search B-tree: Operation not permitted: '/'
    
    The unprivileged ioctl has been supported since Linux 4.18. Let's try
    the unprivileged ioctl first, then fall back to the privileged version
    only if it isn't supported.
    
    Signed-off-by: Omar Sandoval <[email protected]>
    osandov authored and maharmstone committed Sep 23, 2024
    Configuration menu
    Copy the full SHA
    4f45b51 View commit details
    Browse the repository at this point in the history
  2. libbtrfsutil: don't check for UID 0 in subvolume iterator

    The subvolume iterator API explicitly checks whether geteuid() == 0 to
    decide whether to use the unprivileged BTRFS_IOC_GET_SUBVOL_ROOTREF and
    BTRFS_IOC_INO_LOOKUP_USER ioctls or the privileged BTRFS_IOC_TREE_SEARCH
    ioctl. This breaks in user namespaces:
    
      $ unshare -r python3 -c 'import btrfsutil; print(list(btrfsutil.SubvolumeIterator("/home")))'
      Traceback (most recent call last):
        File "<string>", line 1, in <module>
      btrfsutil.BtrfsUtilError: [BtrfsUtilError 12 Errno 1] Could not search B-tree: Operation not permitted
    
    Instead of the explicit check, let's try the privileged mode first, and
    if it fails with a permission error, fall back to the unprivileged mode
    (which has been supported since Linux 4.18). Note that we have to try
    the privileged mode first, since even for privileged users, the
    unprivileged mode may omit some subvolumes that are hidden by filesystem
    mounts.
    
    Signed-off-by: Omar Sandoval <[email protected]>
    osandov authored and maharmstone committed Sep 23, 2024
    Configuration menu
    Copy the full SHA
    0b04cb0 View commit details
    Browse the repository at this point in the history
  3. btrfs-progs: subvol list: remove unused raw layout code

    It hasn't been used since commit 9005b60 ("btrfs-progs: use
    libbtrfsutil for subvol show").
    
    Signed-off-by: Omar Sandoval <[email protected]>
    osandov authored and maharmstone committed Sep 23, 2024
    Configuration menu
    Copy the full SHA
    6df7d8f View commit details
    Browse the repository at this point in the history
  4. btrfs-progs: subvol list: remove unused filters

    BTRFS_LIST_FILTER_ROOTID hasn't been used since commit 9e73a41
    ("btrfs-progs: use libbtrfsutil for get-default"), and
    BTRFS_LIST_FILTER_BY_PARENT hasn't been used since commit 9005b60
    ("btrfs-progs: use libbtrfsutil for subvol show").
    
    Signed-off-by: Omar Sandoval <[email protected]>
    osandov authored and maharmstone committed Sep 23, 2024
    Configuration menu
    Copy the full SHA
    7bb99cf View commit details
    Browse the repository at this point in the history
  5. btrfs-progs: subvol list: document and test actual behavior of paths

    The way btrfs subvol list prints paths and what the -o and -a flags do
    are all nonsense.
    
    Apparently, very early versions of Btrfs had a concept of a "top level"
    of subvolumes rather than the root filesystem tree that we have today;
    see commit 4ff9e2a ("Add btrfs-list for listing subvolumes"). The
    original subvol list code tracked the ID of that top level subvolume.
    Eventually, 5 became the only possibility for the top level, and -o, -a,
    and path printing were based on that. Commit 4f5ebb3 ("Btrfs-progs:
    fix to make list specified directory's subvolumes work") broke this and
    changed the top level to be the same as the parent subvolume ID, which
    gave us the illogical behavior we have today.
    
    It has been this way for a decade, so we're probably stuck with it. But
    let's at least document precisely what these all do in preparation for
    adding sensible options. Let's also add tests in preparation for the
    upcoming changes.
    
    Signed-off-by: Omar Sandoval <[email protected]>
    osandov authored and maharmstone committed Sep 23, 2024
    Configuration menu
    Copy the full SHA
    7115841 View commit details
    Browse the repository at this point in the history
  6. btrfs-progs: subvol list: use libbtrfsutil

    btrfs subvol list has its own subvolume walking implementation that we
    can replace with a libbtrfsutil subvolume iterator. Most of the changed
    lines are removing the old implementation and mechanically updating the
    comparators, filters, and printers to use libbtrfsutil's subvolume info.
    The interesting parts are:
    
    1. We can replace the red-black tree of subvolumes with an array that we
       qsort.
    2. Listing deleted subvolumes needs a different codepath, but we don't
       need a filter for it anymore.
    3. We need some hacks to maintain the weird path behavior documented in
       the previous commit.
    
    In addition to removing a bunch of redundant code, this also prepares us
    for allowing subvol list by unprivileged users in some cases.
    
    Signed-off-by: Omar Sandoval <[email protected]>
    osandov authored and maharmstone committed Sep 23, 2024
    Configuration menu
    Copy the full SHA
    44576c9 View commit details
    Browse the repository at this point in the history
  7. btrfs-progs: subvol list: add sane -O and -A options

    Now that we've documented the current nonsensical behavior, add a couple
    of options that actually make sense: -O lists all subvolumes below a
    path (which is what people think -o does), and -A lists all subvolumes
    with no path munging (which is what people think the default or -a do).
    -O can even be used by unprivileged users.
    
    -O and -A also renames the "top level" in the default output to what it
    actually is now: the "parent".
    
    Signed-off-by: Omar Sandoval <[email protected]>
    osandov authored and maharmstone committed Sep 23, 2024
    Configuration menu
    Copy the full SHA
    7b163f6 View commit details
    Browse the repository at this point in the history