// SPDX-License-Identifier: GPL-2.0-or-later /* * livepatch-sample.c - Kernel Live Patching Sample Module * * Copyright (C) 2014 Seth Jennings <sjenning@redhat.com> */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/module.h> #include <linux/kernel.h> #include <linux/livepatch.h> /* * This (dumb) live patch overrides the function that prints the * kernel boot cmdline when /proc/cmdline is read. * * Example: * * $ cat /proc/cmdline * <your cmdline> * * $ insmod livepatch-sample.ko * $ cat /proc/cmdline * this has been live patched * * $ echo 0 > /sys/kernel/livepatch/livepatch_sample/enabled * $ cat /proc/cmdline * <your cmdline> */ #include <linux/seq_file.h> /* This is the replacement function that we are going to override with */ static int livepatch_cmdline_proc_show(struct seq_file *m, void *v) { seq_printf(m, "%s\n", "this has been live patched"); return 0; } /* We have to provide the livepatch API with the following struct * that indicates which kernel function we are overwriting and with what */ static struct klp_func funcs[] = { { .old_name = "cmdline_proc_show", .new_func = livepatch_cmdline_proc_show, }, { } }; /* The struct above gets passed as a field in the following klp_object * (kernel live patch)_object. */ static struct klp_object objs[] = { { /* name being NULL means vmlinux */ .funcs = funcs, }, { } }; /* Again, the struct above gets passed a field to the following klp_patch * object. The address of this object in memory will be passed to the * klp_enable_patch() function */ static struct klp_patch patch = { .mod = THIS_MODULE, .objs = objs, }; /* Initialize our patch */ static int livepatch_init(void) { return klp_enable_patch(&patch); } static void livepatch_exit(void) { } module_init(livepatch_init); module_exit(livepatch_exit); MODULE_LICENSE("GPL"); /* We have to tell the kernel that this LKM is a livepatch module */ MODULE_INFO(livepatch, "Y");