[PATCH 1/2] livepatch: Add a new function to verify the address and name match for extra module

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



In order to restrict the patch, we can verify the provided function
address and name match. Now we have can only verify the vmlinux function
name and address.

Add a new function to verify extra module function name and address. The
patch would not be patched, if the function name and address are not
matched.

Signed-off-by: Minfei Huang <minfei.huang@xxxxxxxxxxx>
---
 kernel/livepatch/core.c | 54 ++++++++++++++++++++++++++++++++++---------------
 1 file changed, 38 insertions(+), 16 deletions(-)

diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
index 3f9f1d6..ff42c29 100644
--- a/kernel/livepatch/core.c
+++ b/kernel/livepatch/core.c
@@ -196,12 +196,16 @@ static int klp_find_object_symbol(const char *objname, const char *name,
 }
 
 struct klp_verify_args {
+	const char *objname;
 	const char *name;
 	const unsigned long addr;
 };
 
-static int klp_verify_callback(void *data, const char *name,
-			       struct module *mod, unsigned long addr)
+typedef int (*klp_verify_callback)(void *data, const char *name,
+		struct module *mod, unsigned long addr);
+
+static int klp_verify_vmlinux_callback(void *data, const char *name,
+		struct module *mod, unsigned long addr)
 {
 	struct klp_verify_args *args = data;
 
@@ -213,18 +217,38 @@ static int klp_verify_callback(void *data, const char *name,
 	return 0;
 }
 
-static int klp_verify_vmlinux_symbol(const char *name, unsigned long addr)
+static int klp_verify_module_callback(void *data, const char *name,
+		struct module *mod, unsigned long addr)
+{
+	struct klp_verify_args *args = data;
+
+	if (!mod || !args->objname)
+		return 0;
+
+	if (!strcmp(args->objname, mod->name) &&
+	    !strcmp(args->name, name) &&
+	    args->addr == addr)
+		return 1;
+
+	return 0;
+}
+
+static int klp_verify_symbol(const char *objname, const char *name,
+		unsigned long addr)
 {
 	struct klp_verify_args args = {
+		.objname = objname,
 		.name = name,
 		.addr = addr,
 	};
+	klp_verify_callback fn = objname ?
+		klp_verify_module_callback : klp_verify_vmlinux_callback;
 
-	if (kallsyms_on_each_symbol(klp_verify_callback, &args))
+	if (kallsyms_on_each_symbol(fn, &args))
 		return 0;
 
-	pr_err("symbol '%s' not found at specified address 0x%016lx, kernel mismatch?\n",
-		name, addr);
+	pr_err("symbol '%s' not found at specified address 0x%016lx, %s mismatch?\n",
+			name, addr, objname ? objname : "kernel");
 	return -EINVAL;
 }
 
@@ -238,12 +262,12 @@ static int klp_find_verify_func_addr(struct klp_object *obj,
 	func->old_addr = 0;
 #endif
 
-	if (!func->old_addr || klp_is_module(obj))
-		ret = klp_find_object_symbol(obj->name, func->old_name,
-					     &func->old_addr);
+	if (func->old_addr)
+		ret = klp_verify_symbol(obj->name, func->old_name,
+				func->old_addr);
 	else
-		ret = klp_verify_vmlinux_symbol(func->old_name,
-						func->old_addr);
+		ret = klp_find_object_symbol(obj->name, func->old_name,
+				&func->old_addr);
 
 	return ret;
 }
@@ -285,10 +309,8 @@ static int klp_write_object_relocations(struct module *pmod,
 
 	for (reloc = obj->relocs; reloc->name; reloc++) {
 		if (!klp_is_module(obj)) {
-			ret = klp_verify_vmlinux_symbol(reloc->name,
+			ret = klp_verify_symbol(NULL, reloc->name,
 							reloc->val);
-			if (ret)
-				return ret;
 		} else {
 			/* module, reloc->val needs to be discovered */
 			if (reloc->external)
@@ -299,9 +321,9 @@ static int klp_write_object_relocations(struct module *pmod,
 				ret = klp_find_object_symbol(obj->mod->name,
 							     reloc->name,
 							     &reloc->val);
-			if (ret)
-				return ret;
 		}
+		if (ret)
+			return ret;
 		ret = klp_write_module_reloc(pmod, reloc->type, reloc->loc,
 					     reloc->val + reloc->addend);
 		if (ret) {
-- 
2.2.2

--
To unsubscribe from this list: send the line "unsubscribe live-patching" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux Kernel]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux