Skip to content

Commit

Permalink
KSP: added variable sized patch support
Browse files Browse the repository at this point in the history
Signed-off-by: Oliver Pinter <[email protected]>
  • Loading branch information
opntr committed Aug 14, 2014
1 parent 5be2b1d commit b29c263
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 4 deletions.
30 changes: 29 additions & 1 deletion sys/kern/kern_selfpatch.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ 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);
static void lf_pad_with_nop(struct lf_selfpatch *p);

bool
lf_selfpatch_patch_needed(struct lf_selfpatch *p)
Expand Down Expand Up @@ -194,13 +195,13 @@ lf_selfpatch_apply(linker_file_t lf, struct lf_selfpatch *p, int mod)
* 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);
Expand Down Expand Up @@ -302,6 +303,33 @@ lf_close_module_text(struct lf_selfpatch *p)
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)
Expand Down
2 changes: 1 addition & 1 deletion sys/sys/selfpatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ typedef struct lf_selfpatch {
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);
Expand Down
1 change: 1 addition & 0 deletions sys/x86/include/selfpatch-asmacros.h
Original file line number Diff line number Diff line change
Expand Up @@ -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: \
Expand Down
2 changes: 0 additions & 2 deletions sys/x86/include/selfpatch-machdep.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__ */
48 changes: 48 additions & 0 deletions sys/x86/x86/selfpatch_machdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,51 @@ const struct ksp_selector_entry ksp_selector_table[] = {
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"
);

0 comments on commit b29c263

Please sign in to comment.