kmod/core: ensure the readonly flag is reset correctly

When the core module loops through an object's list of dynrelas, it
determines whether or not the target location of the dynrela is in a
read-only region of the patch module. If it is, the readonly flag is set to
1 and it calls set_memory_{rw,ro} before and after the probe_kernel_write()
operation. This flag gets set once, and never gets reset for subsequent
iterations. Therefore, if a target happens to be in a RW section of the
patch module, and readonly = 1 had been set before, we may unintentionally
set a normally RW page to RO. Fix this by setting the readonly flag with
each iteration of the loop.

Fixes #681.
This commit is contained in:
Jessica Yu 2017-03-02 17:29:38 -08:00
parent 6ae49e36be
commit a095b4ed41

View File

@ -681,11 +681,10 @@ static int kpatch_write_relocations(struct kpatch_module *kpmod,
( LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) && \
UTS_UBUNTU_RELEASE_ABI >= 7 ) \
)
if (loc < core + kpmod->mod->core_layout.ro_size)
readonly = (loc < core + kpmod->mod->core_layout.ro_size);
#else
if (loc < core + kpmod->mod->core_ro_size)
readonly = (loc < core + kpmod->mod->core_ro_size);
#endif
readonly = 1;
#endif
numpages = (PAGE_SIZE - (loc & ~PAGE_MASK) >= size) ? 1 : 2;