2014-04-14 20:18:26

by Nicolas Iooss

[permalink] [raw]
Subject: [refpolicy] [PATCH] Allow lvm_t to use unconfined_t SysV semaphores

When an unconfined user uses truecrypt to mount an encrypted file, following
logs appears in audit.log:

type=AVC msg=audit(1397491934.868:164): avc: denied { associate } for pid=3695 comm="dmsetup" key=223198474 scontext=system_u:system_r:lvm_t tcontext=unconfined_u:unconfined_r:unconfined_t tclass=sem
type=AVC msg=audit(1397491934.868:165): avc: denied { unix_read } for pid=3695 comm="dmsetup" key=223198474 scontext=system_u:system_r:lvm_t tcontext=unconfined_u:unconfined_r:unconfined_t tclass=sem
type=AVC msg=audit(1397491934.868:165): avc: denied { read } for pid=3695 comm="dmsetup" key=223198474 scontext=system_u:system_r:lvm_t tcontext=unconfined_u:unconfined_r:unconfined_t tclass=sem
type=AVC msg=audit(1397491934.868:166): avc: denied { unix_write } for pid=3695 comm="dmsetup" key=223198474 scontext=system_u:system_r:lvm_t tcontext=unconfined_u:unconfined_r:unconfined_t tclass=sem
type=AVC msg=audit(1397491934.868:166): avc: denied { write } for pid=3695 comm="dmsetup" key=223198474 scontext=system_u:system_r:lvm_t tcontext=unconfined_u:unconfined_r:unconfined_t tclass=sem

audit2allow gives:

allow lvm_t unconfined_t:sem { unix_read read write unix_write associate };

Allowing this access requires a new interface in unconfined.if.
---
policy/modules/system/lvm.te | 4 ++++
policy/modules/system/unconfined.if | 37 +++++++++++++++++++++++++++++++++++++
2 files changed, 41 insertions(+)

diff --git a/policy/modules/system/lvm.te b/policy/modules/system/lvm.te
index 3dac9a5..a407c18 100644
--- a/policy/modules/system/lvm.te
+++ b/policy/modules/system/lvm.te
@@ -347,6 +347,10 @@ optional_policy(`
')

optional_policy(`
+ unconfined_rw_semaphores(lvm_t)
+')
+
+optional_policy(`
virt_manage_images(lvm_t)
')

diff --git a/policy/modules/system/unconfined.if b/policy/modules/system/unconfined.if
index 5ca20a9..59a519e 100644
--- a/policy/modules/system/unconfined.if
+++ b/policy/modules/system/unconfined.if
@@ -463,6 +463,43 @@ interface(`unconfined_dontaudit_rw_pipes',`

########################################
## <summary>
+## Read and write unconfined domain SysV semaphores.
+## </summary>
+## <param name="domain">
+## <summary>
+## Domain allowed access.
+## </summary>
+## </param>
+#
+interface(`unconfined_rw_semaphores',`
+ gen_require(`
+ type unconfined_t;
+ ')
+
+ allow $1 unconfined_t:sem rw_sem_perms;
+')
+
+########################################
+## <summary>
+## Do not audit attempts to read and write
+## unconfined domain SysV semaphores.
+## </summary>
+## <param name="domain">
+## <summary>
+## Domain allowed access.
+## </summary>
+## </param>
+#
+interface(`unconfined_dontaudit_rw_semaphores',`
+ gen_require(`
+ type unconfined_t;
+ ')
+
+ dontaudit $1 unconfined_t:sem rw_sem_perms;
+')
+
+########################################
+## <summary>
## Connect to the unconfined domain using
## a unix domain stream socket.
## </summary>
--
1.9.1


2014-04-21 13:17:10

by cpebenito

[permalink] [raw]
Subject: [refpolicy] [PATCH] Allow lvm_t to use unconfined_t SysV semaphores

On 04/14/2014 04:18 PM, Nicolas Iooss wrote:
> When an unconfined user uses truecrypt to mount an encrypted file, following
> logs appears in audit.log:
>
> type=AVC msg=audit(1397491934.868:164): avc: denied { associate } for pid=3695 comm="dmsetup" key=223198474 scontext=system_u:system_r:lvm_t tcontext=unconfined_u:unconfined_r:unconfined_t tclass=sem
> type=AVC msg=audit(1397491934.868:165): avc: denied { unix_read } for pid=3695 comm="dmsetup" key=223198474 scontext=system_u:system_r:lvm_t tcontext=unconfined_u:unconfined_r:unconfined_t tclass=sem
> type=AVC msg=audit(1397491934.868:165): avc: denied { read } for pid=3695 comm="dmsetup" key=223198474 scontext=system_u:system_r:lvm_t tcontext=unconfined_u:unconfined_r:unconfined_t tclass=sem
> type=AVC msg=audit(1397491934.868:166): avc: denied { unix_write } for pid=3695 comm="dmsetup" key=223198474 scontext=system_u:system_r:lvm_t tcontext=unconfined_u:unconfined_r:unconfined_t tclass=sem
> type=AVC msg=audit(1397491934.868:166): avc: denied { write } for pid=3695 comm="dmsetup" key=223198474 scontext=system_u:system_r:lvm_t tcontext=unconfined_u:unconfined_r:unconfined_t tclass=sem
>
> audit2allow gives:
>
> allow lvm_t unconfined_t:sem { unix_read read write unix_write associate };
>
> Allowing this access requires a new interface in unconfined.if.

It might make more sense to add this access to lvm_run(), since any user than can run lvm could potentially need this. It also warrants a comment in the policy about Truecrypt.



> ---
> policy/modules/system/lvm.te | 4 ++++
> policy/modules/system/unconfined.if | 37 +++++++++++++++++++++++++++++++++++++
> 2 files changed, 41 insertions(+)
>
> diff --git a/policy/modules/system/lvm.te b/policy/modules/system/lvm.te
> index 3dac9a5..a407c18 100644
> --- a/policy/modules/system/lvm.te
> +++ b/policy/modules/system/lvm.te
> @@ -347,6 +347,10 @@ optional_policy(`
> ')
>
> optional_policy(`
> + unconfined_rw_semaphores(lvm_t)
> +')
> +
> +optional_policy(`
> virt_manage_images(lvm_t)
> ')
>
> diff --git a/policy/modules/system/unconfined.if b/policy/modules/system/unconfined.if
> index 5ca20a9..59a519e 100644
> --- a/policy/modules/system/unconfined.if
> +++ b/policy/modules/system/unconfined.if
> @@ -463,6 +463,43 @@ interface(`unconfined_dontaudit_rw_pipes',`
>
> ########################################
> ## <summary>
> +## Read and write unconfined domain SysV semaphores.
> +## </summary>
> +## <param name="domain">
> +## <summary>
> +## Domain allowed access.
> +## </summary>
> +## </param>
> +#
> +interface(`unconfined_rw_semaphores',`
> + gen_require(`
> + type unconfined_t;
> + ')
> +
> + allow $1 unconfined_t:sem rw_sem_perms;
> +')
> +
> +########################################
> +## <summary>
> +## Do not audit attempts to read and write
> +## unconfined domain SysV semaphores.
> +## </summary>
> +## <param name="domain">
> +## <summary>
> +## Domain allowed access.
> +## </summary>
> +## </param>
> +#
> +interface(`unconfined_dontaudit_rw_semaphores',`
> + gen_require(`
> + type unconfined_t;
> + ')
> +
> + dontaudit $1 unconfined_t:sem rw_sem_perms;
> +')
> +
> +########################################
> +## <summary>
> ## Connect to the unconfined domain using
> ## a unix domain stream socket.
> ## </summary>
>


--
Chris PeBenito
Tresys Technology, LLC
http://www.tresys.com | oss.tresys.com

2014-05-08 09:52:31

by Nicolas Iooss

[permalink] [raw]
Subject: [refpolicy] [PATCH] Allow lvm_t to use unconfined_t SysV semaphores

2014-04-21 15:17 GMT+02:00 Christopher J. PeBenito <[email protected]>:
> On 04/14/2014 04:18 PM, Nicolas Iooss wrote:
>> When an unconfined user uses truecrypt to mount an encrypted file, following
>> logs appears in audit.log:
>>
>> type=AVC msg=audit(1397491934.868:164): avc: denied { associate } for pid=3695 comm="dmsetup" key=223198474 scontext=system_u:system_r:lvm_t tcontext=unconfined_u:unconfined_r:unconfined_t tclass=sem
>> type=AVC msg=audit(1397491934.868:165): avc: denied { unix_read } for pid=3695 comm="dmsetup" key=223198474 scontext=system_u:system_r:lvm_t tcontext=unconfined_u:unconfined_r:unconfined_t tclass=sem
>> type=AVC msg=audit(1397491934.868:165): avc: denied { read } for pid=3695 comm="dmsetup" key=223198474 scontext=system_u:system_r:lvm_t tcontext=unconfined_u:unconfined_r:unconfined_t tclass=sem
>> type=AVC msg=audit(1397491934.868:166): avc: denied { unix_write } for pid=3695 comm="dmsetup" key=223198474 scontext=system_u:system_r:lvm_t tcontext=unconfined_u:unconfined_r:unconfined_t tclass=sem
>> type=AVC msg=audit(1397491934.868:166): avc: denied { write } for pid=3695 comm="dmsetup" key=223198474 scontext=system_u:system_r:lvm_t tcontext=unconfined_u:unconfined_r:unconfined_t tclass=sem
>>
>> audit2allow gives:
>>
>> allow lvm_t unconfined_t:sem { unix_read read write unix_write associate };
>>
>> Allowing this access requires a new interface in unconfined.if.
>
> It might make more sense to add this access to lvm_run(), since any user than can run lvm could potentially need this. It also warrants a comment in the policy about Truecrypt.

Thanks for your answer. As code and policy are a bit difficult to
understand here, I needed to take time to dig more and understand
what's going on here. Here is what I've found so far:

* unconfined_t doesn't use lvm_run(). More precisely, "sesearch -A -p
transition -t lvm_t" shows transitions for udev_t, sysadm_t, init_t,
initrc_t... but not unconfined_t. So I would expect dmsetup to run in
unconfined_t context, not lvm_t.
* "strace -f truecrypt --mount mydata" shows that after truecrypt asks
for a decryption key, it:
- creates /dev/loop0 with "mydata" file (using losetup),
- calls "dmsetup create truecrypt1" and gives through stdin a table
which basically configures /dev/mapper/truecrypt1 to decrypt data from
/dev/loop0 using kernel crypto API,
- mounts /dev/mapper/truecrypt1.

* Moreover, "dmsetup create truecrypt1" uses SysV semaphores. The
code [1][2] shows that the semaphores are used to sync with udev
notifications.
* Using a custom kernel module which logs every call to execve(), it
appears that udev calls "/usr/bin/dmsetup udevflags 6307491",
"/usr/lib/udev/udisks-dm-export 254 0", "/usr/lib/udev/udisks-part-id
/dev/dm-0" and "/usr/bin/dmsetup udevcomplete 6307491" right after
truecrypt calls "dmsetup create truecrypt1". The policy says that
when udev runs dmsetup, it is in lvm_t context.

If I understand correctly, when unconfined_t user uses truecrypt, this
program executes dmsetup in unconfined_t context and dmsetup creates a
semaphore in unconfined_t context. Then it notifies udev about a new
device and udev executes dmsetup to sync with the first dmsetup
process. The new dmsetup processes run in lvm_t context and use the
semaphore created in unconfined_t context. This behavior is denied by
the current reference policy.

I'm quite new to SELinux but this kind of scenario where a resource
(here a semaphore) is shared between a confined daemon (udev) and an
unconfined user (who uses truecrypt) might have occurred in the past
and a kind of general solution may exist. There are at least two
solutions: to allow the restricted daemon to access unconfined
resources (ie. allow lvm_t to use unconfined_t semaphores), or to add
a transition so that the user creates a confined resource (ie. add
"lvm_run(unconfined_t)"). What is the best way to solve this issue?

Regards,

Nicolas

PS: If it matters, I'm using Arch Linux with device-mapper 2.02.106,
truecrypt 1:7.1a, udev from systemd 212, linux 3.14.2 and a custom
SELinux policy heavily patched from the reference policy.

[1] https://git.fedorahosted.org/cgit/lvm2.git/tree/tools/dmsetup.c
[2] https://git.fedorahosted.org/cgit/lvm2.git/tree/libdm/libdm-common.c

2014-05-09 12:46:58

by cpebenito

[permalink] [raw]
Subject: [refpolicy] [PATCH] Allow lvm_t to use unconfined_t SysV semaphores

On 05/08/2014 05:52 AM, Nicolas Iooss wrote:
> 2014-04-21 15:17 GMT+02:00 Christopher J. PeBenito <[email protected]>:
>> On 04/14/2014 04:18 PM, Nicolas Iooss wrote:
>>> When an unconfined user uses truecrypt to mount an encrypted file, following
>>> logs appears in audit.log:
>>>
>>> type=AVC msg=audit(1397491934.868:164): avc: denied { associate } for pid=3695 comm="dmsetup" key=223198474 scontext=system_u:system_r:lvm_t tcontext=unconfined_u:unconfined_r:unconfined_t tclass=sem
>>> type=AVC msg=audit(1397491934.868:165): avc: denied { unix_read } for pid=3695 comm="dmsetup" key=223198474 scontext=system_u:system_r:lvm_t tcontext=unconfined_u:unconfined_r:unconfined_t tclass=sem
>>> type=AVC msg=audit(1397491934.868:165): avc: denied { read } for pid=3695 comm="dmsetup" key=223198474 scontext=system_u:system_r:lvm_t tcontext=unconfined_u:unconfined_r:unconfined_t tclass=sem
>>> type=AVC msg=audit(1397491934.868:166): avc: denied { unix_write } for pid=3695 comm="dmsetup" key=223198474 scontext=system_u:system_r:lvm_t tcontext=unconfined_u:unconfined_r:unconfined_t tclass=sem
>>> type=AVC msg=audit(1397491934.868:166): avc: denied { write } for pid=3695 comm="dmsetup" key=223198474 scontext=system_u:system_r:lvm_t tcontext=unconfined_u:unconfined_r:unconfined_t tclass=sem
>>>
>>> audit2allow gives:
>>>
>>> allow lvm_t unconfined_t:sem { unix_read read write unix_write associate };
>>>
>>> Allowing this access requires a new interface in unconfined.if.
>>
>> It might make more sense to add this access to lvm_run(), since any user than can run lvm could potentially need this. It also warrants a comment in the policy about Truecrypt.
>
> Thanks for your answer. As code and policy are a bit difficult to
> understand here, I needed to take time to dig more and understand
> what's going on here. Here is what I've found so far:
>
> * unconfined_t doesn't use lvm_run(). More precisely, "sesearch -A -p
[...]
> * Moreover, "dmsetup create truecrypt1" uses SysV semaphores. The
> code [1][2] shows that the semaphores are used to sync with udev
> notifications.
[...]
> when udev runs dmsetup, it is in lvm_t context.
[...]
> I'm quite new to SELinux but this kind of scenario where a resource
> (here a semaphore) is shared between a confined daemon (udev) and an
> unconfined user (who uses truecrypt) might have occurred in the past
> and a kind of general solution may exist. There are at least two
> solutions: to allow the restricted daemon to access unconfined
> resources (ie. allow lvm_t to use unconfined_t semaphores), or to add
> a transition so that the user creates a confined resource (ie. add
> "lvm_run(unconfined_t)"). What is the best way to solve this issue?

Thanks for the very detailed investigation. Based on your results, I'd say that these denials indicate that the semaphores have the wrong label, i.e. the semaphores should be labeled lvm_t, rather than unconfined_t. To make that happen, the solution is to have unconfined_t transition to lvm_t.

--
Chris PeBenito
Tresys Technology, LLC
http://www.tresys.com | oss.tresys.com