lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Thu, 12 Jan 2023 22:53:07 +0100
From:   Vegard Nossum <vegard.nossum@...cle.com>
To:     Luis Chamberlain <mcgrof@...nel.org>,
        Petr Pavlu <petr.pavlu@...e.com>,
        Petr Mladek <pmladek@...e.com>, prarit@...hat.com,
        david@...hat.com, mwilck@...e.com
Cc:     linux-kernel@...r.kernel.org,
        Thadeu Lima de Souza Cascardo <cascardo@...onical.com>,
        Serge Hallyn <serge@...lyn.com>,
        Eric Biederman <ebiederm@...ssion.com>,
        Kees Cook <keescook@...omium.org>,
        linux-hardening@...r.kernel.org, linux-modules@...r.kernel.org,
        John Haxby <john.haxby@...cle.com>,
        Jann Horn <jannh@...gle.com>
Subject: Re: [PATCH v3] kmod: harden user namespaces with new
 kernel.ns_modules_allowed sysctl

On 1/12/23 19:45, Luis Chamberlain wrote:
> On Thu, Jan 12, 2023 at 02:19:11PM +0100, Vegard Nossum wrote:
>>   
>> +ns_modules_allowed
>> +==================
>> +
>> +Control whether processes may trigger module loading inside a user namespace.
> 
> This is false documentation. The place it is trying to protect simply
> prevents trying to call modprobe for auto-loading within the kernel.

I don't think this is false -- but yes, this only protects module
auto-loading in user namespaces; all auto-loading calls within the
kernel should be going through this __request_module() -> modprobe path.

init_module()/finit_module(), the mechanism used by modprobe, are
themselves already restricted inside user namespaces, see below.

>> +	/*
>> +	 * Disallow module loading if we're in a user namespace.
>> +	 */
>> +	if (current_user_ns() != &init_user_ns &&
>> +	    !sysctl_ns_modules_allowed) {
>> +		pr_warn_ratelimited("request_module: pid %d (%s) in user namespace requested kernel module %s; denied due to kernel.ns_modules_allowed sysctl\n",
>> +			task_pid_nr(current), current->comm, module_name);
>> +		return -EPERM;
>> +	}
>> +
>>   	if (atomic_dec_if_positive(&kmod_concurrent_max) < 0) {
>>   		pr_warn_ratelimited("request_module: kmod_concurrent_max (%u) close to 0 (max_modprobes: %u), for module %s, throttling...",
>>   				    atomic_read(&kmod_concurrent_max),
> 
> Have you seen what call_modprobe() does?

Yes.

> This is just a limitting the auto-loading through calling modprobe.
> If the concern is to load modules wouldn't you be better off just
> putting a stop gap at finit_module() which actually receives the
> load attempt from modprobe? Ie, an evil namespace, if it has access
> to /sbin/modprobe could simply just try calling /sbin/modprobe on its
> own.

No.

Root inside a user namespace can't call finit_module() as it won't have
the necessary capabilities in the init namespace, see may_init_module().

modprobe, on the other hand, when called by the kernel, is called
through usermode helper, which runs in the init namespace as root, so it
can do whatever it wants.

If modprobe called by root inside a user namespace could load anything,
that itself would be a security issue. But it can't, so it's not.

> Beating the royal shit out of kmod is already stress tested via
> tools/testing/selftests/kmod/kmod.sh in particular:
> 
> tools/testing/selftests/kmod/kmod.sh -t 0008
> tools/testing/selftests/kmod/kmod.sh -t 0009
> 
> What this *could* do is race to force a failure on some other *real*
> modprobe request we do wish to honor when the above kmod kmod_concurrent_max
> is triggered.

How? My new check is done before the kmod_concurrent_max check/critical
section... the check doesn't cause any more modprobe requests to happen
in the first place, the only thing it can do is make them exit early.
There is no way my patch can make this worse.

> So in terms of justification, this commit log needs a bit more work as I
> just can't see how this alone is fixing any CVE.

[...]

> So let's take a step back and think this through. What exaclty and why
> would this commit fix *any* security issue? Itemizing CVEs won't cut it.

I can include my explanations above in the changelog if you think that
will help.


Vegard

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ