[POC 10/23] livepatch: Handle modprobe exit code

Petr Mladek
2020-01-17T15:04:05Z

request_module() returns classic negative error codes when it was
not even able to call "modprobe" from some reasons. Otherwise,
it returns the exit code multiplied by 256.

modprobe exit code is always 1 in case of error. Use -EINVAL
instead as the least ugly internal error code.

A better solution would be to somehow pass the original error
code from the init_module() syscall or at least the error code
from klp_module_add() functions. But there is no obvious way
how to pass the information.

Global variable is not enough because more livepatch modules
can be loaded simultaneously from klp_enable_patch() and
klp_module_comming().

Signed-off-by: Petr Mladek <pmladek@suse.com>
---
kernel/livepatch/core.c | 3 +++
tools/testing/selftests/livepatch/test-callbacks.sh | 2 +-
2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
index 8e693c58b736..19ca8baa2f16 100644
--- a/kernel/livepatch/core.c
+++ b/kernel/livepatch/core.c
@@ -1109,6 +1109,9 @@ static int klp_try_load_object(const char *patch_name, const char *obj_name)

ret = request_module("%s__%s", patch_name, obj_name);
if (ret) {
+ /* modprobe always set exit code 1 on error */
+ if (ret > 0)
+ ret = -EINVAL;
pr_info("Module load failed: %s__%s\n", patch_name, obj_name);
return ret;
}
diff --git a/tools/testing/selftests/livepatch/test-callbacks.sh b/tools/testing/selftests/livepatch/test-callbacks.sh
index 39a4f35e5f8e..060e5b512367 100755
--- a/tools/testing/selftests/livepatch/test-callbacks.sh
+++ b/tools/testing/selftests/livepatch/test-callbacks.sh
@@ -331,7 +331,7 @@ $MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full fo
livepatch: pre-patch callback failed for object '$MOD_TARGET'
livepatch: patch '$MOD_LIVEPATCH' failed for module '$MOD_TARGET', refusing to load module '$MOD_TARGET'
livepatch: Module load failed: ${MOD_LIVEPATCH}__${MOD_TARGET}
-modprobe: ERROR: could not insert '$MOD_TARGET': No such device
+modprobe: ERROR: could not insert '$MOD_TARGET': Invalid argument
% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
$MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
--
2.16.4