Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751632AbdH2TCq (ORCPT ); Tue, 29 Aug 2017 15:02:46 -0400 Received: from mx2.suse.de ([195.135.220.15]:37158 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751595AbdH2TCo (ORCPT ); Tue, 29 Aug 2017 15:02:44 -0400 From: Joao Moreira To: live-patching@vger.kernel.org, linux-kernel@vger.kernel.org Cc: mbenes@suse.cz, mmarek@suse.cz, pmladek@suse.com, jikos@suse.cz, nstange@suse.de, jroedel@suse.de, matz@suse.de, jpoimboe@redhat.com, khlebnikov@yandex-team.ru, jeyu@kernel.org, jmoreira@suse.de Subject: [PATCH 7/8] livepatch: Add sample livepatch module Date: Tue, 29 Aug 2017 16:01:39 -0300 Message-Id: <20170829190140.401-8-jmoreira@suse.de> X-Mailer: git-send-email 2.12.3 In-Reply-To: <20170829190140.401-1-jmoreira@suse.de> References: <20170829190140.401-1-jmoreira@suse.de> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5525 Lines: 173 From: Josh Poimboeuf 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_REOC 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". [jmoreira: * Switched from "updating existing" module to "adding a new" module * Update module to use KLP_SYMPOS * Comments on symbol resolution scheme * Update Makefile * Changelog ] Signed-off-by: Josh Poimboeuf Signed-off-by: Joao Moreira --- samples/livepatch/Makefile | 4 +- samples/livepatch/livepatch-annotated-sample.c | 128 +++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 samples/livepatch/livepatch-annotated-sample.c diff --git a/samples/livepatch/Makefile b/samples/livepatch/Makefile index 955e7ac12d2b..2690ef439bec 100644 --- a/samples/livepatch/Makefile +++ b/samples/livepatch/Makefile @@ -1,2 +1,4 @@ LIVEPATCH_livepatch-sample.o := y -obj-$(CONFIG_SAMPLE_LIVEPATCH) += livepatch-sample.o +LIVEPATCH_livepatch-annotated-sample.o := y +obj-$(CONFIG_SAMPLE_LIVEPATCH) += livepatch-sample.o \ + livepatch-annotated-sample.o diff --git a/samples/livepatch/livepatch-annotated-sample.c b/samples/livepatch/livepatch-annotated-sample.c new file mode 100644 index 000000000000..93da32610076 --- /dev/null +++ b/samples/livepatch/livepatch-annotated-sample.c @@ -0,0 +1,128 @@ +/* + * livepatch-annotated-sample.c - Kernel Live Patching Sample Module + * + * Copyright (C) 2014 Seth Jennings + * + * 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 . + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include + +/* + * 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 + * + * + * $ insmod livepatch-sample.ko + * $ cat /proc/cmdline + * livepatch=1 + * + * $ echo 0 > /sys/kernel/livepatch/livepatch_sample/enabled + * $ cat /proc/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; + + if (!klp_have_reliable_stack() && !patch.immediate) { + /* + * WARNING: Be very careful when using 'patch.immediate' in + * your patches. It's ok to use it for simple patches like + * this, but for more complex patches which change function + * semantics, locking semantics, or data structures, it may not + * be safe. Use of this option will also prevent removal of + * the patch. + * + * See Documentation/livepatch/livepatch.txt for more details. + */ + patch.immediate = true; + pr_notice("The consistency model isn't supported for your architecture. Bypassing safety mechanisms and applying the patch immediately.\n"); + } + + 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"); -- 2.12.0