File Index
Files and directories
Sign in
FILE

init.c

File preview with syntax highlighting.

linux-6.19.14/scripts/livepatch/init.c C
  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
 12static struct klp_patch *patch;
 13
 14static int __init livepatch_mod_init(void)
 15{
 16	struct klp_object_ext *obj_exts;
 17	size_t obj_exts_sec_size;
 18	struct klp_object *objs;
 19	unsigned int nr_objs;
 20	int ret;
 21
 22	obj_exts = klp_find_section_by_name(THIS_MODULE, ".init.klp_objects",
 23					    &obj_exts_sec_size);
 24	nr_objs = obj_exts_sec_size / sizeof(*obj_exts);
 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 = obj_exts + 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
 83err_free_objs:
 84	kfree(objs);
 85err_free_patch:
 86	kfree(patch);
 87err:
 88	return ret;
 89}
 90
 91static void __exit livepatch_mod_exit(void)
 92{
 93	struct klp_object *obj;
 94
 95	klp_for_each_object_static(patch, obj)
 96		kfree(obj->funcs);
 97
 98	kfree(patch->objs);
 99	kfree(patch);
100}
101
102module_init(livepatch_mod_init);
103module_exit(livepatch_mod_exit);
104MODULE_LICENSE("GPL");
105MODULE_INFO(livepatch, "Y");
106MODULE_DESCRIPTION("Livepatch module");
~/ Read-only file preview.