aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/livepatch
diff options
context:
space:
mode:
authorMiroslav Benes <mbenes@suse.cz>2018-01-10 05:01:28 -0500
committerJiri Kosina <jkosina@suse.cz>2018-01-11 04:58:03 -0500
commitd0807da78e11d46f18399cbf8c4028c731346766 (patch)
tree7421d9d68ae0d159c816995564984a0c0cfcc26a /kernel/livepatch
parentc99a2be790b07752d8cc694434d3450afd4c5a00 (diff)
livepatch: Remove immediate feature
Immediate flag has been used to disable per-task consistency and patch all tasks immediately. It could be useful if the patch doesn't change any function or data semantics. However, it causes problems on its own. The consistency problem is currently broken with respect to immediate patches. func a patches 1i 2i 3 When the patch 3 is applied, only 2i function is checked (by stack checking facility). There might be a task sleeping in 1i though. Such task is migrated to 3, because we do not check 1i in klp_check_stack_func() at all. Coming atomic replace feature would be easier to implement and more reliable without immediate. Thus, remove immediate feature completely and save us from the problems. Note that force feature has the similar problem. However it is considered as a last resort. If used, administrator should not apply any new live patches and should plan for reboot into an updated kernel. The architectures would now need to provide HAVE_RELIABLE_STACKTRACE to fully support livepatch. Signed-off-by: Miroslav Benes <mbenes@suse.cz> Acked-by: Josh Poimboeuf <jpoimboe@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'kernel/livepatch')
-rw-r--r--kernel/livepatch/core.c12
-rw-r--r--kernel/livepatch/transition.c49
2 files changed, 6 insertions, 55 deletions
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
index 1c3c9b27c916..41be6061b92f 100644
--- a/kernel/livepatch/core.c
+++ b/kernel/livepatch/core.c
@@ -366,11 +366,6 @@ static int __klp_enable_patch(struct klp_patch *patch)
366 /* 366 /*
367 * A reference is taken on the patch module to prevent it from being 367 * A reference is taken on the patch module to prevent it from being
368 * unloaded. 368 * unloaded.
369 *
370 * Note: For immediate (no consistency model) patches we don't allow
371 * patch modules to unload since there is no safe/sane method to
372 * determine if a thread is still running in the patched code contained
373 * in the patch module once the ftrace registration is successful.
374 */ 369 */
375 if (!try_module_get(patch->mod)) 370 if (!try_module_get(patch->mod))
376 return -ENODEV; 371 return -ENODEV;
@@ -890,12 +885,7 @@ int klp_register_patch(struct klp_patch *patch)
890 if (!klp_initialized()) 885 if (!klp_initialized())
891 return -ENODEV; 886 return -ENODEV;
892 887
893 /* 888 if (!klp_have_reliable_stack()) {
894 * Architectures without reliable stack traces have to set
895 * patch->immediate because there's currently no way to patch kthreads
896 * with the consistency model.
897 */
898 if (!klp_have_reliable_stack() && !patch->immediate) {
899 pr_err("This architecture doesn't have support for the livepatch consistency model.\n"); 889 pr_err("This architecture doesn't have support for the livepatch consistency model.\n");
900 return -ENOSYS; 890 return -ENOSYS;
901 } 891 }
diff --git a/kernel/livepatch/transition.c b/kernel/livepatch/transition.c
index be5bfa533ee8..7c6631e693bc 100644
--- a/kernel/livepatch/transition.c
+++ b/kernel/livepatch/transition.c
@@ -82,7 +82,6 @@ static void klp_complete_transition(void)
82 struct klp_func *func; 82 struct klp_func *func;
83 struct task_struct *g, *task; 83 struct task_struct *g, *task;
84 unsigned int cpu; 84 unsigned int cpu;
85 bool immediate_func = false;
86 85
87 pr_debug("'%s': completing %s transition\n", 86 pr_debug("'%s': completing %s transition\n",
88 klp_transition_patch->mod->name, 87 klp_transition_patch->mod->name,
@@ -104,16 +103,9 @@ static void klp_complete_transition(void)
104 klp_synchronize_transition(); 103 klp_synchronize_transition();
105 } 104 }
106 105
107 if (klp_transition_patch->immediate) 106 klp_for_each_object(klp_transition_patch, obj)
108 goto done; 107 klp_for_each_func(obj, func)
109
110 klp_for_each_object(klp_transition_patch, obj) {
111 klp_for_each_func(obj, func) {
112 func->transition = false; 108 func->transition = false;
113 if (func->immediate)
114 immediate_func = true;
115 }
116 }
117 109
118 /* Prevent klp_ftrace_handler() from seeing KLP_UNDEFINED state */ 110 /* Prevent klp_ftrace_handler() from seeing KLP_UNDEFINED state */
119 if (klp_target_state == KLP_PATCHED) 111 if (klp_target_state == KLP_PATCHED)
@@ -132,7 +124,6 @@ static void klp_complete_transition(void)
132 task->patch_state = KLP_UNDEFINED; 124 task->patch_state = KLP_UNDEFINED;
133 } 125 }
134 126
135done:
136 klp_for_each_object(klp_transition_patch, obj) { 127 klp_for_each_object(klp_transition_patch, obj) {
137 if (!klp_is_object_loaded(obj)) 128 if (!klp_is_object_loaded(obj))
138 continue; 129 continue;
@@ -146,16 +137,11 @@ done:
146 klp_target_state == KLP_PATCHED ? "patching" : "unpatching"); 137 klp_target_state == KLP_PATCHED ? "patching" : "unpatching");
147 138
148 /* 139 /*
149 * See complementary comment in __klp_enable_patch() for why we 140 * klp_forced set implies unbounded increase of module's ref count if
150 * keep the module reference for immediate patches. 141 * the module is disabled/enabled in a loop.
151 *
152 * klp_forced or immediate_func set implies unbounded increase of
153 * module's ref count if the module is disabled/enabled in a loop.
154 */ 142 */
155 if (!klp_forced && !klp_transition_patch->immediate && 143 if (!klp_forced && klp_target_state == KLP_UNPATCHED)
156 !immediate_func && klp_target_state == KLP_UNPATCHED) {
157 module_put(klp_transition_patch->mod); 144 module_put(klp_transition_patch->mod);
158 }
159 145
160 klp_target_state = KLP_UNDEFINED; 146 klp_target_state = KLP_UNDEFINED;
161 klp_transition_patch = NULL; 147 klp_transition_patch = NULL;
@@ -223,9 +209,6 @@ static int klp_check_stack_func(struct klp_func *func,
223 struct klp_ops *ops; 209 struct klp_ops *ops;
224 int i; 210 int i;
225 211
226 if (func->immediate)
227 return 0;
228
229 for (i = 0; i < trace->nr_entries; i++) { 212 for (i = 0; i < trace->nr_entries; i++) {
230 address = trace->entries[i]; 213 address = trace->entries[i];
231 214
@@ -388,13 +371,6 @@ void klp_try_complete_transition(void)
388 WARN_ON_ONCE(klp_target_state == KLP_UNDEFINED); 371 WARN_ON_ONCE(klp_target_state == KLP_UNDEFINED);
389 372
390 /* 373 /*
391 * If the patch can be applied or reverted immediately, skip the
392 * per-task transitions.
393 */
394 if (klp_transition_patch->immediate)
395 goto success;
396
397 /*
398 * Try to switch the tasks to the target patch state by walking their 374 * Try to switch the tasks to the target patch state by walking their
399 * stacks and looking for any to-be-patched or to-be-unpatched 375 * stacks and looking for any to-be-patched or to-be-unpatched
400 * functions. If such functions are found on a stack, or if the stack 376 * functions. If such functions are found on a stack, or if the stack
@@ -437,7 +413,6 @@ void klp_try_complete_transition(void)
437 return; 413 return;
438 } 414 }
439 415
440success:
441 /* we're done, now cleanup the data structures */ 416 /* we're done, now cleanup the data structures */
442 klp_complete_transition(); 417 klp_complete_transition();
443} 418}
@@ -458,13 +433,6 @@ void klp_start_transition(void)
458 klp_target_state == KLP_PATCHED ? "patching" : "unpatching"); 433 klp_target_state == KLP_PATCHED ? "patching" : "unpatching");
459 434
460 /* 435 /*
461 * If the patch can be applied or reverted immediately, skip the
462 * per-task transitions.
463 */
464 if (klp_transition_patch->immediate)
465 return;
466
467 /*
468 * Mark all normal tasks as needing a patch state update. They'll 436 * Mark all normal tasks as needing a patch state update. They'll
469 * switch either in klp_try_complete_transition() or as they exit the 437 * switch either in klp_try_complete_transition() or as they exit the
470 * kernel. 438 * kernel.
@@ -514,13 +482,6 @@ void klp_init_transition(struct klp_patch *patch, int state)
514 klp_target_state == KLP_PATCHED ? "patching" : "unpatching"); 482 klp_target_state == KLP_PATCHED ? "patching" : "unpatching");
515 483
516 /* 484 /*
517 * If the patch can be applied or reverted immediately, skip the
518 * per-task transitions.
519 */
520 if (patch->immediate)
521 return;
522
523 /*
524 * Initialize all tasks to the initial patch state to prepare them for 485 * Initialize all tasks to the initial patch state to prepare them for
525 * switching to the target state. 486 * switching to the target state.
526 */ 487 */