mbox series

[RFC,v2,0/4] btrfs-progs: build distinct binaries for specific btrfs subcommands

Message ID 20180912144604.6178-1-axel@tty0.ch (mailing list archive)
Headers show
Series btrfs-progs: build distinct binaries for specific btrfs subcommands | expand

Message

Axel Burri Sept. 12, 2018, 2:46 p.m. UTC
This patch allows to build distinct binaries for specific btrfs
subcommands, e.g. "btrfs-subvolume-show" which would be identical to
"btrfs subvolume show".

Changes from v1 [1]:

 - No more need of generated c-file for each separated commands (all
   functionality has moved to Makefile).

 - More generic approach: match entry point declarations as well as
   additional tage in all "cmds-*.c" files.

 - Change naming: use "separated" instead of "splitcmd".


Motivation:

While btrfs-progs offer the all-inclusive "btrfs" command, it gets
pretty cumbersome to restrict privileges to the subcommands [2].
Common approaches are to either setuid root for "/sbin/btrfs" (which
is not recommended at all), or to write sudo rules for each
subcommand.

Separating the subcommands into distinct binaries makes it easy to set
elevated privileges using capabilities(7) or setuid. A typical use
case where this is needed is when it comes to automated scripts,
e.g. btrbk [3] [4] creating snapshots and send/receive them via ssh.


Description:

Patch 1 adds a minimal, non-invasive framework for building separated
binaries. Note that some subcommands fail to build ("make -k separated").

Patches 2,3 fix build dependencies: make all subcommands build
correctly, with smaller binary size. Probably to be squashed into
patch 1 for final commit.

Patch 4 adds configuration options -enable-setcap-install,
--enable-setuid-install, --enable-btrfs-separated.


Notes:

 - This patchset is available on github [5].

 - A gentoo ebuild "sys-fs/btrfs-progs-separated" is available on
   github [6], as well as in the digint-overlay [7]:

    USE=filecaps emerge -av sys-fs/btrfs-progs-separated


References:

  [1] https://www.spinics.net/lists/linux-btrfs/msg81451.html
  [2] https://www.spinics.net/lists/linux-btrfs/msg75736.html
  [3] https://github.com/digint/btrbk
  [4] https://github.com/digint/btrfs-progs-btrbk
  [5] https://github.com/digint/btrfs-progs/tree/cmds-separated-fscaps-v2
  [6] https://github.com/digint/gentoo/tree/btrfs-progs-separated/sys-fs/btrfs-progs-separated
  [7] https://dev.tty0.ch/portage/digint-overlay.git


Axel Burri (4):
  btrfs-progs: Makefile: create separated binaries for "btrfs"
    subcommands; add fscaps declarations
  btrfs-progs: remove unneeded dependencies on separated build
    (-DBTRFS_SEPARATED_BUILD)
  btrfs-progs: Makefile: add extra objects definitions for separated
    binaries
  btrfs-progs: build: add --enable-setcap-install,
    --enable-setuid-install, --enable-btrfs-separated

 .gitignore        |  1 +
 Makefile          | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 Makefile.inc.in   |  6 ++++
 cmds-balance.c    |  2 ++
 cmds-device.c     |  2 ++
 cmds-fi-usage.c   |  1 +
 cmds-filesystem.c |  2 ++
 cmds-inspect.c    |  2 ++
 cmds-property.c   |  2 ++
 cmds-qgroup.c     |  3 ++
 cmds-quota.c      |  2 ++
 cmds-receive.c    |  1 +
 cmds-replace.c    |  2 ++
 cmds-rescue.c     |  2 ++
 cmds-scrub.c      |  2 ++
 cmds-send.c       |  1 +
 cmds-subvolume.c  |  6 ++++
 commands.h        | 37 +++++++++++++++++++++
 configure.ac      | 40 ++++++++++++++++++++++
 19 files changed, 212 insertions(+), 1 deletion(-)

Comments

Axel Burri Sept. 19, 2018, 10:02 p.m. UTC | #1
In Reply to:

On 30/08/2018 04.38, Misono Tomohiro wrote:
>
> Hello,
>
> Not directly related this series and just FYI,
> I'm working to allow sub show/list to non-privileged user as long
> as he can access to the subvolume:
>   https://www.spinics.net/lists/linux-btrfs/msg79285.html
>
> Hopefully this will be merged to master in near future
> (any comments from user/dev is welcome).
>
> Thanks,
> Misono
>

I found some time to play around with your patchset, it worked fine on
4.18.8-gentoo kernel.

As far as I can see, only "btrfs subvolume show" and "btrfs subvolume
list" makes sense for a regular user?

With the "cmds-separated-fscaps-v2" patchset [1], you can build
separated binaries as follows:

    # make btrfs-subvolume-list.separated
    # make btrfs-subvolume-show.separated

Now not everybody wants to install these with fscaps or setuid, but it
might also make sense to provide "/usr/bin/btrfs-subvolume-{show,list}",
as they now work for a regular user. Having both root/user binaries
concurrently is not an issue (e.g. in gentoo the full-featured btrfs
command is in "/sbin/").

Last time I checked, debian installs it to "/bin/btrfs", which from my
perspective seems to be the preferred location as soon as Misonos patch
is merged.

 [1] https://github.com/digint/btrfs-progs/tree/cmds-separated-fscaps-v2
Duncan Sept. 20, 2018, 8:32 a.m. UTC | #2
Axel Burri posted on Thu, 20 Sep 2018 00:02:22 +0200 as excerpted:

> Now not everybody wants to install these with fscaps or setuid, but it
> might also make sense to provide "/usr/bin/btrfs-subvolume-{show,list}",
> as they now work for a regular user. Having both root/user binaries
> concurrently is not an issue (e.g. in gentoo the full-featured btrfs
> command is in "/sbin/").

That's going to be a problem for distros (or users like me with advanced 
layouts, on gentoo too FWIW) that have the bin/sbin merge, where one is a 
symlink to the other.

FWIW I have both the /usr merge (tho reversed for me, so /usr -> . 
instead of having to have /bin and /sbin symlinks to /usr/bin) and the 
bin/sbin merge, along with, since I'm on amd64-nomultilib, the lib/lib64 
merge.  So:

$$ dir -gGd /bin /sbin /usr /lib /lib64
drwxr-xr-x 1 35688 Sep 18 22:56 /bin
lrwxrwxrwx 1     5 Aug  7 00:29 /lib -> lib64
drwxr-xr-x 1 78560 Sep 18 22:56 /lib64
lrwxrwxrwx 1     3 Mar 11  2018 /sbin -> bin
lrwxrwxrwx 1     1 Mar 11  2018 /usr -> .


Of course that last one (/usr -> .) leads to /share and /include hanging 
directly off of / as well, but it works.

But in that scheme /bin, /sbin, /usr/bin and /usr/sbin, are all the same 
dir, so only one executable of a particularly name can exist therein.
Axel Burri Sept. 21, 2018, 9:46 a.m. UTC | #3
On 20/09/2018 10.32, Duncan wrote:
> Axel Burri posted on Thu, 20 Sep 2018 00:02:22 +0200 as excerpted:
> 
>> Now not everybody wants to install these with fscaps or setuid, but it
>> might also make sense to provide "/usr/bin/btrfs-subvolume-{show,list}",
>> as they now work for a regular user. Having both root/user binaries
>> concurrently is not an issue (e.g. in gentoo the full-featured btrfs
>> command is in "/sbin/").
> 
> That's going to be a problem for distros (or users like me with advanced 
> layouts, on gentoo too FWIW) that have the bin/sbin merge, where one is a 
> symlink to the other.

I think you got me wrong here: There will not be binaries with the same
filename. I totally agree that this would be a bad thing, no matter if
you have bin/sbin merged or not, you'll end up in either having a
collision or (even worse) rely on the order in $PATH.

With this "separated" patchset, you can install a binary
"btrfs-subvolume-show", which has the same functionality as "btrfs
subvolume show" (note the whitespace/dash), ending up with:

    /sbin/btrfs
    /usr/bin/btrfs-subvolume-show
    /usr/bin/btrfs-subvolume-list

thus allowing a user to run "btrfs-subvolume-show" while "btrfs" is
still only visible for root. With /usr merge it would look like this:

    /bin/btrfs
    /bin/btrfs-subvolume-show
    /bin/btrfs-subvolume-list


What I'm thinking of is a distro package which installs the separated
binaries, either with suid/fscaps (if the admin wants to provide their
users with non-restricted versions of specific commands), or without
special flags (if the admin wants to just provide the binaries that also
work for non-root user, enabled by Misono's patchset.

See my gentoo ebuild:
https://github.com/digint/gentoo/tree/btrfs-progs-separated/sys-fs/btrfs-progs-separated


> 
> FWIW I have both the /usr merge (tho reversed for me, so /usr -> . 
> instead of having to have /bin and /sbin symlinks to /usr/bin) and the 
> bin/sbin merge, along with, since I'm on amd64-nomultilib, the lib/lib64 
> merge.  So:
> 
> $$ dir -gGd /bin /sbin /usr /lib /lib64
> drwxr-xr-x 1 35688 Sep 18 22:56 /bin
> lrwxrwxrwx 1     5 Aug  7 00:29 /lib -> lib64
> drwxr-xr-x 1 78560 Sep 18 22:56 /lib64
> lrwxrwxrwx 1     3 Mar 11  2018 /sbin -> bin
> lrwxrwxrwx 1     1 Mar 11  2018 /usr -> .
> 
> 
> Of course that last one (/usr -> .) leads to /share and /include hanging 
> directly off of / as well, but it works.
> 
> But in that scheme /bin, /sbin, /usr/bin and /usr/sbin, are all the same 
> dir, so only one executable of a particularly name can exist therein.
>
Duncan Sept. 22, 2018, 5:57 a.m. UTC | #4
Axel Burri posted on Fri, 21 Sep 2018 11:46:37 +0200 as excerpted:

> I think you got me wrong here: There will not be binaries with the same
> filename. I totally agree that this would be a bad thing, no matter if
> you have bin/sbin merged or not, you'll end up in either having a
> collision or (even worse) rely on the order in $PATH.
> 
> With this "separated" patchset, you can install a binary
> "btrfs-subvolume-show", which has the same functionality as "btrfs
> subvolume show" (note the whitespace/dash), ending up with:
> 
>     /sbin/btrfs
>     /usr/bin/btrfs-subvolume-show
>     /usr/bin/btrfs-subvolume-list

I did get you wrong (and had even understood the separately named 
binaries from an earlier post, too, but forgot).

Thanks. =:^)