[libvirt] [PATCH] apparmor: support finer-grained ptrace checks

Jim Fehlig jfehlig at suse.com
Fri Sep 22 21:04:21 UTC 2017


On 09/22/2017 06:52 AM, Guido Günther wrote:
> Hi Jim,
> On Wed, Sep 20, 2017 at 11:17:06AM -0600, Jim Fehlig wrote:
>> On 09/20/2017 08:57 AM, Jim Fehlig wrote:
>>> On 09/20/2017 12:51 AM, Guido Günther wrote:
>>>> Hi Jim,
>>>> On Mon, Sep 18, 2017 at 02:06:13PM -0600, Jim Fehlig wrote:
>>>>> Kernel 4.13 introduced finer-grained ptrace checks
>>>>>
>>>>> https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/commit/?h=v4.13.2&id=290f458a4f16f9cf6cb6562b249e69fe1c3c3a07
>>>>>
>>>>>
>>>>> When Apparmor is enabled and libvirtd is confined, attempting to start
>>>>> a domain fails
>>>>>
>>>>> virsh start test
>>>>> error: Failed to start domain test
>>>>> error: internal error: child reported: Kernel does not provide mount
>>>>>          namespace: Permission denied
>>>>>
>>>>> The audit log contains
>>>>>
>>>>> type=AVC msg=audit(1505466699.828:534): apparmor="DENIED"
>>>>> operation="ptrace" profile="/usr/sbin/libvirtd" pid=6621
>>>>> comm="libvirtd" requested_mask="trace" denied_mask="trace"
>>>>> peer="/usr/sbin/libvirtd"
>>>>
>>>> It seems access to /proc/<pid>/tasks already requires trace permissions.
>>>>
>>>>>
>>>>> It was also noticed that simply connecting to libvirtd (e.g. virsh list)
>>>>> resulted in the following entries in the audit log
>>>>>
>>>>> type=AVC msg=audit(1505755799.975:65): apparmor="DENIED"
>>>>> operation="ptrace" profile="/usr/sbin/libvirtd" pid=1418
>>>>> comm="libvirtd" requested_mask="trace" denied_mask="trace"
>>>>> peer="unconfined"
>>>>> type=AVC msg=audit(1505755799.976:66): apparmor="DENIED"
>>>>> operation="ptrace" profile="/usr/sbin/libvirtd" pid=1418
>>>>> comm="libvirtd" requested_mask="trace" denied_mask="trace"
>>>>> peer="unconfined"
>>>>>
>>>>> Both Apparmor denials can be fixed by adding ptrace rules to the
>>>>> libvirtd profile. The new rules only grant trace permission.
>>>>
>>>> I'm seeing the same denials with 4.13 (4.13.1-1~exp1 (2017-09-11) in
>>>> Debian) but the proposed profile change does not fix the vm start issue
>>>> for me. I can't tell why atm, will have to look into this in more detail
>>>> at the WE.
>>>
>>> I have other problems when running with 'security_default_confined = 1'
>>> in qemu.conf, but the changes allow starting unconfined domains.
>>>
>>> Cedric remembered this old thread
>>>
>>> https://www.redhat.com/archives/libvir-list/2014-October/msg00011.html
>>>
>>> Some of those changes have been merged, but the ptrace, dbus, signal,
>>> etc. have not. I used Stefan's changes to the libvirtd profile but still
>>> see the same issue with confined domains
>>
>> I dug a bit further in that thread to find Stefan's most recent version of
>> the patches
>>
>> https://www.redhat.com/archives/libvir-list/2014-October/msg00556.html
>>
>> I took the ptrace, dbus, signal, etc. changes out of patch 2 and used the
>> attached patch to successfully start confined domains.
>>
>> Since a few years have passed, I'm not sure if patch 1 is still relevant.
>> IIUC, it allows to conditionalize profile content based on apparmor version,
>> which patch 2 uses to add some stuff if version >= 2.9. 2.9 has been out for
>> a while...
> 
> Great, this helps a lot!
> 
>>  From e3bb609812776b30acfc0349b25b2e4d539c45c2 Mon Sep 17 00:00:00 2001
>> From: Jim Fehlig <jfehlig at suse.com>
>> Date: Mon, 18 Sep 2017 13:41:26 -0600
>> Subject: [PATCH] apparmor: support ptrace checks
>>
>> Kernel 4.13 introduced finer-grained ptrace checks
>>
>> https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/commit/?h=v4.13.2&id=290f458a4f16f9cf6cb6562b249e69fe1c3c3a07
>>
>> When Apparmor is enabled and libvirtd is confined, attempting to start
>> a domain fails
>>
>> virsh start test
>> error: Failed to start domain test
>> error: internal error: child reported: Kernel does not provide mount
>>         namespace: Permission denied
>>
>> The audit log contains
>>
>> type=AVC msg=audit(1505466699.828:534): apparmor="DENIED"
>> operation="ptrace" profile="/usr/sbin/libvirtd" pid=6621
>> comm="libvirtd" requested_mask="trace" denied_mask="trace"
>> peer="/usr/sbin/libvirtd"
>>
>> It was also noticed that simply connecting to libvirtd (e.g. virsh list)
>> resulted in the following entries in the audit log
>>
>> type=AVC msg=audit(1505755799.975:65): apparmor="DENIED"
>> operation="ptrace" profile="/usr/sbin/libvirtd" pid=1418
>> comm="libvirtd" requested_mask="trace" denied_mask="trace"
>> peer="unconfined"
>> type=AVC msg=audit(1505755799.976:66): apparmor="DENIED"
>> operation="ptrace" profile="/usr/sbin/libvirtd" pid=1418
>> comm="libvirtd" requested_mask="trace" denied_mask="trace"
>> peer="unconfined"
>>
>> Both Apparmor denials can be fixed by supporting ptrace in the
>> libvirtd, qemu, and lxc profiles. While at it, also add support
>> for dbus, signal, and unix.
>>
>> Resolves: https://bugzilla.suse.com/show_bug.cgi?id=1058847
>> Signed-off-by: Jim Fehlig <jfehlig at suse.com>
>> ---
>>   examples/apparmor/libvirt-lxc       | 3 +++
>>   examples/apparmor/libvirt-qemu      | 3 +++
>>   examples/apparmor/usr.sbin.libvirtd | 6 ++++++
>>   3 files changed, 12 insertions(+)
>>
>> diff --git a/examples/apparmor/libvirt-lxc b/examples/apparmor/libvirt-lxc
>> index 4bfb503aa..0db137de0 100644
>> --- a/examples/apparmor/libvirt-lxc
>> +++ b/examples/apparmor/libvirt-lxc
>> @@ -3,6 +3,9 @@
>>     #include <abstractions/base>
>>   
>>     umount,
>> +  dbus,
>> +  signal,
>> +  ptrace,
> 
> Can't we get a long with a
> 
>      ptrace (tracedby) peer=/usr/sbin/libvirtd,
> 
> here too?

Probably. I simply took the changes from Stefan's latest patch and didn't test lxc.

> 
>>   
>>     # ignore DENIED message on / remount
>>     deny mount options=(ro, remount) -> /,
>> diff --git a/examples/apparmor/libvirt-qemu b/examples/apparmor/libvirt-qemu
>> index dcfb1a598..6a4a2335a 100644
>> --- a/examples/apparmor/libvirt-qemu
>> +++ b/examples/apparmor/libvirt-qemu
>> @@ -170,6 +170,9 @@
>>     @{PROC}/device-tree/** r,
>>     /sys/firmware/devicetree/** r,
>>   
>> +  signal (receive) peer=/usr/sbin/libvirtd,
>> +  ptrace (tracedby) peer=/usr/sbin/libvirtd,
> 
> I would have expected to need the ptrace part but don't (see below).

Likewise for these. But after testing I've found they are not needed.

> 
>> +
>>     # for gathering information about available host resources
>>     /sys/devices/system/cpu/ r,
>>     /sys/devices/system/node/ r,
>> diff --git a/examples/apparmor/usr.sbin.libvirtd b/examples/apparmor/usr.sbin.libvirtd
>> index acb59e071..9aadba411 100644
>> --- a/examples/apparmor/usr.sbin.libvirtd
>> +++ b/examples/apparmor/usr.sbin.libvirtd
>> @@ -36,6 +36,12 @@
>>     network inet6 dgram,
>>     network packet dgram,
>>     network packet raw,
>> +  network netlink,
>> +
>> +  dbus bus=system,
>> +  signal,
>> +  ptrace,
> 
> ^^^^^^^
> 
> This single line is enough to make things work for me on 4.13.

Same here, but it allows more than needed IMO.

Although Jamie provided excellent info on dbus, signal, etc., I'm going to 
ignore those for now since I can't test on 4.13 kernel. I can however test 
ptrace and here is a summary of my findings.

Using kernel 4.13, apparmor 2.11, and the current libvirt.git profiles, simply 
starting libvirtd results in the following denial

type=AVC msg=audit(1506112085.645:954): apparmor="DENIED" operation="ptrace" 
profile="/usr/sbin/libvirtd" pid=6984 comm="libvirtd" requested_mask="trace" 
denied_mask="trace" peer="unconfined"

Adding 'ptrace (trace) peer=unconfined,' allows starting libvirtd with no 
denials. But this rule is not enough to start unconfined domains, where I see 
the following denial

type=AVC msg=audit(1506112301.227:1112): apparmor="DENIED" operation="ptrace" 
profile="/usr/sbin/libvirtd" pid=7498 comm="libvirtd" requested_mask="trace" 
denied_mask="trace" peer="/usr/sbin/libvirtd"

Adding 'ptrace (trace) peer=/usr/sbin/libvirtd,' allows starting unconfined 
domains. But this is still not enough to start confined domains, where I see the 
following denials

type=AVC msg=audit(1506112631.408:1312): apparmor="DENIED" operation="open" 
profile="virt-aa-helper" name="/etc/libnl/classid" pid=8283 
comm="virt-aa-helper" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
type=AVC msg=audit(1506112631.530:1319): apparmor="DENIED" operation="open" 
profile="virt-aa-helper" name="/etc/libnl/classid" pid=8289 
comm="virt-aa-helper" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
type=AVC msg=audit(1506112632.186:1324): apparmor="DENIED" operation="ptrace" 
profile="/usr/sbin/libvirtd" pid=8342 comm="libvirtd" requested_mask="trace" 
denied_mask="trace" peer="libvirt-66154842-e926-4f92-92f0-1c1bf61dd1ff"

Finally, adding 'ptrace (trace) peer=(label=@{profile_name}),' allows starting 
confined domains.

I'll send a V2 patch that only adds the above ptrace rules to the libvirtd profile.

Regards,
Jim




More information about the libvir-list mailing list