From aec71d794731c441a9b7ee9705efedd2f6054173 Mon Sep 17 00:00:00 2001 From: Miroslav Benes Date: Tue, 7 May 2019 15:08:14 +0200 Subject: [PATCH 1/5] livepatch: Remove stale kobj_added entries from kernel-doc descriptions Commit 4d141ab3416d ("livepatch: Remove custom kobject state handling") removed kobj_added members of klp_func, klp_object and klp_patch structures. kernel-doc descriptions were omitted by accident. Remove them. Reported-by: Kamalesh Babulal Signed-off-by: Miroslav Benes Acked-by: Joe Lawrence Reviewed-by: Kamalesh Babulal Signed-off-by: Jiri Kosina --- include/linux/livepatch.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/linux/livepatch.h b/include/linux/livepatch.h index a14bab1a0a3e..955d46f37b72 100644 --- a/include/linux/livepatch.h +++ b/include/linux/livepatch.h @@ -47,7 +47,6 @@ * @stack_node: list node for klp_ops func_stack list * @old_size: size of the old function * @new_size: size of the new function - * @kobj_added: @kobj has been added and needs freeing * @nop: temporary patch to use the original code again; dyn. allocated * @patched: the func has been added to the klp_ops list * @transition: the func is currently being applied or reverted @@ -125,7 +124,6 @@ struct klp_callbacks { * @node: list node for klp_patch obj_list * @mod: kernel module associated with the patched object * (NULL for vmlinux) - * @kobj_added: @kobj has been added and needs freeing * @dynamic: temporary object for nop functions; dynamically allocated * @patched: the object's funcs have been added to the klp_ops list */ @@ -152,7 +150,6 @@ struct klp_object { * @list: list node for global list of actively used patches * @kobj: kobject for sysfs resources * @obj_list: dynamic list of the object entries - * @kobj_added: @kobj has been added and needs freeing * @enabled: the patch is enabled (but operation may be incomplete) * @forced: was involved in a forced transition * @free_work: patch cleanup from workqueue-context From f36e664516b02c7f54bbd3094bab047d54bb5488 Mon Sep 17 00:00:00 2001 From: Petr Mladek Date: Fri, 31 May 2019 09:41:47 +0200 Subject: [PATCH 2/5] livepatch: Use static buffer for debugging messages under rq lock The err_buf array uses 128 bytes of stack space. Move it off the stack by making it static. It's safe to use a shared buffer because klp_try_switch_task() is called under klp_mutex. Acked-by: Miroslav Benes Acked-by: Josh Poimboeuf Reviewed-by: Kamalesh Babulal Signed-off-by: Petr Mladek --- kernel/livepatch/transition.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kernel/livepatch/transition.c b/kernel/livepatch/transition.c index c53370d596be..0a3889c4f617 100644 --- a/kernel/livepatch/transition.c +++ b/kernel/livepatch/transition.c @@ -293,11 +293,11 @@ static int klp_check_stack(struct task_struct *task, char *err_buf) */ static bool klp_try_switch_task(struct task_struct *task) { + static char err_buf[STACK_ERR_BUF_SIZE]; struct rq *rq; struct rq_flags flags; int ret; bool success = false; - char err_buf[STACK_ERR_BUF_SIZE]; err_buf[0] = '\0'; @@ -340,7 +340,6 @@ done: pr_debug("%s", err_buf); return success; - } /* From 380178ef7fde58f2040788a1bab972ce4867ac58 Mon Sep 17 00:00:00 2001 From: Miroslav Benes Date: Tue, 11 Jun 2019 16:13:18 +0200 Subject: [PATCH 3/5] stacktrace: Remove weak version of save_stack_trace_tsk_reliable() Recent rework of stack trace infrastructure introduced a new set of helpers for common stack trace operations (commit e9b98e162aa5 ("stacktrace: Provide helpers for common stack trace operations") and related). As a result, save_stack_trace_tsk_reliable() is not directly called anywhere. Livepatch, currently the only user of the reliable stack trace feature, now calls stack_trace_save_tsk_reliable(). When CONFIG_HAVE_RELIABLE_STACKTRACE is set and depending on CONFIG_ARCH_STACKWALK, stack_trace_save_tsk_reliable() calls either arch_stack_walk_reliable() or mentioned save_stack_trace_tsk_reliable(). x86_64 defines the former, ppc64le the latter. All other architectures do not have HAVE_RELIABLE_STACKTRACE and include/linux/stacktrace.h defines -ENOSYS returning version for them. In short, stack_trace_save_tsk_reliable() returning -ENOSYS defined in include/linux/stacktrace.h serves the same purpose as the old weak version of save_stack_trace_tsk_reliable() which is therefore no longer needed. Signed-off-by: Miroslav Benes Acked-by: Josh Poimboeuf Reviewed-by: Thomas Gleixner Reviewed-by: Kamalesh Babulal Signed-off-by: Petr Mladek --- kernel/stacktrace.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/kernel/stacktrace.c b/kernel/stacktrace.c index 27bafc1e271e..319e7fcf3083 100644 --- a/kernel/stacktrace.c +++ b/kernel/stacktrace.c @@ -254,14 +254,6 @@ save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace) WARN_ONCE(1, KERN_INFO "save_stack_trace_regs() not implemented yet.\n"); } -__weak int -save_stack_trace_tsk_reliable(struct task_struct *tsk, - struct stack_trace *trace) -{ - WARN_ONCE(1, KERN_INFO "save_stack_tsk_reliable() not implemented yet.\n"); - return -ENOSYS; -} - /** * stack_trace_save - Save a stack trace into a storage array * @store: Pointer to storage array From 67059d65f7da537c41513fc52e78eff096092b8c Mon Sep 17 00:00:00 2001 From: Miroslav Benes Date: Tue, 11 Jun 2019 16:13:19 +0200 Subject: [PATCH 4/5] Revert "livepatch: Remove reliable stacktrace check in klp_try_switch_task()" This reverts commit 1d98a69e5cef3aeb68bcefab0e67e342d6bb4dad. Commit 31adf2308f33 ("livepatch: Convert error about unsupported reliable stacktrace into a warning") weakened the enforcement for architectures to have reliable stack traces support. The system only warns now about it. It only makes sense to reintroduce the compile time checking in klp_try_switch_task() again and bail out early. Signed-off-by: Miroslav Benes Acked-by: Josh Poimboeuf Reviewed-by: Kamalesh Babulal Signed-off-by: Petr Mladek --- kernel/livepatch/transition.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/kernel/livepatch/transition.c b/kernel/livepatch/transition.c index 0a3889c4f617..cb85dae09ce5 100644 --- a/kernel/livepatch/transition.c +++ b/kernel/livepatch/transition.c @@ -305,6 +305,13 @@ static bool klp_try_switch_task(struct task_struct *task) if (task->patch_state == klp_target_state) return true; + /* + * For arches which don't have reliable stack traces, we have to rely + * on other methods (e.g., switching tasks at kernel exit). + */ + if (!klp_have_reliable_stack()) + return false; + /* * Now try to check the stack for any to-be-patched or to-be-unpatched * functions. If all goes well, switch the task to the target patch From ac59a471e9371e3184425efd6a2fd8ac5c7e4c2b Mon Sep 17 00:00:00 2001 From: Petr Mladek Date: Tue, 11 Jun 2019 16:13:20 +0200 Subject: [PATCH 5/5] livepatch: Remove duplicate warning about missing reliable stacktrace support WARN_ON_ONCE() could not be called safely under rq lock because of console deadlock issues. Moreover WARN_ON_ONCE() is superfluous in klp_check_stack(), because stack_trace_save_tsk_reliable() cannot return -ENOSYS thanks to klp_have_reliable_stack() check in klp_try_switch_task(). [ mbenes: changelog edited ] Signed-off-by: Miroslav Benes Acked-by: Josh Poimboeuf Reviewed-by: Kamalesh Babulal Signed-off-by: Petr Mladek --- kernel/livepatch/transition.c | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/livepatch/transition.c b/kernel/livepatch/transition.c index cb85dae09ce5..3c764e73b032 100644 --- a/kernel/livepatch/transition.c +++ b/kernel/livepatch/transition.c @@ -259,7 +259,6 @@ static int klp_check_stack(struct task_struct *task, char *err_buf) int ret, nr_entries; ret = stack_trace_save_tsk_reliable(task, entries, ARRAY_SIZE(entries)); - WARN_ON_ONCE(ret == -ENOSYS); if (ret < 0) { snprintf(err_buf, STACK_ERR_BUF_SIZE, "%s: %s:%d has an unreliable stack\n",