Date: Thu, 14 Aug 2014 11:45:48 GMT From: op@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r272397 - in soc2014/op/freebsd-base/sys: kern sys x86/include x86/x86 Message-ID: <201408141145.s7EBjmKG013300@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: op Date: Thu Aug 14 11:45:48 2014 New Revision: 272397 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=272397 Log: KSP: added variable sized patch support 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 soc2014/op/freebsd-base/sys/x86/include/selfpatch-asmacros.h soc2014/op/freebsd-base/sys/x86/include/selfpatch-machdep.h soc2014/op/freebsd-base/sys/x86/x86/selfpatch_machdep.c Modified: soc2014/op/freebsd-base/sys/kern/kern_selfpatch.c ============================================================================== --- soc2014/op/freebsd-base/sys/kern/kern_selfpatch.c Thu Aug 14 11:42:24 2014 (r272396) +++ soc2014/op/freebsd-base/sys/kern/kern_selfpatch.c Thu Aug 14 11:45:48 2014 (r272397) @@ -73,6 +73,7 @@ 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); +static void lf_pad_with_nop(struct lf_selfpatch *p); bool lf_selfpatch_patch_needed(struct lf_selfpatch *p) @@ -194,13 +195,13 @@ * replace the instructions */ memcpy(p->patchable, p->patch, p->patchable_size); + lf_pad_with_nop(p); if (mod == KSP_MODULE) lf_close_module_text(p); else lf_close_kernel_text(p); - DBG("patched.\n"); return (0); @@ -302,6 +303,33 @@ DBG("caches flushed.\n"); } + +static void +lf_pad_with_nop(struct lf_selfpatch *p) +{ + int i, rem; + char *patchable; + + if (p->patch_size == p->patchable_size) + return; + + if (p->patch_size > p->patchable_size) + panic("%s: patch_size > patchable_size", __func__); + + rem = p->patchable_size - p->patch_size; + patchable = p->patchable + p->patch_size; + + for (i = rem / KSP_MAX_NOPLEN; i > 0; i -= KSP_MAX_NOPLEN) { + memcpy(patchable, + selfpatch_nop_table[KSP_MAX_NOPLEN], + KSP_MAX_NOPLEN); + patchable += KSP_MAX_NOPLEN; + } + + rem %= KSP_MAX_NOPLEN; + memcpy(patchable, selfpatch_nop_table[rem], rem); +} + #ifdef KSP_DEBUG __noinline void lf_selfpatch_selftest(void) Modified: soc2014/op/freebsd-base/sys/sys/selfpatch.h ============================================================================== --- soc2014/op/freebsd-base/sys/sys/selfpatch.h Thu Aug 14 11:42:24 2014 (r272396) +++ soc2014/op/freebsd-base/sys/sys/selfpatch.h Thu Aug 14 11:45:48 2014 (r272397) @@ -60,7 +60,7 @@ char *comment; } lf_selfpatch_t; -extern char *selfpatch_nop_table[]; +extern const 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 mod); Modified: soc2014/op/freebsd-base/sys/x86/include/selfpatch-asmacros.h ============================================================================== --- soc2014/op/freebsd-base/sys/x86/include/selfpatch-asmacros.h Thu Aug 14 11:42:24 2014 (r272396) +++ soc2014/op/freebsd-base/sys/x86/include/selfpatch-asmacros.h Thu Aug 14 11:45:48 2014 (r272397) @@ -86,6 +86,7 @@ #define KSP_INSTR_NOP8_C KSP_INSTR_INTEL_NOP8_C #define KSP_INSTR_NOP9_C KSP_INSTR_INTEL_NOP9_C +#define KSP_MAX_NOPLEN 9 #define KSP_INSTR_XSAVE_XSAVEOPT(_ARG) \ 0723: \ Modified: soc2014/op/freebsd-base/sys/x86/include/selfpatch-machdep.h ============================================================================== --- soc2014/op/freebsd-base/sys/x86/include/selfpatch-machdep.h Thu Aug 14 11:42:24 2014 (r272396) +++ soc2014/op/freebsd-base/sys/x86/include/selfpatch-machdep.h Thu Aug 14 11:45:48 2014 (r272397) @@ -31,8 +31,6 @@ struct lf_selfpatch; -extern char *md_selfpatch_nop_table[]; - bool lf_selfpatch_patch_needed(struct lf_selfpatch *p); #endif /* __X86_SELFPATH_MACHDEP_H__ */ Modified: soc2014/op/freebsd-base/sys/x86/x86/selfpatch_machdep.c ============================================================================== --- soc2014/op/freebsd-base/sys/x86/x86/selfpatch_machdep.c Thu Aug 14 11:42:24 2014 (r272396) +++ soc2014/op/freebsd-base/sys/x86/x86/selfpatch_machdep.c Thu Aug 14 11:45:48 2014 (r272397) @@ -53,3 +53,51 @@ KSP_SELECTOR_END }; +/* + * assembly NOP store + */ +extern const char nop1; +extern const char nop2; +extern const char nop3; +extern const char nop4; +extern const char nop5; +extern const char nop6; +extern const char nop7; +extern const char nop8; +extern const char nop9; + +const char *selfpatch_nop_table[] = { + [0] = (const char *)NULL, + [1] = (const char *)&nop1, + [2] = (const char *)&nop2, + [3] = (const char *)&nop3, + [4] = (const char *)&nop4, + [5] = (const char *)&nop5, + [6] = (const char *)&nop6, + [7] = (const char *)&nop7, + [8] = (const char *)&nop8, + [9] = (const char *)&nop9 +}; + +__asm( +"nop1: \n" +" " KSP_INSTR_NOP1_C " \n" +"nop2: \n" +" " KSP_INSTR_NOP2_C " \n" +"nop3: \n" +" " KSP_INSTR_NOP3_C " \n" +"nop4: \n" +" " KSP_INSTR_NOP4_C " \n" +"nop5: \n" +" " KSP_INSTR_NOP5_C " \n" +"nop6: \n" +" " KSP_INSTR_NOP6_C " \n" +"nop7: \n" +" " KSP_INSTR_NOP7_C " \n" +"nop8: \n" +" " KSP_INSTR_NOP8_C " \n" +"nop9: \n" +" " KSP_INSTR_NOP9_C " \n" +" .p2align 4,0x90 \n" +); +
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201408141145.s7EBjmKG013300>