* [PATCH v6 0/3] kexec: Add new parameter to limit the access to kexec
@ 2023-01-04 14:38 Ricardo Ribalda
2023-01-04 14:38 ` [PATCH v6 1/3] Documentation: sysctl: Correct kexec_load_disabled Ricardo Ribalda
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Ricardo Ribalda @ 2023-01-04 14:38 UTC (permalink / raw)
To: Philipp Rudo, Eric Biederman, Guilherme G. Piccoli,
Jonathan Corbet
Cc: Ricardo Ribalda, linux-doc, Sergey Senozhatsky,
Joel Fernandes (Google), Baoquan He, Petr Tesarik, kexec,
Bagas Sanjaya, Steven Rostedt, linux-kernel, Ross Zwisler
Add two parameter to specify how many times a kexec kernel can be loaded.
These parameter allow hardening the system.
While we are at it, fix a documentation issue and refactor some code.
To: Jonathan Corbet <corbet@lwn.net>
To: Eric Biederman <ebiederm@xmission.com>
Cc: linux-doc@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: kexec@lists.infradead.org
Cc: Joel Fernandes (Google) <joel@joelfernandes.org>
Cc: Sergey Senozhatsky <senozhatsky@chromium.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Ross Zwisler <zwisler@kernel.org>
To: Philipp Rudo <prudo@redhat.com>
To: Guilherme G. Piccoli <gpiccoli@igalia.com>
Cc: Bagas Sanjaya <bagasdotme@gmail.com>
Cc: Petr Tesarik <petr@tesarici.cz>
Cc: Baoquan He <bhe@redhat.com>
Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
---
Changes in v6:
- Fix kexec type on kexec_file
- Match the length of the table borders to the sections underline (Thanks Bagas!)
- Fix typo on kexec_load_limit_reboot (Thanks Petr!)
- Improve commit message (Thanks Baoquan!)
- Link to v5: https://lore.kernel.org/r/20221114-disable-kexec-reset-v5-0-1bd37caf3c75@chromium.org
Changes in v5:
- Remove maxlen from ctl_table. Thanks Steven!
- Link to v4: https://lore.kernel.org/r/20221114-disable-kexec-reset-v4-0-ab809c8d988c@chromium.org
Changes in v4 (Thanks Steven!):
- Uses sysctl instead or module_parameters
- Pass image type instead of boolean to permitted
- Fix typo on flag handling
- Return -EINVAL for values that does not change the current value.
- Link to v3: https://lore.kernel.org/r/20221114-disable-kexec-reset-v3-0-4ef4e929adf6@chromium.org
Changes in v3:
- s/paramter/parameter/ Thanks Ghilherme!
- s/permited/permitted/ Thanks Joel!
- Link to v2: https://lore.kernel.org/r/20221114-disable-kexec-reset-v2-0-c498313c1bb5@chromium.org
Changes in v2:
- Instead of kexec_reboot_disabled, add two new counters (Thanks Philipp!)
- Link to v1: https://lore.kernel.org/r/20221114-disable-kexec-reset-v1-0-fb51d20cf871@chromium.org
---
Ricardo Ribalda (3):
Documentation: sysctl: Correct kexec_load_disabled
kexec: Factor out kexec_load_permitted
kexec: Introduce sysctl parameters kexec_load_limit_*
Documentation/admin-guide/sysctl/kernel.rst | 25 +++++++-
include/linux/kexec.h | 3 +-
kernel/kexec.c | 4 +-
kernel/kexec_core.c | 94 ++++++++++++++++++++++++++++-
kernel/kexec_file.c | 11 ++--
5 files changed, 127 insertions(+), 10 deletions(-)
---
base-commit: 479174d402bcf60789106eedc4def3957c060bad
change-id: 20221114-disable-kexec-reset-19b7e117338f
Best regards,
--
Ricardo Ribalda <ribalda@chromium.org>
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v6 1/3] Documentation: sysctl: Correct kexec_load_disabled
2023-01-04 14:38 [PATCH v6 0/3] kexec: Add new parameter to limit the access to kexec Ricardo Ribalda
@ 2023-01-04 14:38 ` Ricardo Ribalda
2023-01-04 14:38 ` [PATCH v6 2/3] kexec: Factor out kexec_load_permitted Ricardo Ribalda
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Ricardo Ribalda @ 2023-01-04 14:38 UTC (permalink / raw)
To: Philipp Rudo, Eric Biederman, Guilherme G. Piccoli,
Jonathan Corbet
Cc: Ricardo Ribalda, linux-doc, Sergey Senozhatsky,
Joel Fernandes (Google), Baoquan He, Petr Tesarik, kexec,
Bagas Sanjaya, Steven Rostedt, linux-kernel, Ross Zwisler
kexec_load_disabled affects both ``kexec_load`` and ``kexec_file_load``
syscalls. Make it explicit.
Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
---
Documentation/admin-guide/sysctl/kernel.rst | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/Documentation/admin-guide/sysctl/kernel.rst b/Documentation/admin-guide/sysctl/kernel.rst
index 98d1b198b2b4..97394bd9d065 100644
--- a/Documentation/admin-guide/sysctl/kernel.rst
+++ b/Documentation/admin-guide/sysctl/kernel.rst
@@ -450,9 +450,10 @@ this allows system administrators to override the
kexec_load_disabled
===================
-A toggle indicating if the ``kexec_load`` syscall has been disabled.
-This value defaults to 0 (false: ``kexec_load`` enabled), but can be
-set to 1 (true: ``kexec_load`` disabled).
+A toggle indicating if the syscalls ``kexec_load`` and
+``kexec_file_load`` have been disabled.
+This value defaults to 0 (false: ``kexec_*load`` enabled), but can be
+set to 1 (true: ``kexec_*load`` disabled).
Once true, kexec can no longer be used, and the toggle cannot be set
back to false.
This allows a kexec image to be loaded before disabling the syscall,
--
2.39.0.314.g84b9a713c41-goog-b4-0.11.0-dev-696ae
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v6 2/3] kexec: Factor out kexec_load_permitted
2023-01-04 14:38 [PATCH v6 0/3] kexec: Add new parameter to limit the access to kexec Ricardo Ribalda
2023-01-04 14:38 ` [PATCH v6 1/3] Documentation: sysctl: Correct kexec_load_disabled Ricardo Ribalda
@ 2023-01-04 14:38 ` Ricardo Ribalda
2023-01-04 14:38 ` [PATCH v6 3/3] kexec: Introduce sysctl parameters kexec_load_limit_* Ricardo Ribalda
2023-01-10 2:32 ` [PATCH v6 0/3] kexec: Add new parameter to limit the access to kexec Baoquan He
3 siblings, 0 replies; 6+ messages in thread
From: Ricardo Ribalda @ 2023-01-04 14:38 UTC (permalink / raw)
To: Philipp Rudo, Eric Biederman, Guilherme G. Piccoli,
Jonathan Corbet
Cc: Ricardo Ribalda, linux-doc, Sergey Senozhatsky,
Joel Fernandes (Google), Baoquan He, Petr Tesarik, kexec,
Bagas Sanjaya, Steven Rostedt, linux-kernel, Ross Zwisler
Both syscalls (kexec and kexec_file) do the same check, lets factor it
out.
Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
---
include/linux/kexec.h | 3 ++-
kernel/kexec.c | 2 +-
kernel/kexec_core.c | 11 ++++++++++-
kernel/kexec_file.c | 2 +-
4 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 41a686996aaa..182e0c11b87b 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -406,7 +406,8 @@ extern int kimage_crash_copy_vmcoreinfo(struct kimage *image);
extern struct kimage *kexec_image;
extern struct kimage *kexec_crash_image;
-extern int kexec_load_disabled;
+
+bool kexec_load_permitted(void);
#ifndef kexec_flush_icache_page
#define kexec_flush_icache_page(page)
diff --git a/kernel/kexec.c b/kernel/kexec.c
index cb8e6e6f983c..ce1bca874a8d 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -193,7 +193,7 @@ static inline int kexec_load_check(unsigned long nr_segments,
int result;
/* We only trust the superuser with rebooting the system. */
- if (!capable(CAP_SYS_BOOT) || kexec_load_disabled)
+ if (!kexec_load_permitted())
return -EPERM;
/* Permit LSMs and IMA to fail the kexec */
diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
index ca2743f9c634..a1efc70f4158 100644
--- a/kernel/kexec_core.c
+++ b/kernel/kexec_core.c
@@ -928,7 +928,7 @@ int kimage_load_segment(struct kimage *image,
struct kimage *kexec_image;
struct kimage *kexec_crash_image;
-int kexec_load_disabled;
+static int kexec_load_disabled;
#ifdef CONFIG_SYSCTL
static struct ctl_table kexec_core_sysctls[] = {
{
@@ -952,6 +952,15 @@ static int __init kexec_core_sysctl_init(void)
late_initcall(kexec_core_sysctl_init);
#endif
+bool kexec_load_permitted(void)
+{
+ /*
+ * Only the superuser can use the kexec syscall and if it has not
+ * been disabled.
+ */
+ return capable(CAP_SYS_BOOT) && !kexec_load_disabled;
+}
+
/*
* No panic_cpu check version of crash_kexec(). This function is called
* only when panic_cpu holds the current CPU number; this is the only CPU
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index 45637511e0de..29efa43ea951 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -330,7 +330,7 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
struct kimage **dest_image, *image;
/* We only trust the superuser with rebooting the system. */
- if (!capable(CAP_SYS_BOOT) || kexec_load_disabled)
+ if (!kexec_load_permitted())
return -EPERM;
/* Make sure we have a legal set of flags */
--
2.39.0.314.g84b9a713c41-goog-b4-0.11.0-dev-696ae
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v6 3/3] kexec: Introduce sysctl parameters kexec_load_limit_*
2023-01-04 14:38 [PATCH v6 0/3] kexec: Add new parameter to limit the access to kexec Ricardo Ribalda
2023-01-04 14:38 ` [PATCH v6 1/3] Documentation: sysctl: Correct kexec_load_disabled Ricardo Ribalda
2023-01-04 14:38 ` [PATCH v6 2/3] kexec: Factor out kexec_load_permitted Ricardo Ribalda
@ 2023-01-04 14:38 ` Ricardo Ribalda
2023-01-10 2:31 ` Baoquan He
2023-01-10 2:32 ` [PATCH v6 0/3] kexec: Add new parameter to limit the access to kexec Baoquan He
3 siblings, 1 reply; 6+ messages in thread
From: Ricardo Ribalda @ 2023-01-04 14:38 UTC (permalink / raw)
To: Philipp Rudo, Eric Biederman, Guilherme G. Piccoli,
Jonathan Corbet
Cc: Ricardo Ribalda, linux-doc, Sergey Senozhatsky,
Joel Fernandes (Google), Baoquan He, Petr Tesarik, kexec,
Bagas Sanjaya, Steven Rostedt, linux-kernel, Ross Zwisler
kexec allows replacing the current kernel with a different one. This is
usually a source of concerns for sysadmins that want to harden a system.
Linux already provides a way to disable loading new kexec kernel via
kexec_load_disabled, but that control is very coard, it is all or
nothing and does not make distinction between a panic kexec and a
normal kexec.
This patch introduces new sysctl parameters, with finner tunning to
specify how many times a kexec kernel can be loaded. The sysadmin can
set different limits for kexec panic and kexec reboot kernels. The
value can be modified at runtime via sysctl, but only with a stricter
value.
With these new parameters on place, a system with loadpin and verity
enabled, using the following kernel parameters:
sysctl.kexec_load_limit_reboot=0 sysct.kexec_load_limit_panic=1
can have a good warranty that if initrd tries to load a panic kernel,
a malitious user will have small chances to replace that kernel with a
different one, even if they can trigger timeouts on the disk where the
panic kernel lives.
Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
---
Documentation/admin-guide/sysctl/kernel.rst | 18 ++++++
include/linux/kexec.h | 2 +-
kernel/kexec.c | 4 +-
kernel/kexec_core.c | 87 ++++++++++++++++++++++++++++-
kernel/kexec_file.c | 11 ++--
5 files changed, 114 insertions(+), 8 deletions(-)
diff --git a/Documentation/admin-guide/sysctl/kernel.rst b/Documentation/admin-guide/sysctl/kernel.rst
index 97394bd9d065..d5fb4b6ef405 100644
--- a/Documentation/admin-guide/sysctl/kernel.rst
+++ b/Documentation/admin-guide/sysctl/kernel.rst
@@ -461,6 +461,24 @@ allowing a system to set up (and later use) an image without it being
altered.
Generally used together with the `modules_disabled`_ sysctl.
+kexec_load_limit_panic
+======================
+
+This parameter specifies a limit to the number of times the syscalls
+``kexec_load`` and ``kexec_file_load`` can be called with a crash
+image. It can only be set with a more restrictive value than the
+current one.
+
+== ======================================================
+-1 Unlimited calls to kexec. This is the default setting.
+N Number of calls left.
+== ======================================================
+
+kexec_load_limit_reboot
+=======================
+
+Similar functionality as ``kexec_load_limit_panic``, but for a normal
+image.
kptr_restrict
=============
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 182e0c11b87b..791e65829f86 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -407,7 +407,7 @@ extern int kimage_crash_copy_vmcoreinfo(struct kimage *image);
extern struct kimage *kexec_image;
extern struct kimage *kexec_crash_image;
-bool kexec_load_permitted(void);
+bool kexec_load_permitted(int kexec_image_type);
#ifndef kexec_flush_icache_page
#define kexec_flush_icache_page(page)
diff --git a/kernel/kexec.c b/kernel/kexec.c
index ce1bca874a8d..92d301f98776 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -190,10 +190,12 @@ static int do_kexec_load(unsigned long entry, unsigned long nr_segments,
static inline int kexec_load_check(unsigned long nr_segments,
unsigned long flags)
{
+ int image_type = (flags & KEXEC_ON_CRASH) ?
+ KEXEC_TYPE_CRASH : KEXEC_TYPE_DEFAULT;
int result;
/* We only trust the superuser with rebooting the system. */
- if (!kexec_load_permitted())
+ if (!kexec_load_permitted(image_type))
return -EPERM;
/* Permit LSMs and IMA to fail the kexec */
diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
index a1efc70f4158..951541d78ca8 100644
--- a/kernel/kexec_core.c
+++ b/kernel/kexec_core.c
@@ -926,10 +926,64 @@ int kimage_load_segment(struct kimage *image,
return result;
}
+struct kexec_load_limit {
+ /* Mutex protects the limit count. */
+ struct mutex mutex;
+ int limit;
+};
+
+static struct kexec_load_limit load_limit_reboot = {
+ .mutex = __MUTEX_INITIALIZER(load_limit_reboot.mutex),
+ .limit = -1,
+};
+
+static struct kexec_load_limit load_limit_panic = {
+ .mutex = __MUTEX_INITIALIZER(load_limit_panic.mutex),
+ .limit = -1,
+};
+
struct kimage *kexec_image;
struct kimage *kexec_crash_image;
static int kexec_load_disabled;
+
#ifdef CONFIG_SYSCTL
+static int kexec_limit_handler(struct ctl_table *table, int write,
+ void *buffer, size_t *lenp, loff_t *ppos)
+{
+ struct kexec_load_limit *limit = table->data;
+ int val;
+ struct ctl_table tmp = {
+ .data = &val,
+ .maxlen = sizeof(val),
+ .mode = table->mode,
+ };
+ int ret;
+
+ if (write) {
+ ret = proc_dointvec(&tmp, write, buffer, lenp, ppos);
+ if (ret)
+ return ret;
+
+ if (val < 0)
+ return -EINVAL;
+
+ mutex_lock(&limit->mutex);
+ if (limit->limit != -1 && val >= limit->limit)
+ ret = -EINVAL;
+ else
+ limit->limit = val;
+ mutex_unlock(&limit->mutex);
+
+ return ret;
+ }
+
+ mutex_lock(&limit->mutex);
+ val = limit->limit;
+ mutex_unlock(&limit->mutex);
+
+ return proc_dointvec(&tmp, write, buffer, lenp, ppos);
+}
+
static struct ctl_table kexec_core_sysctls[] = {
{
.procname = "kexec_load_disabled",
@@ -941,6 +995,18 @@ static struct ctl_table kexec_core_sysctls[] = {
.extra1 = SYSCTL_ONE,
.extra2 = SYSCTL_ONE,
},
+ {
+ .procname = "kexec_load_limit_panic",
+ .data = &load_limit_panic,
+ .mode = 0644,
+ .proc_handler = kexec_limit_handler,
+ },
+ {
+ .procname = "kexec_load_limit_reboot",
+ .data = &load_limit_reboot,
+ .mode = 0644,
+ .proc_handler = kexec_limit_handler,
+ },
{ }
};
@@ -952,13 +1018,30 @@ static int __init kexec_core_sysctl_init(void)
late_initcall(kexec_core_sysctl_init);
#endif
-bool kexec_load_permitted(void)
+bool kexec_load_permitted(int kexec_image_type)
{
+ struct kexec_load_limit *limit;
+
/*
* Only the superuser can use the kexec syscall and if it has not
* been disabled.
*/
- return capable(CAP_SYS_BOOT) && !kexec_load_disabled;
+ if (!capable(CAP_SYS_BOOT) || kexec_load_disabled)
+ return false;
+
+ /* Check limit counter and decrease it.*/
+ limit = (kexec_image_type == KEXEC_TYPE_CRASH) ?
+ &load_limit_panic : &load_limit_reboot;
+ mutex_lock(&limit->mutex);
+ if (!limit->limit) {
+ mutex_unlock(&limit->mutex);
+ return false;
+ }
+ if (limit->limit != -1)
+ limit->limit--;
+ mutex_unlock(&limit->mutex);
+
+ return true;
}
/*
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index 29efa43ea951..70e1e99038ee 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -326,11 +326,13 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
unsigned long, cmdline_len, const char __user *, cmdline_ptr,
unsigned long, flags)
{
- int ret = 0, i;
+ int image_type = (flags & KEXEC_FILE_ON_CRASH) ?
+ KEXEC_TYPE_CRASH : KEXEC_TYPE_DEFAULT;
struct kimage **dest_image, *image;
+ int ret = 0, i;
/* We only trust the superuser with rebooting the system. */
- if (!kexec_load_permitted())
+ if (!kexec_load_permitted(image_type))
return -EPERM;
/* Make sure we have a legal set of flags */
@@ -342,11 +344,12 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
if (!kexec_trylock())
return -EBUSY;
- dest_image = &kexec_image;
- if (flags & KEXEC_FILE_ON_CRASH) {
+ if (image_type == KEXEC_TYPE_CRASH) {
dest_image = &kexec_crash_image;
if (kexec_crash_image)
arch_kexec_unprotect_crashkres();
+ } else {
+ dest_image = &kexec_image;
}
if (flags & KEXEC_FILE_UNLOAD)
--
2.39.0.314.g84b9a713c41-goog-b4-0.11.0-dev-696ae
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v6 3/3] kexec: Introduce sysctl parameters kexec_load_limit_*
2023-01-04 14:38 ` [PATCH v6 3/3] kexec: Introduce sysctl parameters kexec_load_limit_* Ricardo Ribalda
@ 2023-01-10 2:31 ` Baoquan He
0 siblings, 0 replies; 6+ messages in thread
From: Baoquan He @ 2023-01-10 2:31 UTC (permalink / raw)
To: Ricardo Ribalda
Cc: Philipp Rudo, Eric Biederman, Guilherme G. Piccoli,
Jonathan Corbet, linux-doc, Sergey Senozhatsky,
Joel Fernandes (Google), Petr Tesarik, kexec, Bagas Sanjaya,
Steven Rostedt, linux-kernel, Ross Zwisler
On 01/04/23 at 03:38pm, Ricardo Ribalda wrote:
> kexec allows replacing the current kernel with a different one. This is
> usually a source of concerns for sysadmins that want to harden a system.
>
> Linux already provides a way to disable loading new kexec kernel via
> kexec_load_disabled, but that control is very coard, it is all or
> nothing and does not make distinction between a panic kexec and a
> normal kexec.
>
> This patch introduces new sysctl parameters, with finner tunning to
> specify how many times a kexec kernel can be loaded. The sysadmin can
> set different limits for kexec panic and kexec reboot kernels. The
> value can be modified at runtime via sysctl, but only with a stricter
> value.
>
> With these new parameters on place, a system with loadpin and verity
> enabled, using the following kernel parameters:
> sysctl.kexec_load_limit_reboot=0 sysct.kexec_load_limit_panic=1
> can have a good warranty that if initrd tries to load a panic kernel,
> a malitious user will have small chances to replace that kernel with a
> different one, even if they can trigger timeouts on the disk where the
> panic kernel lives.
This log is much clearer, thanks for the effort. I guess distros won't
set these two knobs, while customers can make use of them to enhance the
security. E.g on production environment, peopel are more concerned about
kernel panic and getting vmcore. so they can set
'sysctl.kexec_load_limit_reboot=0 sysct.kexec_load_limit_panic=1'. Thus,
they can be suggested to customers.
Guess this is not urgent fix.
>
> Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org>
> Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
> ---
> Documentation/admin-guide/sysctl/kernel.rst | 18 ++++++
> include/linux/kexec.h | 2 +-
> kernel/kexec.c | 4 +-
> kernel/kexec_core.c | 87 ++++++++++++++++++++++++++++-
> kernel/kexec_file.c | 11 ++--
> 5 files changed, 114 insertions(+), 8 deletions(-)
>
> diff --git a/Documentation/admin-guide/sysctl/kernel.rst b/Documentation/admin-guide/sysctl/kernel.rst
> index 97394bd9d065..d5fb4b6ef405 100644
> --- a/Documentation/admin-guide/sysctl/kernel.rst
> +++ b/Documentation/admin-guide/sysctl/kernel.rst
> @@ -461,6 +461,24 @@ allowing a system to set up (and later use) an image without it being
> altered.
> Generally used together with the `modules_disabled`_ sysctl.
>
> +kexec_load_limit_panic
> +======================
> +
> +This parameter specifies a limit to the number of times the syscalls
> +``kexec_load`` and ``kexec_file_load`` can be called with a crash
> +image. It can only be set with a more restrictive value than the
> +current one.
> +
> +== ======================================================
> +-1 Unlimited calls to kexec. This is the default setting.
> +N Number of calls left.
> +== ======================================================
> +
> +kexec_load_limit_reboot
> +=======================
> +
> +Similar functionality as ``kexec_load_limit_panic``, but for a normal
> +image.
>
> kptr_restrict
> =============
> diff --git a/include/linux/kexec.h b/include/linux/kexec.h
> index 182e0c11b87b..791e65829f86 100644
> --- a/include/linux/kexec.h
> +++ b/include/linux/kexec.h
> @@ -407,7 +407,7 @@ extern int kimage_crash_copy_vmcoreinfo(struct kimage *image);
> extern struct kimage *kexec_image;
> extern struct kimage *kexec_crash_image;
>
> -bool kexec_load_permitted(void);
> +bool kexec_load_permitted(int kexec_image_type);
>
> #ifndef kexec_flush_icache_page
> #define kexec_flush_icache_page(page)
> diff --git a/kernel/kexec.c b/kernel/kexec.c
> index ce1bca874a8d..92d301f98776 100644
> --- a/kernel/kexec.c
> +++ b/kernel/kexec.c
> @@ -190,10 +190,12 @@ static int do_kexec_load(unsigned long entry, unsigned long nr_segments,
> static inline int kexec_load_check(unsigned long nr_segments,
> unsigned long flags)
> {
> + int image_type = (flags & KEXEC_ON_CRASH) ?
> + KEXEC_TYPE_CRASH : KEXEC_TYPE_DEFAULT;
> int result;
>
> /* We only trust the superuser with rebooting the system. */
> - if (!kexec_load_permitted())
> + if (!kexec_load_permitted(image_type))
> return -EPERM;
>
> /* Permit LSMs and IMA to fail the kexec */
> diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
> index a1efc70f4158..951541d78ca8 100644
> --- a/kernel/kexec_core.c
> +++ b/kernel/kexec_core.c
> @@ -926,10 +926,64 @@ int kimage_load_segment(struct kimage *image,
> return result;
> }
>
> +struct kexec_load_limit {
> + /* Mutex protects the limit count. */
> + struct mutex mutex;
> + int limit;
> +};
> +
> +static struct kexec_load_limit load_limit_reboot = {
> + .mutex = __MUTEX_INITIALIZER(load_limit_reboot.mutex),
> + .limit = -1,
> +};
> +
> +static struct kexec_load_limit load_limit_panic = {
> + .mutex = __MUTEX_INITIALIZER(load_limit_panic.mutex),
> + .limit = -1,
> +};
> +
> struct kimage *kexec_image;
> struct kimage *kexec_crash_image;
> static int kexec_load_disabled;
> +
> #ifdef CONFIG_SYSCTL
> +static int kexec_limit_handler(struct ctl_table *table, int write,
> + void *buffer, size_t *lenp, loff_t *ppos)
> +{
> + struct kexec_load_limit *limit = table->data;
> + int val;
> + struct ctl_table tmp = {
> + .data = &val,
> + .maxlen = sizeof(val),
> + .mode = table->mode,
> + };
> + int ret;
> +
> + if (write) {
> + ret = proc_dointvec(&tmp, write, buffer, lenp, ppos);
> + if (ret)
> + return ret;
> +
> + if (val < 0)
> + return -EINVAL;
> +
> + mutex_lock(&limit->mutex);
> + if (limit->limit != -1 && val >= limit->limit)
> + ret = -EINVAL;
> + else
> + limit->limit = val;
> + mutex_unlock(&limit->mutex);
> +
> + return ret;
> + }
> +
> + mutex_lock(&limit->mutex);
> + val = limit->limit;
> + mutex_unlock(&limit->mutex);
> +
> + return proc_dointvec(&tmp, write, buffer, lenp, ppos);
> +}
> +
> static struct ctl_table kexec_core_sysctls[] = {
> {
> .procname = "kexec_load_disabled",
> @@ -941,6 +995,18 @@ static struct ctl_table kexec_core_sysctls[] = {
> .extra1 = SYSCTL_ONE,
> .extra2 = SYSCTL_ONE,
> },
> + {
> + .procname = "kexec_load_limit_panic",
> + .data = &load_limit_panic,
> + .mode = 0644,
> + .proc_handler = kexec_limit_handler,
> + },
> + {
> + .procname = "kexec_load_limit_reboot",
> + .data = &load_limit_reboot,
> + .mode = 0644,
> + .proc_handler = kexec_limit_handler,
> + },
> { }
> };
>
> @@ -952,13 +1018,30 @@ static int __init kexec_core_sysctl_init(void)
> late_initcall(kexec_core_sysctl_init);
> #endif
>
> -bool kexec_load_permitted(void)
> +bool kexec_load_permitted(int kexec_image_type)
> {
> + struct kexec_load_limit *limit;
> +
> /*
> * Only the superuser can use the kexec syscall and if it has not
> * been disabled.
> */
> - return capable(CAP_SYS_BOOT) && !kexec_load_disabled;
> + if (!capable(CAP_SYS_BOOT) || kexec_load_disabled)
> + return false;
> +
> + /* Check limit counter and decrease it.*/
> + limit = (kexec_image_type == KEXEC_TYPE_CRASH) ?
> + &load_limit_panic : &load_limit_reboot;
> + mutex_lock(&limit->mutex);
> + if (!limit->limit) {
> + mutex_unlock(&limit->mutex);
> + return false;
> + }
> + if (limit->limit != -1)
> + limit->limit--;
> + mutex_unlock(&limit->mutex);
> +
> + return true;
> }
>
> /*
> diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
> index 29efa43ea951..70e1e99038ee 100644
> --- a/kernel/kexec_file.c
> +++ b/kernel/kexec_file.c
> @@ -326,11 +326,13 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
> unsigned long, cmdline_len, const char __user *, cmdline_ptr,
> unsigned long, flags)
> {
> - int ret = 0, i;
> + int image_type = (flags & KEXEC_FILE_ON_CRASH) ?
> + KEXEC_TYPE_CRASH : KEXEC_TYPE_DEFAULT;
> struct kimage **dest_image, *image;
> + int ret = 0, i;
>
> /* We only trust the superuser with rebooting the system. */
> - if (!kexec_load_permitted())
> + if (!kexec_load_permitted(image_type))
> return -EPERM;
>
> /* Make sure we have a legal set of flags */
> @@ -342,11 +344,12 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
> if (!kexec_trylock())
> return -EBUSY;
>
> - dest_image = &kexec_image;
> - if (flags & KEXEC_FILE_ON_CRASH) {
> + if (image_type == KEXEC_TYPE_CRASH) {
> dest_image = &kexec_crash_image;
> if (kexec_crash_image)
> arch_kexec_unprotect_crashkres();
> + } else {
> + dest_image = &kexec_image;
> }
>
> if (flags & KEXEC_FILE_UNLOAD)
>
> --
> 2.39.0.314.g84b9a713c41-goog-b4-0.11.0-dev-696ae
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v6 0/3] kexec: Add new parameter to limit the access to kexec
2023-01-04 14:38 [PATCH v6 0/3] kexec: Add new parameter to limit the access to kexec Ricardo Ribalda
` (2 preceding siblings ...)
2023-01-04 14:38 ` [PATCH v6 3/3] kexec: Introduce sysctl parameters kexec_load_limit_* Ricardo Ribalda
@ 2023-01-10 2:32 ` Baoquan He
3 siblings, 0 replies; 6+ messages in thread
From: Baoquan He @ 2023-01-10 2:32 UTC (permalink / raw)
To: Ricardo Ribalda, akpm
Cc: Philipp Rudo, Eric Biederman, Guilherme G. Piccoli,
Jonathan Corbet, linux-doc, Sergey Senozhatsky,
Joel Fernandes (Google), Petr Tesarik, kexec, Bagas Sanjaya,
Steven Rostedt, linux-kernel, Ross Zwisler
On 01/04/23 at 03:38pm, Ricardo Ribalda wrote:
> Add two parameter to specify how many times a kexec kernel can be loaded.
>
> These parameter allow hardening the system.
>
> While we are at it, fix a documentation issue and refactor some code.
The whole series looks good to me, thx.
Acked-by: Baoquan He <bhe@redhat.com>
>
> To: Jonathan Corbet <corbet@lwn.net>
> To: Eric Biederman <ebiederm@xmission.com>
> Cc: linux-doc@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> Cc: kexec@lists.infradead.org
> Cc: Joel Fernandes (Google) <joel@joelfernandes.org>
> Cc: Sergey Senozhatsky <senozhatsky@chromium.org>
> Cc: Steven Rostedt <rostedt@goodmis.org>
> Cc: Ross Zwisler <zwisler@kernel.org>
> To: Philipp Rudo <prudo@redhat.com>
> To: Guilherme G. Piccoli <gpiccoli@igalia.com>
> Cc: Bagas Sanjaya <bagasdotme@gmail.com>
> Cc: Petr Tesarik <petr@tesarici.cz>
> Cc: Baoquan He <bhe@redhat.com>
> Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
>
> ---
> Changes in v6:
> - Fix kexec type on kexec_file
> - Match the length of the table borders to the sections underline (Thanks Bagas!)
> - Fix typo on kexec_load_limit_reboot (Thanks Petr!)
> - Improve commit message (Thanks Baoquan!)
> - Link to v5: https://lore.kernel.org/r/20221114-disable-kexec-reset-v5-0-1bd37caf3c75@chromium.org
>
> Changes in v5:
> - Remove maxlen from ctl_table. Thanks Steven!
> - Link to v4: https://lore.kernel.org/r/20221114-disable-kexec-reset-v4-0-ab809c8d988c@chromium.org
>
> Changes in v4 (Thanks Steven!):
> - Uses sysctl instead or module_parameters
> - Pass image type instead of boolean to permitted
> - Fix typo on flag handling
> - Return -EINVAL for values that does not change the current value.
> - Link to v3: https://lore.kernel.org/r/20221114-disable-kexec-reset-v3-0-4ef4e929adf6@chromium.org
>
> Changes in v3:
> - s/paramter/parameter/ Thanks Ghilherme!
> - s/permited/permitted/ Thanks Joel!
> - Link to v2: https://lore.kernel.org/r/20221114-disable-kexec-reset-v2-0-c498313c1bb5@chromium.org
>
> Changes in v2:
> - Instead of kexec_reboot_disabled, add two new counters (Thanks Philipp!)
> - Link to v1: https://lore.kernel.org/r/20221114-disable-kexec-reset-v1-0-fb51d20cf871@chromium.org
>
> ---
> Ricardo Ribalda (3):
> Documentation: sysctl: Correct kexec_load_disabled
> kexec: Factor out kexec_load_permitted
> kexec: Introduce sysctl parameters kexec_load_limit_*
>
> Documentation/admin-guide/sysctl/kernel.rst | 25 +++++++-
> include/linux/kexec.h | 3 +-
> kernel/kexec.c | 4 +-
> kernel/kexec_core.c | 94 ++++++++++++++++++++++++++++-
> kernel/kexec_file.c | 11 ++--
> 5 files changed, 127 insertions(+), 10 deletions(-)
> ---
> base-commit: 479174d402bcf60789106eedc4def3957c060bad
> change-id: 20221114-disable-kexec-reset-19b7e117338f
>
> Best regards,
> --
> Ricardo Ribalda <ribalda@chromium.org>
>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2023-01-10 2:33 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-01-04 14:38 [PATCH v6 0/3] kexec: Add new parameter to limit the access to kexec Ricardo Ribalda
2023-01-04 14:38 ` [PATCH v6 1/3] Documentation: sysctl: Correct kexec_load_disabled Ricardo Ribalda
2023-01-04 14:38 ` [PATCH v6 2/3] kexec: Factor out kexec_load_permitted Ricardo Ribalda
2023-01-04 14:38 ` [PATCH v6 3/3] kexec: Introduce sysctl parameters kexec_load_limit_* Ricardo Ribalda
2023-01-10 2:31 ` Baoquan He
2023-01-10 2:32 ` [PATCH v6 0/3] kexec: Add new parameter to limit the access to kexec Baoquan He
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).