-
Notifications
You must be signed in to change notification settings - Fork 52.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
livepatch: Add sample livepatch module
Add a new livepatch sample in samples/livepatch/ to make use of symbols that must be post-processed to enable load-time relocation resolution. As the new sample is to be used as an example, it is annotated with KLP_MODULE_RELOC and with KLP_SYMPOS macros. The livepatch sample updates the function cmdline_proc_show to print the string referenced by the symbol saved_command_line appended by the string "livepatch=1". Update livepatch-sample.c to remove livepatch MODULE_INFO statement. [jmoreira: * update module to use KLP_SYMPOS * Comments on symbol resolution scheme * Update Makefile * Remove MODULE_INFO statement * Changelog ] Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com> Signed-off-by: Joao Moreira <jmoreira@suse.de>
- Loading branch information
1 parent
22c59f0
commit 7d9878e
Showing
2 changed files
with
115 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
/* | ||
* livepatch-annotated-sample.c - Kernel Live Patching Sample Module | ||
* | ||
* Copyright (C) 2014 Seth Jennings <sjenning@redhat.com> | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation; either version 2 | ||
* of the License, or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
|
||
#include <linux/module.h> | ||
#include <linux/kernel.h> | ||
#include <linux/livepatch.h> | ||
#include <linux/seq_file.h> | ||
|
||
/* | ||
* This (dumb) live patch overrides the function that prints the | ||
* kernel boot cmdline when /proc/cmdline is read. | ||
* | ||
* This livepatch uses the symbol saved_command_line whose relocation | ||
* must be resolved during load time. To enable that, this module | ||
* must be post-processed by a tool called klp-convert, which embeds | ||
* information to be used by the loader to solve the relocation. | ||
* | ||
* The module is annotated with KLP_MODULE_RELOC/KLP_SYMPOS macros. | ||
* These annotations are used by klp-convert to infer that the symbol | ||
* saved_command_line is in the object vmlinux. | ||
* | ||
* As saved_command_line has no other homonimous symbol across | ||
* kernel objects, this annotation is not a requirement, and can be | ||
* suppressed with no harm to klp-convert. Yet, it is kept here as an | ||
* example on how to annotate livepatch modules that contain symbols | ||
* whose names are used in more than one kernel object. | ||
* | ||
* Example: | ||
* | ||
* $ cat /proc/cmdline | ||
* <your cmdline> | ||
* | ||
* $ insmod livepatch-sample.ko | ||
* $ cat /proc/cmdline | ||
* <your cmdline> livepatch=1 | ||
* | ||
* $ echo 0 > /sys/kernel/livepatch/livepatch_sample/enabled | ||
* $ cat /proc/cmdline | ||
* <your cmdline> | ||
*/ | ||
|
||
extern char *saved_command_line; | ||
|
||
static int livepatch_cmdline_proc_show(struct seq_file *m, void *v) | ||
{ | ||
seq_printf(m, "%s livepatch=1\n", saved_command_line); | ||
return 0; | ||
} | ||
|
||
KLP_MODULE_RELOC(vmlinux) vmlinux_relocs[] = { | ||
KLP_SYMPOS(saved_command_line, 0) | ||
}; | ||
|
||
static struct klp_func vmlinux_funcs[] = { | ||
{ | ||
.old_name = "cmdline_proc_show", | ||
.new_func = livepatch_cmdline_proc_show, | ||
}, { } | ||
}; | ||
|
||
static struct klp_object objs[] = { | ||
{ | ||
/* name being NULL means vmlinux */ | ||
.funcs = vmlinux_funcs, | ||
}, { } | ||
}; | ||
|
||
static struct klp_patch patch = { | ||
.mod = THIS_MODULE, | ||
.objs = objs, | ||
}; | ||
|
||
static int livepatch_init(void) | ||
{ | ||
int ret; | ||
|
||
ret = klp_register_patch(&patch); | ||
if (ret) | ||
return ret; | ||
ret = klp_enable_patch(&patch); | ||
if (ret) { | ||
WARN_ON(klp_unregister_patch(&patch)); | ||
return ret; | ||
} | ||
return 0; | ||
} | ||
|
||
static void livepatch_exit(void) | ||
{ | ||
WARN_ON(klp_unregister_patch(&patch)); | ||
} | ||
|
||
module_init(livepatch_init); | ||
module_exit(livepatch_exit); | ||
MODULE_LICENSE("GPL"); |