diff --git a/arch/arm/kernel/livepatch.c b/arch/arm/kernel/livepatch.c index b4d26474ba3395850c63ec37633a697dac88168d..b1711d947dfe7eea2b52b9118971a52288fe2c21 100644 --- a/arch/arm/kernel/livepatch.c +++ b/arch/arm/kernel/livepatch.c @@ -134,12 +134,17 @@ static int klp_check_activeness_func(struct klp_patch *patch, int enable, struct klp_object *obj; struct klp_func_node *func_node; struct klp_func *func; - unsigned long func_addr, func_size; + unsigned long func_addr = 0; + unsigned long func_size; struct klp_func_list *pcheck = NULL; for (obj = patch->objs; obj->funcs; obj++) { for (func = obj->funcs; func->old_name; func++) { + unsigned long old_func = (unsigned long)func->old_func; + if (enable) { + bool need_check_old = false; + if (func->patched || func->force == KLP_ENFORCEMENT) continue; /* @@ -153,7 +158,7 @@ static int klp_check_activeness_func(struct klp_patch *patch, int enable, * No patched on this function * [ the origin one ] */ - func_addr = (unsigned long)func->old_func; + func_addr = old_func; func_size = func->old_size; } else { /* @@ -184,6 +189,13 @@ static int klp_check_activeness_func(struct klp_patch *patch, int enable, func->old_name, func->force); if (ret) return ret; + need_check_old = (func_addr != old_func); + } + if (need_check_old) { + ret = add_func_to_list(check_funcs, &pcheck, old_func, + func->old_size, func->old_name, func->force); + if (ret) + return ret; } } else { /* @@ -203,7 +215,7 @@ static int klp_check_activeness_func(struct klp_patch *patch, int enable, * the stack. */ if (list_is_singular(&func_node->func_stack)) { - func_addr = (unsigned long)func->old_func; + func_addr = old_func; func_size = func->old_size; } else { struct klp_func *prev; @@ -219,6 +231,12 @@ static int klp_check_activeness_func(struct klp_patch *patch, int enable, func->old_name, 0); if (ret) return ret; + if (func_addr != old_func) { + ret = add_func_to_list(check_funcs, &pcheck, old_func, + func->old_size, func->old_name, 0); + if (ret) + return ret; + } #endif func_addr = (unsigned long)func->new_func; func_size = func->new_size; diff --git a/arch/arm64/kernel/livepatch.c b/arch/arm64/kernel/livepatch.c index 6b5bcb49112595641e6759e6bda0d842d1364697..5b01712548206a2329a447342f73ea01c05f9ee9 100644 --- a/arch/arm64/kernel/livepatch.c +++ b/arch/arm64/kernel/livepatch.c @@ -126,13 +126,18 @@ static int klp_check_activeness_func(struct klp_patch *patch, int enable, int ret; struct klp_object *obj; struct klp_func *func; - unsigned long func_addr, func_size; + unsigned long func_addr = 0; + unsigned long func_size; struct klp_func_node *func_node; struct klp_func_list *pcheck = NULL; for (obj = patch->objs; obj->funcs; obj++) { for (func = obj->funcs; func->old_name; func++) { + unsigned long old_func = (unsigned long)func->old_func; + if (enable) { + bool need_check_old = false; + if (func->patched || func->force == KLP_ENFORCEMENT) continue; /* @@ -142,7 +147,7 @@ static int klp_check_activeness_func(struct klp_patch *patch, int enable, func_node = klp_find_func_node(func->old_func); if (!func_node || list_empty(&func_node->func_stack)) { - func_addr = (unsigned long)func->old_func; + func_addr = old_func; func_size = func->old_size; } else { /* @@ -173,6 +178,13 @@ static int klp_check_activeness_func(struct klp_patch *patch, int enable, func->old_name, func->force); if (ret) return ret; + need_check_old = (func_addr != old_func); + } + if (need_check_old) { + ret = add_func_to_list(check_funcs, &pcheck, old_func, + func->old_size, func->old_name, func->force); + if (ret) + return ret; } } else { /* @@ -193,7 +205,7 @@ static int klp_check_activeness_func(struct klp_patch *patch, int enable, * the stack. */ if (list_is_singular(&func_node->func_stack)) { - func_addr = (unsigned long)func->old_func; + func_addr = old_func; func_size = func->old_size; } else { struct klp_func *prev; @@ -209,6 +221,12 @@ static int klp_check_activeness_func(struct klp_patch *patch, int enable, func->old_name, 0); if (ret) return ret; + if (func_addr != old_func) { + ret = add_func_to_list(check_funcs, &pcheck, old_func, + func->old_size, func->old_name, 0); + if (ret) + return ret; + } #endif func_addr = (unsigned long)func->new_func; diff --git a/arch/powerpc/kernel/livepatch_32.c b/arch/powerpc/kernel/livepatch_32.c index 7b4ed23bf2cabfea4472cde0f58da88d0133e197..3fe4f3c5790b56d0eea542ae085dd30650751b46 100644 --- a/arch/powerpc/kernel/livepatch_32.c +++ b/arch/powerpc/kernel/livepatch_32.c @@ -123,13 +123,18 @@ static int klp_check_activeness_func(struct klp_patch *patch, int enable, int ret; struct klp_object *obj; struct klp_func *func; - unsigned long func_addr, func_size; + unsigned long func_addr = 0; + unsigned long func_size; struct klp_func_node *func_node; struct klp_func_list *pcheck = NULL; for (obj = patch->objs; obj->funcs; obj++) { for (func = obj->funcs; func->old_name; func++) { + unsigned long old_func = (unsigned long)func->old_func; + if (enable) { + bool need_check_old = false; + if (func->patched || func->force == KLP_ENFORCEMENT) continue; /* @@ -143,7 +148,7 @@ static int klp_check_activeness_func(struct klp_patch *patch, int enable, * No patched on this function * [ the origin one ] */ - func_addr = (unsigned long)func->old_func; + func_addr = old_func; func_size = func->old_size; } else { /* @@ -174,6 +179,13 @@ static int klp_check_activeness_func(struct klp_patch *patch, int enable, func->old_name, func->force); if (ret) return ret; + need_check_old = (func_addr != old_func); + } + if (need_check_old) { + ret = add_func_to_list(check_funcs, &pcheck, old_func, + func->old_size, func->old_name, func->force); + if (ret) + return ret; } } else { /* @@ -193,7 +205,7 @@ static int klp_check_activeness_func(struct klp_patch *patch, int enable, * the stack. */ if (list_is_singular(&func_node->func_stack)) { - func_addr = (unsigned long)func->old_func; + func_addr = old_func; func_size = func->old_size; } else { struct klp_func *prev; @@ -208,6 +220,12 @@ static int klp_check_activeness_func(struct klp_patch *patch, int enable, func_size, func->old_name, 0); if (ret) return ret; + if (func_addr != old_func) { + ret = add_func_to_list(check_funcs, &pcheck, old_func, + func->old_size, func->old_name, 0); + if (ret) + return ret; + } #endif func_addr = (unsigned long)func->new_func; func_size = func->new_size; diff --git a/arch/x86/kernel/livepatch.c b/arch/x86/kernel/livepatch.c index 0241e560bd2e3314cf1293ed009d47c70e72b4cc..43404fc1fdbb4700ede192d02170662f2c5f8ce2 100644 --- a/arch/x86/kernel/livepatch.c +++ b/arch/x86/kernel/livepatch.c @@ -120,16 +120,20 @@ static int klp_check_activeness_func(struct klp_patch *patch, int enable, int ret; struct klp_object *obj; struct klp_func *func; - unsigned long func_addr, func_size; + unsigned long func_addr = 0; + unsigned long func_size; struct klp_func_node *func_node = NULL; struct klp_func_list *pcheck = NULL; for (obj = patch->objs; obj->funcs; obj++) { for (func = obj->funcs; func->old_name; func++) { - func_node = klp_find_func_node(func->old_func); + unsigned long old_func = (unsigned long)func->old_func; + func_node = klp_find_func_node(func->old_func); /* Check func address in stack */ if (enable) { + bool need_check_old = false; + if (func->patched || func->force == KLP_ENFORCEMENT) continue; /* @@ -138,7 +142,7 @@ static int klp_check_activeness_func(struct klp_patch *patch, int enable, */ if (!func_node || list_empty(&func_node->func_stack)) { - func_addr = (unsigned long)func->old_func; + func_addr = old_func; func_size = func->old_size; } else { /* @@ -169,6 +173,13 @@ static int klp_check_activeness_func(struct klp_patch *patch, int enable, func->old_name, func->force); if (ret) return ret; + need_check_old = (func_addr != old_func); + } + if (need_check_old) { + ret = add_func_to_list(check_funcs, &pcheck, old_func, + func->old_size, func->old_name, func->force); + if (ret) + return ret; } } else { /* @@ -186,7 +197,7 @@ static int klp_check_activeness_func(struct klp_patch *patch, int enable, * the stack. */ if (list_is_singular(&func_node->func_stack)) { - func_addr = (unsigned long)func->old_func; + func_addr = old_func; func_size = func->old_size; } else { struct klp_func *prev; @@ -201,6 +212,12 @@ static int klp_check_activeness_func(struct klp_patch *patch, int enable, func_size, func->old_name, 0); if (ret) return ret; + if (func_addr != old_func) { + ret = add_func_to_list(check_funcs, &pcheck, old_func, + func->old_size, func->old_name, 0); + if (ret) + return ret; + } #endif func_addr = (unsigned long)func->new_func;