History

livepatch/klp-build: Add stub init code for livepatch modules

Add a module initialization stub which can be linked with binary diff objects to produce a livepatch module.

Josh Poimboeuf committed 1 year ago

Commit 59adee01 parent abaf1f41 file · +108 −0Browse files

Showing the changes to scripts/livepatch (1 of 1 file). Show all

Unified · Split

scripts/livepatch/init.c+108−0
@@ -0,0 +1,108 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * Init code for a livepatch kernel module
4+ */
5+
6+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
7+
8+#include <linux/kernel.h>
9+#include <linux/slab.h>
10+#include <linux/livepatch.h>
11+
12+extern struct klp_object_ext __start_klp_objects[];
13+extern struct klp_object_ext __stop_klp_objects[];
14+
15+static struct klp_patch *patch;
16+
17+static int __init livepatch_mod_init(void)
18+{
19+ struct klp_object *objs;
20+ unsigned int nr_objs;
21+ int ret;
22+
23+ nr_objs = __stop_klp_objects - __start_klp_objects;
24+
25+ if (!nr_objs) {
26+ pr_err("nothing to patch!\n");
27+ ret = -EINVAL;
28+ goto err;
29+ }
30+
31+ patch = kzalloc(sizeof(*patch), GFP_KERNEL);
32+ if (!patch) {
33+ ret = -ENOMEM;
34+ goto err;
35+ }
36+
37+ objs = kzalloc(sizeof(struct klp_object) * (nr_objs + 1), GFP_KERNEL);
38+ if (!objs) {
39+ ret = -ENOMEM;
40+ goto err_free_patch;
41+ }
42+
43+ for (int i = 0; i < nr_objs; i++) {
44+ struct klp_object_ext *obj_ext = __start_klp_objects + i;
45+ struct klp_func_ext *funcs_ext = obj_ext->funcs;
46+ unsigned int nr_funcs = obj_ext->nr_funcs;
47+ struct klp_func *funcs = objs[i].funcs;
48+ struct klp_object *obj = objs + i;
49+
50+ funcs = kzalloc(sizeof(struct klp_func) * (nr_funcs + 1), GFP_KERNEL);
51+ if (!funcs) {
52+ ret = -ENOMEM;
53+ for (int j = 0; j < i; j++)
54+ kfree(objs[i].funcs);
55+ goto err_free_objs;
56+ }
57+
58+ for (int j = 0; j < nr_funcs; j++) {
59+ funcs[j].old_name = funcs_ext[j].old_name;
60+ funcs[j].new_func = funcs_ext[j].new_func;
61+ funcs[j].old_sympos = funcs_ext[j].sympos;
62+ }
63+
64+ obj->name = obj_ext->name;
65+ obj->funcs = funcs;
66+
67+ memcpy(&obj->callbacks, &obj_ext->callbacks, sizeof(struct klp_callbacks));
68+ }
69+
70+ patch->mod = THIS_MODULE;
71+ patch->objs = objs;
72+
73+ /* TODO patch->states */
74+
75+#ifdef KLP_NO_REPLACE
76+ patch->replace = false;
77+#else
78+ patch->replace = true;
79+#endif
80+
81+ return klp_enable_patch(patch);
82+
83+err_free_objs:
84+ kfree(objs);
85+err_free_patch:
86+ kfree(patch);
87+err:
88+ return ret;
89+}
90+
91+static void __exit livepatch_mod_exit(void)
92+{
93+ unsigned int nr_objs;
94+
95+ nr_objs = __stop_klp_objects - __start_klp_objects;
96+
97+ for (int i = 0; i < nr_objs; i++)
98+ kfree(patch->objs[i].funcs);
99+
100+ kfree(patch->objs);
101+ kfree(patch);
102+}
103+
104+module_init(livepatch_mod_init);
105+module_exit(livepatch_mod_exit);
106+MODULE_LICENSE("GPL");
107+MODULE_INFO(livepatch, "Y");
108+MODULE_DESCRIPTION("Livepatch module");