linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Chris J Arges <chris.j.arges@canonical.com>
To: live-patching@vger.kernel.org
Cc: Chris J Arges <chris.j.arges@canonical.com>,
	Josh Poimboeuf <jpoimboe@redhat.com>,
	Jessica Yu <jeyu@redhat.com>, Jiri Kosina <jikos@kernel.org>,
	Miroslav Benes <mbenes@suse.cz>, Petr Mladek <pmladek@suse.com>,
	linux-kernel@vger.kernel.org
Subject: [PATCH] livepatch: add load/unload hooks to objects
Date: Fri, 26 Aug 2016 13:50:27 -0500	[thread overview]
Message-ID: <1472237448-22270-2-git-send-email-chris.j.arges@canonical.com> (raw)
In-Reply-To: <1472237448-22270-1-git-send-email-chris.j.arges@canonical.com>

It can be useful to execute hook functions whenever a livepatch is applied
or unapplied to a particular object. Currently this is possible by writing
logic in the __init function of the livepatch kernel module. However to
handle executing functions when a module loads requires an additional
module notifier to be set up with the correct priority.

By using load/unload hooks we can execute these functions using the
existing livepatch notifier infrastructure and ensure consistent ordering
of notifications.

The load hook executes right before enabling functions, and the unload hook
executes right after disabling functions.

Signed-off-by: Chris J Arges <chris.j.arges@canonical.com>
---
 include/linux/livepatch.h | 33 +++++++++++++++++++++++++++------
 kernel/livepatch/core.c   | 29 +++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+), 6 deletions(-)

diff --git a/include/linux/livepatch.h b/include/linux/livepatch.h
index 9072f04..bb32a66 100644
--- a/include/linux/livepatch.h
+++ b/include/linux/livepatch.h
@@ -65,18 +65,32 @@ struct klp_func {
 };
 
 /**
+ * struct klp_hook - hook structure for live patching
+ * @hook:	function to be executed on hook
+ *
+ */
+struct klp_hook {
+	int (*hook)(void);
+};
+
+/**
  * struct klp_object - kernel object structure for live patching
- * @name:	module name (or NULL for vmlinux)
- * @funcs:	function entries for functions to be patched in the object
- * @kobj:	kobject for sysfs resources
- * @mod:	kernel module associated with the patched object
- * 		(NULL for vmlinux)
- * @state:	tracks object-level patch application state
+ * @name:		module name (or NULL for vmlinux)
+ * @funcs:		function entries for functions to be patched in the
+ *                      object
+ * @load_hooks:		functions to be executed before load time (optional)
+ * @unload_hooks:	functions to be executed before load time (optional)
+ * @kobj:		kobject for sysfs resources
+ * @mod:		kernel module associated with the patched object
+ *                      (NULL for vmlinux)
+ * @state:		tracks object-level patch application state
  */
 struct klp_object {
 	/* external */
 	const char *name;
 	struct klp_func *funcs;
+	struct klp_hook *load_hooks;
+	struct klp_hook *unload_hooks;
 
 	/* internal */
 	struct kobject kobj;
@@ -111,6 +125,13 @@ struct klp_patch {
 	     func->old_name || func->new_func || func->old_sympos; \
 	     func++)
 
+#define klp_for_each_load_hook(obj, hook) \
+	for (hook = obj->load_hooks; hook && hook->hook; hook++)
+
+#define klp_for_each_unload_hook(obj, hook) \
+	for (hook = obj->unload_hooks; hook && hook->hook; hook++)
+
+
 int klp_register_patch(struct klp_patch *);
 int klp_unregister_patch(struct klp_patch *);
 int klp_enable_patch(struct klp_patch *);
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
index 5fbabe0..00e7d9c 100644
--- a/kernel/livepatch/core.c
+++ b/kernel/livepatch/core.c
@@ -378,6 +378,14 @@ static void klp_disable_func(struct klp_func *func)
 	func->state = KLP_DISABLED;
 }
 
+static int klp_run_hook(struct klp_hook *hook)
+{
+	if (hook && hook->hook)
+		return (*hook->hook)();
+
+	return 0;
+}
+
 static int klp_enable_func(struct klp_func *func)
 {
 	struct klp_ops *ops;
@@ -448,17 +456,28 @@ err:
 static void klp_disable_object(struct klp_object *obj)
 {
 	struct klp_func *func;
+	struct klp_hook *hook;
+	int ret;
 
 	klp_for_each_func(obj, func)
 		if (func->state == KLP_ENABLED)
 			klp_disable_func(func);
 
+	klp_for_each_unload_hook(obj, hook) {
+		ret = klp_run_hook(hook);
+		if (ret) {
+			pr_warn("unload hook '%p' failed for object '%s'\n",
+				hook, klp_is_module(obj) ? obj->name : "vmlinux");
+		}
+	}
+
 	obj->state = KLP_DISABLED;
 }
 
 static int klp_enable_object(struct klp_object *obj)
 {
 	struct klp_func *func;
+	struct klp_hook *hook;
 	int ret;
 
 	if (WARN_ON(obj->state != KLP_DISABLED))
@@ -467,6 +486,16 @@ static int klp_enable_object(struct klp_object *obj)
 	if (WARN_ON(!klp_is_object_loaded(obj)))
 		return -EINVAL;
 
+	klp_for_each_load_hook(obj, hook) {
+		ret = klp_run_hook(hook);
+		if (ret) {
+			pr_warn("load hook '%p' failed for object '%s'\n",
+				hook, klp_is_module(obj) ? obj->name : "vmlinux");
+			klp_disable_object(obj);
+			return ret;
+		}
+	}
+
 	klp_for_each_func(obj, func) {
 		ret = klp_enable_func(func);
 		if (ret) {
-- 
2.7.4

  reply	other threads:[~2016-08-26 18:51 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-08-26 18:50 [RFC][PATCH] Load/Unload Hooks for Livepatch Chris J Arges
2016-08-26 18:50 ` Chris J Arges [this message]
2016-08-29 15:23   ` [PATCH] livepatch: add load/unload hooks to objects Petr Mladek
2016-08-29 16:16     ` Christopher Arges
2016-08-30  9:41       ` Jiri Kosina
2016-08-30 12:52         ` Christopher Arges
2016-08-30 14:43       ` Petr Mladek
2016-08-30 15:15         ` Christopher Arges

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1472237448-22270-2-git-send-email-chris.j.arges@canonical.com \
    --to=chris.j.arges@canonical.com \
    --cc=jeyu@redhat.com \
    --cc=jikos@kernel.org \
    --cc=jpoimboe@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=live-patching@vger.kernel.org \
    --cc=mbenes@suse.cz \
    --cc=pmladek@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).