Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 12 Aug 2014 22:38:52 GMT
From:      op@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r272309 - in soc2014/op/freebsd-base/sys: kern sys
Message-ID:  <201408122238.s7CMcqno019658@socsvn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: op
Date: Tue Aug 12 22:38:52 2014
New Revision: 272309
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=272309

Log:
  KSP: fixed panic on module unload case, and added stubs for protection changes
  
  currently protection changes are unneeded, because the whole kernel
  image mappad with RWX protection...
  
  Signed-off-by: Oliver Pinter <oliver.pntr@gmail.com>
  
  git: https://github.com/opntr/opBSD/tree/op/gsoc2014/smap+kpatch

Modified:
  soc2014/op/freebsd-base/sys/kern/kern_selfpatch.c
  soc2014/op/freebsd-base/sys/sys/selfpatch.h

Modified: soc2014/op/freebsd-base/sys/kern/kern_selfpatch.c
==============================================================================
--- soc2014/op/freebsd-base/sys/kern/kern_selfpatch.c	Tue Aug 12 21:51:31 2014	(r272308)
+++ soc2014/op/freebsd-base/sys/kern/kern_selfpatch.c	Tue Aug 12 22:38:52 2014	(r272309)
@@ -65,6 +65,11 @@
 __noinline void lf_selfpatch_selftest(void);
 #endif
 
+static void lf_open_kernel_text(struct lf_selfpatch *p);
+static void lf_close_kernel_text(struct lf_selfpatch *p);
+static void lf_open_module_text(struct lf_selfpatch *p);
+static void lf_close_module_text(struct lf_selfpatch *p);
+
 bool
 lf_selfpatch_patch_needed(struct lf_selfpatch *p)
 {
@@ -127,15 +132,9 @@
 
 	for (patch = start; patch != stop; patch++) {
 		DBG("apply: %p\n", patch);
-		if (mod == KSP_MODULE) {
-			ret = lf_selfpatch_apply_module(lf, patch);
-			if (ret != 0)
-				return (ret);
-		} else {
-			ret = lf_selfpatch_apply(lf, patch);
-			if (ret != 0)
-				return (ret);
-		}
+		ret = lf_selfpatch_apply(lf, patch, mod);
+		if (ret != 0)
+			return (ret);
 	}
 
 #ifdef KSP_DEBUG
@@ -149,11 +148,8 @@
 }
 
 int
-lf_selfpatch_apply(linker_file_t lf, struct lf_selfpatch *p)
+lf_selfpatch_apply(linker_file_t lf, struct lf_selfpatch *p, int mod)
 {
-	vm_paddr_t pages[4];
-	vm_offset_t page_offset;
-	int i, page_number;
 
 	/* Refuse to patch if securelevel raised */
 	if (prison0.pr_securelevel > 0)
@@ -176,77 +172,94 @@
 	if (p->patch_size != p->patchable_size)
 		panic("%s: patch_size != patchable_size", __func__);
 
-	page_offset = (vm_offset_t)p->patchable & (vm_offset_t)PAGE_MASK;
-	page_number = (p->patchable_size >> PAGE_SHIFT) +
-	    ((page_offset + p->patchable_size) > PAGE_SIZE ? 2 : 1);
-
-	DBG("page_number: %d\n", page_number);
-
-	KASSERT(page_number < 4,
-	    ("patch size longer than 3 page does not supported yet\n"));
-
-	DBG("change mapping attribute from RX to RWX:\n");
-	for (i=0; i<page_number; i++) {
-		vm_paddr_t kva;
+	/*
+	 * open the kernel text
+	 * currently this is a dummy function, because the kernel protection
+	 * is RWX now.
+	 */
+	if (mod == KSP_MODULE)
+		lf_open_module_text(p);
+	else
+		lf_open_kernel_text(p);
 
-		kva = trunc_page(p->patchable) + i * PAGE_SIZE;
-		pages[i] = pmap_kextract(kva);
+	/*
+	 * replace the instructions
+	 */
+	memcpy(p->patchable, p->patch, p->patchable_size);
 
-		DBG("kva: %p page: %p\n", (void *)kva, (void *)pages[i]);
-#ifdef NOT_THE_RIGHT_API
-		pmap_kenter_attr(kva, pages[i], VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);
-#endif
-	}
-	DBG("done.\n");
+	if (mod == KSP_MODULE)
+		lf_close_module_text(p);
+	else
+		lf_close_kernel_text(p);
 
-	memcpy(p->patchable, p->patch, p->patchable_size);
 
 	DBG("patched.\n");
 
-	DBG("change mapping attribute from RWX to RX:\n");
-	for (i=0; i<page_number; i++) {
-		vm_paddr_t kva;
-
-		kva = trunc_page(p->patchable) + i * PAGE_SIZE;
-#ifdef NOT_THE_RIGHT_API
-		pmap_kenter_attr(kva, pages[i], VM_PROT_READ | VM_PROT_EXECUTE);
-#endif
-	}
-	DBG("done.\n");
-
 	return (0);
 }
 
-int
-lf_selfpatch_apply_module(linker_file_t lf, struct lf_selfpatch *p)
+static void
+lf_open_kernel_text(struct lf_selfpatch *p)
 {
+	/*
+	 * dummy function, currently unused becasue the kernel
+	 * protection is RWX
+	 */
+#if 0
+	pmap_protect(kernel_pmap, sva, eva,
+	    VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);
+#endif
+}
 
-	/* Refuse to patch if securelevel raised */
-	if (prison0.pr_securelevel > 0)
-		return (EPERM);
-
-	DBG("patchable: %p\n", p->patchable);
-	DBG("patch: %p\n", p->patch);
-	DBG("feature selector: %d\n", p->feature_selector);
-	DBG("feature: %d\n", p->feature);
-	DBG("patchable size: %d\n", p->patchable_size);
-	DBG("patch size: %d\n", p->patch_size);
-	DBG("comment: %s\n", p->comment);
-
-	if (!lf_selfpatch_patch_needed(p)) {
-		DBG("not needed.\n");
-
-		return (0);
-	}
+static void
+lf_close_kernel_text(struct lf_selfpatch *p)
+{
+	/*
+	 * dummy function, currently unused becasue the kernel
+	 * protection is RWX
+	 *
+	 * currently flushes the cache after modification
+	 */
+#if 0
+	pmap_protect(kernel_pmap, sva, eva,
+	    VM_PROT_READ | VM_PROT_EXECUTE);
+#endif
 
-	if (p->patch_size != p->patchable_size)
-		panic("%s: patch_size != patchable_size", __func__);
+	/* Flushes caches and TLBs. */
+	wbinvd();
+	invltlb();
+}
 
-	memcpy(p->patchable, p->patch, p->patchable_size);
+static void
+lf_open_module_text(struct lf_selfpatch *p)
+{
+	/*
+	 * dummy function, currently unused becasue the kernel
+	 * protection is RWX
+	 */
+#if 0
+	pmap_protect(module_pmap, sva, eva,
+	    VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);
+#endif
+}
 
-	DBG("patched.\n");
+static void
+lf_close_module_text(struct lf_selfpatch *p)
+{
+	/*
+	 * dummy function, currently unused becasue the kernel
+	 * protection is RWX
+	 *
+	 * currently flushes the cache after modification
+	 */
+#if 0
+	pmap_protect(module_pmap, sva, eva,
+	    VM_PROT_READ | VM_PROT_EXECUTE);
+#endif
 
-	return (0);
+	/* Flushes caches and TLBs. */
+	wbinvd();
+	invltlb();
 }
 
 #ifdef KSP_DEBUG

Modified: soc2014/op/freebsd-base/sys/sys/selfpatch.h
==============================================================================
--- soc2014/op/freebsd-base/sys/sys/selfpatch.h	Tue Aug 12 21:51:31 2014	(r272308)
+++ soc2014/op/freebsd-base/sys/sys/selfpatch.h	Tue Aug 12 22:38:52 2014	(r272309)
@@ -63,7 +63,6 @@
 extern char *selfpatch_nop_table[];
 
 int lf_selfpatch(linker_file_t lf, int mod);
-int lf_selfpatch_apply(linker_file_t lf, struct lf_selfpatch *patch);
-int lf_selfpatch_apply_module(linker_file_t lf, struct lf_selfpatch *patch);
+int lf_selfpatch_apply(linker_file_t lf, struct lf_selfpatch *patch, int mod);
 
 #endif /* __SELFPATH_H__ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201408122238.s7CMcqno019658>