[PATCH] setpriv: remove dependency on libcap headers

Patrick Steinhardt ps at pks.im
Fri Jul 7 17:20:01 UTC 2017


On Fri, Jul 07, 2017 at 06:00:45PM +0200, Denys Vlasenko wrote:
> On Fri, Jul 7, 2017 at 3:40 PM, Patrick Steinhardt <ps at pks.im> wrote:
> > The setpriv applet is including <sys/capability.h> for the capget(2) and
> > capset(2) functions. Unfortunately, this header is not provided by
> > linux-headers, but by libcap instead, which requires users to have them
> > installed. As these functions are not actually implemented by libcap
> > itself but instead provided by the libc, no additional linking is
> > required and as such the depenency went by unnoticed.
> >
> > To get rid of this requirement, we can instead use a direct syscall.
> > Taking a look at musl libc's implementation of these funcitions, they
> > are direct wrappers to `syscall(SYS_capset, ...)` and
> > `syscall(SYS_capget, ...)`. As such, it is trivial to reimplement them
> > ourselves via syscall(2).
> >
> > function                                             old     new   delta
> > getcaps                                              230     246     +16
> > setpriv_main                                        1260    1266      +6
> 
> Evidently, this is not the same, since code size increased.
> 
> I'm going with this instead:
> 
> // #include <sys/capability.h>
> // This header is in libcap, but the functions are in libc.
> // Comment in the header says this above capset/capget:
> /* system calls - look to libc for function to system call mapping */
> extern int capset(cap_user_header_t header, cap_user_data_t data);
> extern int capget(cap_user_header_t header, const cap_user_data_t data);
> // so for bbox, let's just repeat the declarations.
> // This way, libcap needs not be installed in build environment.

It is not, that's correct, as we're calling `syscall` directly
instead of `capset` with my solution. But functionality-wise, it
is in fact the same. From musl libc, for example:

    int capset(void *a, void *b)
    {
        return syscall(SYS_capset, a, b);
    }

    int capget(void *a, void *b)
    {
        return syscall(SYS_capget, a, b);
    }

But your solution is fine, as well, and as it's smaller I guess
that wins it for busybox.

Regards
Patrick
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.busybox.net/pipermail/busybox/attachments/20170707/0ef6f466/attachment.asc>


More information about the busybox mailing list