Re: call_usermodehelper in containers

From: Kamezawa Hiroyuki
Date: Fri Feb 19 2016 - 04:31:25 EST


On 2016/02/19 14:37, Ian Kent wrote:
On Fri, 2016-02-19 at 12:08 +0900, Kamezawa Hiroyuki wrote:
On 2016/02/19 5:45, Eric W. Biederman wrote:
Personally I am a fan of the don't be clever and capture a kernel
thread
approach as it is very easy to see you what if any exploitation
opportunities there are. The justifications for something more
clever
is trickier. Of course we do something that from this perspective
would
be considered ``clever'' today with kthreadd and user mode helpers.


I read old discussion....let me allow clarification to create a
helper kernel thread
to run usermodehelper with using kthreadd.

0) define a trigger to create an independent usermodehelper
environment for a container.
Option A) at creating some namespace (pid, uid, etc...)
Option B) at creating a new nsproxy
Option C).at a new systemcall is called or some sysctl,
make_private_usermode_helper() or some,

It's expected this should be triggered by init process of a
container with some capability.
And scope of the effect should be defined. pid namespace ? nsporxy ?
or new namespace ?

1) create a helper thread.
task = kthread_create(kthread_work_fn, ?, ?, "usermodehelper")
switch task's nsproxy to current.(swtich_task_namespaces())
switch task's cgroups to current (cgroup_attach_task_all())
switch task's cred to current.
copy task's capability from current
(and any other ?)
wake_up_process()

And create a link between kthread_wq and container.

Not sure I quite understand this but I thought the difficulty with this
approach previously (even though the approach was very much incomplete)
was knowing that all the "moving parts" would not allow vulnerabilities.

Ok, that was discussed.

And it looks like this would require a kernel thread for each instance.
So for a thousand containers that each mount an NFS mount that means, at
least, 1000 additional kernel threads. Might be able to sell that, if we
were lucky, but from an system administration POV it's horrible.

I agree.

There's also the question of existence (aka. lifetime) to deal with
since the thread above needs to be created at a time other than the
usermode helper callback.

What happens for SIGKILL on a container?

It depends on how the helper kthread is tied to a container related object.
If kthread is linked with some namespace, we can kill it when a namespace
goes away.

So, with your opinion,
- a helper thread should be spawned on demand
- the lifetime of it should be clear. It will be good to have as same life time as the container.

I wonder there is no solution for "moving part" problem other than calling
do_fork() or copy_process() with container's init process context if we do all in the kernel.
Is that possible ?

Thanks,
-Kame