From owner-svn-soc-all@FreeBSD.ORG Tue Aug 12 22:38:53 2014 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 7CD5B9C7 for ; Tue, 12 Aug 2014 22:38:53 +0000 (UTC) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 697792025 for ; Tue, 12 Aug 2014 22:38:53 +0000 (UTC) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.14.9/8.14.9) with ESMTP id s7CMcrEO019666 for ; Tue, 12 Aug 2014 22:38:53 GMT (envelope-from op@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.14.9/8.14.9/Submit) id s7CMcqno019658 for svn-soc-all@FreeBSD.org; Tue, 12 Aug 2014 22:38:52 GMT (envelope-from op@FreeBSD.org) Date: Tue, 12 Aug 2014 22:38:52 GMT Message-Id: <201408122238.s7CMcqno019658@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to op@FreeBSD.org using -f From: op@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r272309 - in soc2014/op/freebsd-base/sys: kern sys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Aug 2014 22:38:53 -0000 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 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; ipatchable) + 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; ipatchable) + 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__ */