Message ID | 1511803118-2552-1-git-send-email-tixxdz@gmail.com |
---|---|
Headers | show |
Series | Improve Module autoloading infrastructure | expand |
On Mon, Nov 27, 2017 at 9:18 AM, Djalal Harouni <tixxdz@gmail.com> wrote: > > The sysctl flag is available at "/proc/sys/kernel/modules_autoload_mode" > > When modules_autoload_mode is set to (0), the default, there are no > restrictions. So quick question: do we actually need this? Yes, it may be the current default, but is it anything that people actually depend on? I'd have expected that most module loading comes from system actions anyway, not normal users. So I'd like to explore first whether it even makes sense to make a new option. New options are bad because: - opt-in security isn't security at all - having to configure things is complex so we should generally strive to _not_ need new random config options. What are the real life use-cases for normal users having modules auto-load? Linus
On Mon, Nov 27, 2017 at 10:41 AM, Linus Torvalds <torvalds@linux-foundation.org> wrote: > > What are the real life use-cases for normal users having modules auto-load? Well, I could do some testing. One case is apparently both bluetoothd and ip6tables that have been converted to indeed use CAP_NET_ADMIN. Annoying. Still, can't we just say "you need to have capabilities" and leave it at that? Something (UNTESTED and whitespace damaged) like this: diff --git a/kernel/kmod.c b/kernel/kmod.c index bc6addd9152b..a3f3218f66c6 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c @@ -139,6 +139,11 @@ int __request_module(bool wait, const char *fmt, ...) if (!modprobe_path[0]) return 0; + if (WARN_ON_ONCE(!capable(CAP_SYS_MODULE) || + !capable(CAP_SYS_ADMIN) || + !capable(CAP_NET_ADMIN))) + return -EPERM; + va_start(args, fmt); ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args); va_end(args); instead of adding complex infrastructure for something people might not want anyway? Now, the above will not necessarily work with a legacy /dev/ directory where al the nodes have been pre-populated, and opening the device node is supposed to load the module. So _historically_ we did indeed load modules as normal users. But does that really happen any more? I'd hate to default to historical behavior if there's no actual reason to do so. Linus
On Mon, Nov 27, 2017 at 11:02 AM, Linus Torvalds <torvalds@linux-foundation.org> wrote: > > Now, the above will not necessarily work with a legacy /dev/ directory > where al the nodes have been pre-populated, and opening the device > node is supposed to load the module. So _historically_ we did indeed > load modules as normal users. But does that really happen any more? Sadly, it looks like bluetoothd actually does expect to load the bt-proto-XYZ modules with no capabilities at all. So apparently we really do depend on not needing capabilities for module loading. Oh well. Linus
From: Linus Torvalds <torvalds@linux-foundation.org> Date: Mon, 27 Nov 2017 10:41:30 -0800 > What are the real life use-cases for normal users having modules > auto-load? User opens SCTP socket, SCTP protocol module loads. People build test cases via namespaces, and in that namespaces normal users can setup virtual tunnel devices themselves, and those configure operations can bring the tunnel module in.
Hi Linus, On Mon, Nov 27, 2017 at 8:12 PM, Linus Torvalds <torvalds@linux-foundation.org> wrote: > On Mon, Nov 27, 2017 at 11:02 AM, Linus Torvalds > <torvalds@linux-foundation.org> wrote: >> >> Now, the above will not necessarily work with a legacy /dev/ directory >> where al the nodes have been pre-populated, and opening the device >> node is supposed to load the module. So _historically_ we did indeed >> load modules as normal users. But does that really happen any more? > > Sadly, it looks like bluetoothd actually does expect to load the > bt-proto-XYZ modules with no capabilities at all. > > So apparently we really do depend on not needing capabilities for > module loading. > > Oh well. Yes DCCP is unprivileged, tun and all tunneling, some md drivers, some crypto, and device drivers... fs modules can be loaded inside usernamespaces, and maybe when some request requires external symbols too... However tunneling helps to solve real usecases, so that's why the backward compatibility and opt-in. I do perfectly understand that opt-in is not the best choice, however these patchset includes a per process tree, and given that lot of code is running in containers and sandboxes, it is better than nothing. I will follow up later with patches to the major ones especially when we force the flag by default. Ubuntu was said to be owned in a past security contest due to this kind of things, and now since they have ubuntu snaps or apps they can set the flag, and others will follow. Thanks! > Linus
On Tue, 28 Nov 2017, David Miller wrote: > From: Linus Torvalds <torvalds@linux-foundation.org> > Date: Mon, 27 Nov 2017 10:41:30 -0800 > > > What are the real life use-cases for normal users having modules > > auto-load? > > User opens SCTP socket, SCTP protocol module loads. > > People build test cases via namespaces, and in that namespaces normal > users can setup virtual tunnel devices themselves, and those configure > operations can bring the tunnel module in. What about implementing a white list of modules which are able to be loaded by unprivileged users? Then, Linus' solution would look something like: va_start(args, fmt); ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args); va_end(args); if (WARN_ON_ONCE(!capable(CAP_SYS_MODULE) || !capable(CAP_SYS_ADMIN) || !capable(CAP_NET_ADMIN) || !unprivileged_autoload(module_name))) return -EPERM;
On Mon, Nov 27, 2017 at 2:31 PM, James Morris <james.l.morris@oracle.com> wrote: > On Tue, 28 Nov 2017, David Miller wrote: > >> From: Linus Torvalds <torvalds@linux-foundation.org> >> Date: Mon, 27 Nov 2017 10:41:30 -0800 >> >> > What are the real life use-cases for normal users having modules >> > auto-load? >> >> User opens SCTP socket, SCTP protocol module loads. >> >> People build test cases via namespaces, and in that namespaces normal >> users can setup virtual tunnel devices themselves, and those configure >> operations can bring the tunnel module in. > > What about implementing a white list of modules which are able to be > loaded by unprivileged users? > > Then, Linus' solution would look something like: > > va_start(args, fmt); > ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args); > va_end(args); > > if (WARN_ON_ONCE(!capable(CAP_SYS_MODULE) || > !capable(CAP_SYS_ADMIN) || > !capable(CAP_NET_ADMIN) || > !unprivileged_autoload(module_name))) > return -EPERM; We have some of this already with the module prefixes. Doing this per-module would need to be exported to userspace, I think. It'd be way too fragile sitting in the kernel. To control this via modprobe, we'd need to expand modprobe to include the user that is trying to load the module (so it can reason about who is doing it), and then teach modprobe about that so the policy could be exported to userspace. -Kees
On Mon, 27 Nov 2017, Kees Cook wrote: > > if (WARN_ON_ONCE(!capable(CAP_SYS_MODULE) || > > !capable(CAP_SYS_ADMIN) || > > !capable(CAP_NET_ADMIN) || > > !unprivileged_autoload(module_name))) (Side note: the capable() calls would ideally come after the whitelist check). > We have some of this already with the module prefixes. Doing this > per-module would need to be exported to userspace, I think. It'd be > way too fragile sitting in the kernel. What about writing a whitelist to /proc (per-task) or /sys/fs (global) ? The per-task whitelist is inherited from the global one by default, or from a parent process if it's been modified in the parent.