Re: [CFT][PATCH] proc: Update /proc/net to point at the accessing threads network namespace

Eric W. Biederman
2022-09-30T16:18:24Z

David Laight <David.Laight@ACULAB.COM> writes:

> From: Eric W. Biederman
>> Sent: 29 September 2022 23:48
>>
>> Since common apparmor policies don't allow access /proc/tgid/task/tid/net
>> point the code at /proc/tid/net instead.
>>
>> Link: https://lkml.kernel.org/r/dacfc18d6667421d97127451eafe4f29@AcuMS.aculab.com
>> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
>> ---
>>
>> I have only compile tested this. All of the boiler plate is a copy of
>> /proc/self and /proc/thread-self, so it should work.
>>
>> Can David or someone who cares and has access to the limited apparmor
>> configurations could test this to make certain this works?
>
> It works with a minor 'cut & paste' fixup.
> (Not nested inside a program that changes namespaces.)

Were there any apparmor problems? I just want to confirm that is what
you tested.

Assuming not this patch looks like it reveals a solution to this
issue.

> Although if it is reasonable for /proc/net -> /proc/tid/net
> why not just make /proc/thread-self -> /proc/tid
> Then /proc/net can just be thread-self/net

There are minor differences between the process directories that
tend to report process wide information and task directories that
only report some of the same information per-task. So in general
thread-self makes much more sense pointing to a per-task directory.

The hidden /proc/tid/ directories use the per process code to generate
themselves. The difference is that they assume the tid is the leading
thread instead of the other process. Those directories are all a bit of
a scrambled mess. I was suspecting the other day we might be able to
fix gdb and make them go away entirely in a decade or so.

So I don't think it makes sense in general to point /proc/thread-self at
the hidden per /proc/tid/ directories.

> I have wondered if the namespace lookup could be done as a 'special'
> directory lookup for "net" rather that changing everything when the
> namespace is changed.
> I can imagine scenarios where a thread needs to keep changing
> between two namespaces, at the moment I suspect that is rather
> more expensive than a lookup and changing the reference counts.

You can always open the net directories once, and then change as
an open directory will not change between namespaces.

> Notwithstanding the apparmor issues, /proc/net could actuall be
> a symlink to (say) /proc/net_namespaces/namespace_name with
> readlink returning the name based on the threads actual namespace.

There really aren't good names for namespaces at the kernel level. As
one of their use cases is to make process migration possible between
machines. So any kernel level name would need to be migrated as well.
So those kernel level names would need a name in another namespace,
or an extra namespace would have to be created for those names.

> I've also had problems with accessing /sys/class/net for multiple
> namespaces within the same thread (think of a system monitor process).
> The simplest solution is to start the program with:
> ip netne exec namespace program 3</sys/class/net
> and the use openat(3, ...) to read items in the 'init' namespace.
>
> FWIW I'm pretty sure there a sequence involving unshare() that
> can get you out of a chroot - but I've not found it yet.

Out of a chroot is essentially just:
chdir("/");
chroot("/somedir");
chdir("../../../../../../../../../../../../../../../..");
Out of most namespaces except the pid and user namespace is
just chns.

You can't get out of the pid namespace as you can't change your pid.

Not being able to escape a user namespace is what makes it impossible to
confuse a process and gain privileges through a privilege gaining exec.

Eric