Re: [PATCH v5 next 0/5] Improve Module autoloading infrastructure
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. -- James Morris
Re: [PATCH v5 next 0/5] Improve Module autoloading infrastructure
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. -- James Morris
Re: [PATCH v5 next 0/5] Improve Module autoloading infrastructure
On Mon, Nov 27, 2017 at 2:31 PM, James Morriswrote: > On Tue, 28 Nov 2017, David Miller wrote: > >> From: Linus Torvalds >> 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 -- Kees Cook Pixel Security
Re: [PATCH v5 next 0/5] Improve Module autoloading infrastructure
On Mon, Nov 27, 2017 at 2:31 PM, James Morris wrote: > On Tue, 28 Nov 2017, David Miller wrote: > >> From: Linus Torvalds >> 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 -- Kees Cook Pixel Security
Re: [PATCH v5 next 0/5] Improve Module autoloading infrastructure
On Tue, 28 Nov 2017, David Miller wrote: > From: Linus Torvalds> 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; -- James Morris
Re: [PATCH v5 next 0/5] Improve Module autoloading infrastructure
On Tue, 28 Nov 2017, David Miller wrote: > From: Linus Torvalds > 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; -- James Morris
Re: [PATCH v5 next 0/5] Improve Module autoloading infrastructure
Hi Linus, On Mon, Nov 27, 2017 at 8:12 PM, Linus Torvaldswrote: > On Mon, Nov 27, 2017 at 11:02 AM, Linus Torvalds > 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 -- tixxdz
Re: [PATCH v5 next 0/5] Improve Module autoloading infrastructure
Hi Linus, On Mon, Nov 27, 2017 at 8:12 PM, Linus Torvalds wrote: > On Mon, Nov 27, 2017 at 11:02 AM, Linus Torvalds > 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 -- tixxdz
Re: [PATCH v5 next 0/5] Improve Module autoloading infrastructure
From: Linus TorvaldsDate: 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.
Re: [PATCH v5 next 0/5] Improve Module autoloading infrastructure
From: Linus Torvalds 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.
Re: [PATCH v5 next 0/5] Improve Module autoloading infrastructure
On Mon, Nov 27, 2017 at 11:02 AM, Linus Torvaldswrote: > > 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
Re: [PATCH v5 next 0/5] Improve Module autoloading infrastructure
On Mon, Nov 27, 2017 at 11:02 AM, Linus Torvalds 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
Re: [PATCH v5 next 0/5] Improve Module autoloading infrastructure
On Mon, Nov 27, 2017 at 10:41 AM, Linus Torvaldswrote: > > 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
Re: [PATCH v5 next 0/5] Improve Module autoloading infrastructure
On Mon, Nov 27, 2017 at 10:41 AM, Linus Torvalds 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
Re: [PATCH v5 next 0/5] Improve Module autoloading infrastructure
On Mon, Nov 27, 2017 at 9:18 AM, Djalal Harouniwrote: > > 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
Re: [PATCH v5 next 0/5] Improve Module autoloading infrastructure
On Mon, Nov 27, 2017 at 9:18 AM, Djalal Harouni 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
[PATCH v5 next 0/5] Improve Module autoloading infrastructure
Hi List, This is v5 of automatic module load restriction series. I have renamed it to 'Improve Module autoloading infrastructure' for abvious reasons: * It is more of an infrastructure change now. * Reduce the use of word 'restriction' and use 'improving' maybe easy to sell ? These patches are based on next-20171127 Credits: The idea was inspired from grsecurity 'GRKERNSEC_MODHARDEN' config option. However, upstream Linux implementation is more focused on the run-time behavior with a three mode switch, plus upstream version solves Linux usecases with a per process tree flag that can be used in containers, sandboxes, etc to block direct implicit auto-load operations. This implementation does not share anything with grsecurity. The first RFC was as LSM, Kees Cook and others suggested that it can be turned as a core kernel feature and after some months, they were right. Previous versions: == v1 RFC as an LSM: http://www.openwall.com/lists/kernel-hardening/2017/02/02/21 v2 RFC as an LSM: http://www.openwall.com/lists/kernel-hardening/2017/04/09/1 v3 core feature as requested by kernel maintainers: https://lkml.org/lkml/2017/4/19/1086 v4: https://lkml.org/lkml/2017/5/22/312 All previous feedback from: Andy Lutomirski, Solar Designer, Kees Cook, Rusty Russell, Ben Hutchings and Serge Hallyn is fixed in this series. Please check Changelog for details. Thank you for the feedback. == Currently, an explicit call to load or unload kernel modules require CAP_SYS_MODULE capability. However unprivileged users have always been able to load some modules using the implicit auto-load operation. An automatic module loading happens when programs request a kernel feature from a module that is not loaded. In order to satisfy userspace, the kernel then automatically load all these required modules. Historically, the kernel was always able to automatically load modules if they are not blacklisted. This is one of the most important and transparent operations of Linux, it allows to provide numerous other features as they are needed which is crucial for a better user experience. However, as Linux is popular now and used for different appliances some of these may need to control such operations. For such systems, recent needs showed that in some cases allowing to control automatic module loading is as important as the operation itself. Restricting unprivileged programs or attackers that abuse this feature to load unused modules or modules that contain bugs is a significant security measure. This allows administrators or some special programs to have the appropriate time to update and deny module autoloading in advance, then blacklist the corresponding ones. Not doing so may affect the global state of the machine, especially containers where some apps are moved from one context to another and not having such mechanisms may allow to expose and exploit the vulnerable parts to escape the container sandbox. Embedded or IoT devices also started to ship as containers using generic distros, some vendors do not have the appropriate time to make their own OS, hence, using base images is getting popular. These setups may include unnecessary modules that the final applications will not need. Untrusted access may abuse the module auto-load feature to expose vulnerabilities. As every code contains bugs or vulnerabilties, the following vulnerabilities that affected some features that are often compiled as modules could have been completely blocked, by a better mechanism that handles module autoloading, especially if the system does not need them. Past months: * DCCP use after free CVE-2017-6074 [1] [2] Unprivileged to local root. * XFRM framework CVE-2017-7184 [3] As advertised it seems it was used to break Ubuntu on a security contest. * n_hldc CVE-2017-2636 [4] [5] Local privilege escalation. * L2TPv3 CVE-2016-10200 The list is longer. To improve the current status, this series tries to re-work how module autoloading is performed by adding two new properties: "modules_autoload_mode" sysctl flag, and a per-task one. The sysctl controls modules auto-load feature and complements "modules_disabled" which apply to all modules operations. This new flag allows to control only automatic module loading and if it is allowed or not, aligning in the process the implicit operation with the explicit one where both now are covered by capabilities checks. The three modes that "modules_autoload_mode" support allow to provide restrictions on automatic module loading without breaking user experience. 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. When modules_autoload_mode is set to (1), processes must have CAP_SYS_MODULE to be able to trigger a module auto-load operation, or CAP_NET_ADMIN for modules with a 'netdev-%s' alias, or other capabilities for specific aliased modules.
[PATCH v5 next 0/5] Improve Module autoloading infrastructure
Hi List, This is v5 of automatic module load restriction series. I have renamed it to 'Improve Module autoloading infrastructure' for abvious reasons: * It is more of an infrastructure change now. * Reduce the use of word 'restriction' and use 'improving' maybe easy to sell ? These patches are based on next-20171127 Credits: The idea was inspired from grsecurity 'GRKERNSEC_MODHARDEN' config option. However, upstream Linux implementation is more focused on the run-time behavior with a three mode switch, plus upstream version solves Linux usecases with a per process tree flag that can be used in containers, sandboxes, etc to block direct implicit auto-load operations. This implementation does not share anything with grsecurity. The first RFC was as LSM, Kees Cook and others suggested that it can be turned as a core kernel feature and after some months, they were right. Previous versions: == v1 RFC as an LSM: http://www.openwall.com/lists/kernel-hardening/2017/02/02/21 v2 RFC as an LSM: http://www.openwall.com/lists/kernel-hardening/2017/04/09/1 v3 core feature as requested by kernel maintainers: https://lkml.org/lkml/2017/4/19/1086 v4: https://lkml.org/lkml/2017/5/22/312 All previous feedback from: Andy Lutomirski, Solar Designer, Kees Cook, Rusty Russell, Ben Hutchings and Serge Hallyn is fixed in this series. Please check Changelog for details. Thank you for the feedback. == Currently, an explicit call to load or unload kernel modules require CAP_SYS_MODULE capability. However unprivileged users have always been able to load some modules using the implicit auto-load operation. An automatic module loading happens when programs request a kernel feature from a module that is not loaded. In order to satisfy userspace, the kernel then automatically load all these required modules. Historically, the kernel was always able to automatically load modules if they are not blacklisted. This is one of the most important and transparent operations of Linux, it allows to provide numerous other features as they are needed which is crucial for a better user experience. However, as Linux is popular now and used for different appliances some of these may need to control such operations. For such systems, recent needs showed that in some cases allowing to control automatic module loading is as important as the operation itself. Restricting unprivileged programs or attackers that abuse this feature to load unused modules or modules that contain bugs is a significant security measure. This allows administrators or some special programs to have the appropriate time to update and deny module autoloading in advance, then blacklist the corresponding ones. Not doing so may affect the global state of the machine, especially containers where some apps are moved from one context to another and not having such mechanisms may allow to expose and exploit the vulnerable parts to escape the container sandbox. Embedded or IoT devices also started to ship as containers using generic distros, some vendors do not have the appropriate time to make their own OS, hence, using base images is getting popular. These setups may include unnecessary modules that the final applications will not need. Untrusted access may abuse the module auto-load feature to expose vulnerabilities. As every code contains bugs or vulnerabilties, the following vulnerabilities that affected some features that are often compiled as modules could have been completely blocked, by a better mechanism that handles module autoloading, especially if the system does not need them. Past months: * DCCP use after free CVE-2017-6074 [1] [2] Unprivileged to local root. * XFRM framework CVE-2017-7184 [3] As advertised it seems it was used to break Ubuntu on a security contest. * n_hldc CVE-2017-2636 [4] [5] Local privilege escalation. * L2TPv3 CVE-2016-10200 The list is longer. To improve the current status, this series tries to re-work how module autoloading is performed by adding two new properties: "modules_autoload_mode" sysctl flag, and a per-task one. The sysctl controls modules auto-load feature and complements "modules_disabled" which apply to all modules operations. This new flag allows to control only automatic module loading and if it is allowed or not, aligning in the process the implicit operation with the explicit one where both now are covered by capabilities checks. The three modes that "modules_autoload_mode" support allow to provide restrictions on automatic module loading without breaking user experience. 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. When modules_autoload_mode is set to (1), processes must have CAP_SYS_MODULE to be able to trigger a module auto-load operation, or CAP_NET_ADMIN for modules with a 'netdev-%s' alias, or other capabilities for specific aliased modules.