[libvirt] [PATCH v1 16/21] qemu: Enter the namespace on relabelling
Michal Privoznik
mprivozn at redhat.com
Mon Dec 5 14:14:50 UTC 2016
On 05.12.2016 14:40, Daniel P. Berrange wrote:
> On Thu, Nov 24, 2016 at 03:48:05PM +0100, Michal Privoznik wrote:
>> Instead of trying to fix our security drivers, we can use a
>> simple trick to relabel paths in both namespace and the host.
>> I mean, if we enter the namespace some paths are still shared
>> with the host so any change done to them is visible from the host
>> too.
>> Therefore, we can just enter the namespace and call
>> SetAllLabel()/RestoreAllLabel() from there. Yes, it has slight
>> overhead because we have to fork in order to enter the namespace.
>> But on the other hand, no complexity is added to our code.
>
> I'm a little concerned that this may be storing problems for us
> at a later date. If the security manager classes have any state
> they update such changes are invisible to the main libvirt
> process now. Also stuff running between fork+exec is restricted
> to async signal safe functions only. I think it is hard for us
> to be entirely confident about that safety when we're running
> the entire security driver labelling code in that region.
>
> Ultimately the only bit of the security drivers that needs to
> run in the namespace is the setfilecon_raw() or chown() system
> calls.
>
> So I wonder if we should make it possible to provide a namespace
> helper callback to the security drivers that they'd use only
> for the setfilecon_raw/chown calls.
>
> eg, we could do something like
>
>
> typedef (*virSecurityManagerNamespaceHelperFunc)(void *opaque)
> typedef (*virSecurityManagerNamespaceHelper)(virSecurityManagerNamespaceHelperFunc func, void *opaque)
>
> virSecurityManagerSetNamespacehelper(mgr, runInNamespaceHelper)
>
> ....do the labelling...
>
> virSecurityManagerSetNamespacehelper(mgr, NULL)
>
> the namespace helper would have to be stored in a thread local
> since we need to cope with some VMs not having separate namespaces
>
> The security manager code would need todo
>
> struct SELinuxNamespaceData {
> const char *path;
> security_context_t ctx;
> }
>
> Now instead of
>
>
> if (setfilecon_raw(path, tcon) < 0)
> ...
>
> it would do
>
> static int SELinuxNamespaceHelperFunc(void *opaque) {
> struct SELinuxNamespaceData *data = opaque
>
> return setfilecon_raw(data->path, data->tcon)
> }
>
> struct SELinuxNamespaceData data = { path, tcon}
>
> if (namespacehelper(SELinuxNamespaceHelperFunc, &data) < 0)
> ...
>
I was thinking about this too, but I see two problems with this approach:
1) fork() on every chown() and every sefilecon_raw(). That's too much IMO.
2) thread safeness. We can't have the sec manager wide callback. But you
already covered that - and thread local variable might in fact work just
fine!
Michal
More information about the libvir-list
mailing list