Skip to content

Commit

Permalink
Merge pull request #223 from jpoimboe/dynrela-loc-check
Browse files Browse the repository at this point in the history
kmod/core: validate dynrela destination address
  • Loading branch information
sjenning committed May 30, 2014
2 parents ad8f229 + ecf6173 commit 26a75e5
Showing 1 changed file with 17 additions and 6 deletions.
23 changes: 17 additions & 6 deletions kmod/core/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -462,8 +462,9 @@ static int kpatch_write_relocations(struct kpatch_module *kpmod)
int ret, i, size, readonly = 0;
struct kpatch_dynrela *dynrela;
u64 loc, val;
pte_t *pte;
unsigned int level;
unsigned long core = (unsigned long)kpmod->mod->module_core;
unsigned long core_ro_size = kpmod->mod->core_ro_size;
unsigned long core_size = kpmod->mod->core_size;

for (i = 0; i < kpmod->dynrelas_nr; i++) {
dynrela = &kpmod->dynrelas[i];
Expand Down Expand Up @@ -492,19 +493,29 @@ static int kpatch_write_relocations(struct kpatch_module *kpmod)
return -EINVAL;
}

pte = lookup_address(loc, &level);
if (!pte_write(*pte)) {
if (loc >= core && loc < core + core_ro_size)
readonly = 1;
set_memory_rw(loc & PAGE_MASK, 1);
else if (loc >= core + core_ro_size && loc < core + core_size)
readonly = 0;
else {
pr_err("bad dynrela location 0x%llx for symbol %s\n",
loc, dynrela->name);
return -EINVAL;
}

if (readonly)
set_memory_rw(loc & PAGE_MASK, 1);

ret = probe_kernel_write((void *)loc, &val, size);

if (readonly)
set_memory_ro(loc & PAGE_MASK, 1);

if (ret)
if (ret) {
pr_err("write to 0x%llx failed for symbol %s\n",
loc, dynrela->name);
return ret;
}
}

return 0;
Expand Down

0 comments on commit 26a75e5

Please sign in to comment.