summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/static_call_inline.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/kernel/static_call_inline.c b/kernel/static_call_inline.c
index 639397b5491c..7bb0962b5229 100644
--- a/kernel/static_call_inline.c
+++ b/kernel/static_call_inline.c
@@ -411,6 +411,17 @@ static void static_call_del_module(struct module *mod)
for (site = start; site < stop; site++) {
key = static_call_key(site);
+
+ /*
+ * If the key was not updated due to a memory allocation
+ * failure in __static_call_init() then treating key::sites
+ * as key::mods in the code below would cause random memory
+ * access and #GP. In that case all subsequent sites have
+ * not been touched either, so stop iterating.
+ */
+ if (!static_call_key_has_mods(key))
+ break;
+
if (key == prev_key)
continue;