From: Corey Bryant <coreyb@linux.vnet.ibm.com>
To: Blue Swirl <blauwirbel@gmail.com>
Cc: rmarwah@linux.vnet.ibm.com, aliguori@us.ibm.com, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH v2 3/4] Add cap reduction support to enable use as SUID
Date: Mon, 24 Oct 2011 15:13:41 -0400 [thread overview]
Message-ID: <4EA5B8E5.6040306@linux.vnet.ibm.com> (raw)
In-Reply-To: <CAAu8pHvkc_FsE-5HODFxqxQjEDDHYATtq9uSLNgdc=VmeS91pg@mail.gmail.com>
On 10/24/2011 02:58 PM, Blue Swirl wrote:
> On Mon, Oct 24, 2011 at 18:38, Corey Bryant<coreyb@linux.vnet.ibm.com> wrote:
>>
>>
>> On 10/24/2011 01:10 PM, Blue Swirl wrote:
>>>
>>> On Mon, Oct 24, 2011 at 14:13, Corey Bryant<coreyb@linux.vnet.ibm.com>
>>> wrote:
>>>>
>>>>
>>>> On 10/23/2011 09:22 AM, Blue Swirl wrote:
>>>>>
>>>>> On Fri, Oct 21, 2011 at 15:07, Corey Bryant<coreyb@linux.vnet.ibm.com>
>>>>> wrote:
>>>>>>
>>>>>> The ideal way to use qemu-bridge-helper is to give it an fscap of
>>>>>> using:
>>>>>>
>>>>>> setcap cap_net_admin=ep qemu-bridge-helper
>>>>>>
>>>>>> Unfortunately, most distros still do not have a mechanism to package
>>>>>> files
>>>>>> with fscaps applied. This means they'll have to SUID the
>>>>>> qemu-bridge-helper
>>>>>> binary.
>>>>>>
>>>>>> To improve security, use libcap to reduce our capability set to just
>>>>>> cap_net_admin, then reduce privileges down to the calling user. This
>>>>>> is
>>>>>> hopefully close to equivalent to fscap support from a security
>>>>>> perspective.
>>>>>>
>>>>>> Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>
>>>>>> Signed-off-by: Richa Marwaha<rmarwah@linux.vnet.ibm.com>
>>>>>> Signed-off-by: Corey Bryant<coreyb@linux.vnet.ibm.com>
>>>>>> ---
>>>>>> configure | 34 ++++++++++++++++++++++++++++++++++
>>>>>> qemu-bridge-helper.c | 39 +++++++++++++++++++++++++++++++++++++++
>>>>>> 2 files changed, 73 insertions(+), 0 deletions(-)
>>>>>>
>>>>>> diff --git a/configure b/configure
>>>>>> index 6c8b659..fed66b0 100755
>>>>>> --- a/configure
>>>>>> +++ b/configure
>>>>>> @@ -128,6 +128,7 @@ vnc_thread="no"
>>>>>> xen=""
>>>>>> xen_ctrl_version=""
>>>>>> linux_aio=""
>>>>>> +cap=""
>>>>>> attr=""
>>>>>> xfs=""
>>>>>>
>>>>>> @@ -653,6 +654,10 @@ for opt do
>>>>>> ;;
>>>>>> --enable-kvm) kvm="yes"
>>>>>> ;;
>>>>>> + --disable-cap) cap="no"
>>>>>> + ;;
>>>>>> + --enable-cap) cap="yes"
>>>>>> + ;;
>>>>>> --disable-spice) spice="no"
>>>>>> ;;
>>>>>> --enable-spice) spice="yes"
>>>>>> @@ -1032,6 +1037,8 @@ echo " --disable-vde disable support
>>>>>> for vde network"
>>>>>> echo " --enable-vde enable support for vde network"
>>>>>> echo " --disable-linux-aio disable Linux AIO support"
>>>>>> echo " --enable-linux-aio enable Linux AIO support"
>>>>>> +echo " --disable-cap disable libcap-ng support"
>>>>>> +echo " --enable-cap enable libcap-ng support"
>>>>>> echo " --disable-attr disables attr and xattr support"
>>>>>> echo " --enable-attr enable attr and xattr support"
>>>>>> echo " --disable-blobs disable installing provided firmware
>>>>>> blobs"
>>>>>> @@ -1638,6 +1645,29 @@ EOF
>>>>>> fi
>>>>>>
>>>>>> ##########################################
>>>>>> +# libcap-ng library probe
>>>>>> +if test "$cap" != "no" ; then
>>>>>> + cap_libs="-lcap-ng"
>>>>>> + cat> $TMPC<< EOF
>>>>>> +#include<cap-ng.h>
>>>>>> +int main(void)
>>>>>> +{
>>>>>> + capng_capability_to_name(CAPNG_EFFECTIVE);
>>>>>> + return 0;
>>>>>> +}
>>>>>> +EOF
>>>>>> + if compile_prog "" "$cap_libs" ; then
>>>>>> + cap=yes
>>>>>> + libs_tools="$cap_libs $libs_tools"
>>>>>> + else
>>>>>> + if test "$cap" = "yes" ; then
>>>>>> + feature_not_found "cap"
>>>>>> + fi
>>>>>> + cap=no
>>>>>> + fi
>>>>>> +fi
>>>>>> +
>>>>>> +##########################################
>>>>>> # Sound support libraries probe
>>>>>>
>>>>>> audio_drv_probe()
>>>>>> @@ -2735,6 +2765,7 @@ echo "fdatasync $fdatasync"
>>>>>> echo "madvise $madvise"
>>>>>> echo "posix_madvise $posix_madvise"
>>>>>> echo "uuid support $uuid"
>>>>>> +echo "libcap-ng support $cap"
>>>>>> echo "vhost-net support $vhost_net"
>>>>>> echo "Trace backend $trace_backend"
>>>>>> echo "Trace output file $trace_file-<pid>"
>>>>>> @@ -2846,6 +2877,9 @@ fi
>>>>>> if test "$vde" = "yes" ; then
>>>>>> echo "CONFIG_VDE=y">> $config_host_mak
>>>>>> fi
>>>>>> +if test "$cap" = "yes" ; then
>>>>>> + echo "CONFIG_LIBCAP=y">> $config_host_mak
>>>>>> +fi
>>>>>> for card in $audio_card_list; do
>>>>>> def=CONFIG_`echo $card | tr '[:lower:]' '[:upper:]'`
>>>>>> echo "$def=y">> $config_host_mak
>>>>>> diff --git a/qemu-bridge-helper.c b/qemu-bridge-helper.c
>>>>>> index db257d5..b1562eb 100644
>>>>>> --- a/qemu-bridge-helper.c
>>>>>> +++ b/qemu-bridge-helper.c
>>>>>> @@ -33,6 +33,10 @@
>>>>>>
>>>>>> #include "net/tap-linux.h"
>>>>>>
>>>>>> +#ifdef CONFIG_LIBCAP
>>>>>> +#include<cap-ng.h>
>>>>>> +#endif
>>>>>> +
>>>>>> #define MAX_ACLS (128)
>>>>>> #define DEFAULT_ACL_FILE CONFIG_QEMU_CONFDIR "/bridge.conf"
>>>>>>
>>>>>> @@ -185,6 +189,27 @@ static int send_fd(int c, int fd)
>>>>>> return sendmsg(c,&msg, 0);
>>>>>> }
>>>>>>
>>>>>> +#ifdef CONFIG_LIBCAP
>>>>>> +static int drop_privileges(void)
>>>>>> +{
>>>>>> + /* clear all capabilities */
>>>>>> + capng_clear(CAPNG_SELECT_BOTH);
>>>>>> +
>>>>>> + if (capng_update(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED,
>>>>>> + CAP_NET_ADMIN)< 0) {
>>>>>> + return -1;
>>>>>> + }
>>>>>> +
>>>>>> + /* change to calling user's real uid and gid, retaining
>>>>>> supplemental
>>>>>> + * groups and CAP_NET_ADMIN */
>>>>>> + if (capng_change_id(getuid(), getgid(), CAPNG_CLEAR_BOUNDING)) {
>>>>>> + return -1;
>>>>>> + }
>>>>>> +
>>>>>> + return 0;
>>>>>> +}
>>>>>> +#endif
>>>>>> +
>>>>>> int main(int argc, char **argv)
>>>>>> {
>>>>>> struct ifreq ifr;
>>>>>> @@ -198,6 +223,20 @@ int main(int argc, char **argv)
>>>>>> int acl_count = 0;
>>>>>> int i, access_allowed, access_denied;
>>>>>>
>>>>>> + /* if we're run from an suid binary, immediately drop privileges
>>>>>> preserving
>>>>>> + * cap_net_admin -- exit immediately if libcap not configured */
>>>>>> + if (geteuid() == 0&& getuid() != geteuid()) {
>>>>>> +#ifdef CONFIG_LIBCAP
>>>>>> + if (drop_privileges() == -1) {
>>>>>> + fprintf(stderr, "failed to drop privileges\n");
>>>>>> + return 1;
>>>>>> + }
>>>>>> +#else
>>>>>> + fprintf(stderr, "failed to drop privileges\n");
>>>>>
>>>>> This makes the tool useless without CONFIG_LIBCAP. Wouldn't it be
>>>>> possible to use setfsuid() instead for Linux?
>>>>>
>>>>> Some fork+setuid helper could be used for other Unix and for the lame
>>>>> OSes without any file system DAC capabilities, a different syntax that
>>>>> does not rely on underlying FS may need to be introduced. Again, I
>>>>> don't know if the tool is even interesting for non-Linux.
>>>>>
>>>>
>>>> I just want to make sure that there is no chance that the helper is run
>>>> as
>>>> root beyond this point. Are you saying to seteuid(getuid) and
>>>> setfsuid(root)? I'm not sure that would drop the privileges enough.
>>>
>>> Without capabilities, we can't drop root privileges because bridge
>>> setup would fail otherwise, but we could use setfsuid(getuid()) and
>>> setfsgid(getgid()) during file access so permission checks work.
>>> Perhaps non-Linux could use seteuid() etc. instead.
>>>
>>
>> This would reduce file system access from effective UID/GID (root/root) to
>> real UID/GID (non-root/non-root). Other than file system access, the helper
>> would still run under root/root, right? I don't think we want that from a
>> security aspect.
>
> Right, it's not desirable, but isn't that the best we can do without
> libcap or FS capabilities?
>
I think the best we can do is not let it run in those cases. :) I'd
like see if others in the community have an opinion on this though.
--
Regards,
Corey
>> --
>> Regards,
>> Corey
>>
>>>>>> + return 1;
>>>>>> +#endif
>>>>>> + }
>>>>>> +
>>>>>> /* parse arguments */
>>>>>> if (argc< 3 || argc> 4) {
>>>>>> fprintf(stderr, "Usage: %s [--use-vnet] BRIDGE FD\n", argv[0]);
>>>>>> --
>>>>>> 1.7.3.4
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>
>>
>
next prev parent reply other threads:[~2011-10-24 19:14 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-10-21 15:07 [Qemu-devel] [PATCH v2 0/4] -net bridge: rootless bridge support for qemu Corey Bryant
2011-10-21 15:07 ` [Qemu-devel] [PATCH v2 1/4] Add basic version of bridge helper Corey Bryant
2011-10-23 12:56 ` Blue Swirl
2011-10-24 13:12 ` Corey Bryant
2011-10-21 15:07 ` [Qemu-devel] [PATCH v2 2/4] Add access control support to qemu " Corey Bryant
2011-10-23 13:10 ` Blue Swirl
2011-10-24 13:44 ` Corey Bryant
2011-10-24 16:58 ` Blue Swirl
2011-10-21 15:07 ` [Qemu-devel] [PATCH v2 3/4] Add cap reduction support to enable use as SUID Corey Bryant
2011-10-23 13:22 ` Blue Swirl
2011-10-24 14:13 ` Corey Bryant
2011-10-24 17:10 ` Blue Swirl
2011-10-24 18:38 ` Corey Bryant
2011-10-24 18:58 ` Blue Swirl
2011-10-24 19:13 ` Corey Bryant [this message]
2011-10-24 19:21 ` Anthony Liguori
2011-10-24 20:20 ` Corey Bryant
2011-10-24 22:15 ` Anthony Liguori
2011-10-24 19:19 ` Anthony Liguori
2011-10-21 15:07 ` [Qemu-devel] [PATCH v2 4/4] Add support for net bridge Corey Bryant
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4EA5B8E5.6040306@linux.vnet.ibm.com \
--to=coreyb@linux.vnet.ibm.com \
--cc=aliguori@us.ibm.com \
--cc=blauwirbel@gmail.com \
--cc=qemu-devel@nongnu.org \
--cc=rmarwah@linux.vnet.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).