Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UCM: Use correct pointer for original 'free' when patching plt. #1626

Merged
merged 1 commit into from
Jun 21, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/ucm/malloc/malloc_hook.c
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,8 @@ ucs_status_t ucm_malloc_install(int events)
ucm_debug("installing malloc relocations");
ucm_malloc_populate_glibc_cache();
ucm_malloc_install_symbols(ucm_malloc_symbol_patches);
ucs_assert(ucm_malloc_symbol_patches[0].value == ucm_free);
ucm_malloc_hook_state.free = ucm_malloc_symbol_patches[0].prev_value;
ucm_malloc_hook_state.install_state |= UCM_MALLOC_INSTALLED_MALL_SYMS;
}
} else {
Expand Down
28 changes: 15 additions & 13 deletions src/ucm/util/reloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,13 @@ typedef struct ucm_auxv {
long value;
} UCS_S_PACKED ucm_auxv_t;


typedef struct ucm_reloc_dl_iter_context {
const char *symbol;
void *newvalue;
ucs_status_t status;
ucm_reloc_patch_t *patch;
ucs_status_t status;
} ucm_reloc_dl_iter_context_t;


/* List of patches to be applied to additional libraries */
static UCS_LIST_HEAD(ucm_reloc_patch_list);
static void * (*ucm_reloc_orig_dlopen)(const char *, int) = NULL;
Expand Down Expand Up @@ -142,7 +143,7 @@ static int ucm_reloc_get_aux_phsize()

static ucs_status_t
ucm_reloc_modify_got(ElfW(Addr) base, const ElfW(Phdr) *phdr, const char *phname,
int phnum, int phsize, const char *symbol, void *newvalue)
int phnum, int phsize, ucm_reloc_patch_t *patch)
{
ElfW(Phdr) *dphdr;
ElfW(Rela) *reloc;
Expand Down Expand Up @@ -183,19 +184,20 @@ ucm_reloc_modify_got(ElfW(Addr) base, const ElfW(Phdr) *phdr, const char *phname
/* Find matching symbol and replace it */
for (reloc = jmprel; (void*)reloc < jmprel + pltrelsz; ++reloc) {
elf_sym = (char*)strtab + symtab[ELF64_R_SYM(reloc->r_info)].st_name;
if (!strcmp(symbol, elf_sym)) {
if (!strcmp(patch->symbol, elf_sym)) {
entry = (void *)(base + reloc->r_offset);

ucm_trace("'%s' entry in '%s' is at %p", symbol, basename(phname),
entry);
ucm_trace("'%s' entry in '%s' is at %p", patch->symbol,
basename(phname), entry);

page = (void *)((intptr_t)entry & ~(page_size - 1));
ret = mprotect(page, page_size, PROT_READ|PROT_WRITE);
if (ret < 0) {
ucm_error("failed to modify GOT page %p to rw: %m", page);
return UCS_ERR_UNSUPPORTED;
}
*entry = newvalue;
patch->prev_value = *entry;
*entry = patch->value;
break;
}
}
Expand All @@ -217,7 +219,7 @@ static int ucm_reloc_phdr_iterator(struct dl_phdr_info *info, size_t size, void

ctx->status = ucm_reloc_modify_got(info->dlpi_addr, info->dlpi_phdr,
info->dlpi_name, info->dlpi_phnum,
phsize, ctx->symbol, ctx->newvalue);
phsize, ctx->patch);
if (ctx->status == UCS_OK) {
return 0; /* continue iteration and patch all objects */
} else {
Expand All @@ -229,17 +231,17 @@ static int ucm_reloc_phdr_iterator(struct dl_phdr_info *info, size_t size, void
static ucs_status_t ucm_reloc_apply_patch(ucm_reloc_patch_t *patch)
{
ucm_reloc_dl_iter_context_t ctx = {
.symbol = patch->symbol,
.newvalue = patch->value,
.status = UCS_OK
.patch = patch,
.status = UCS_OK
};

/* Avoid locks here because we don't modify ELF data structures.
* Worst case the same symbol will be written more than once.
*/
(void)dl_iterate_phdr(ucm_reloc_phdr_iterator, &ctx);
if (ctx.status == UCS_OK) {
ucm_debug("modified '%s' to %p", ctx.symbol, ctx.newvalue);
ucm_debug("modified '%s' from %p to %p", patch->symbol,
patch->prev_value, patch->value);
}
return ctx.status;
}
Expand Down
1 change: 1 addition & 0 deletions src/ucm/util/reloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
typedef struct ucm_reloc_patch {
const char *symbol;
void *value;
void *prev_value;
ucs_list_link_t list;
} ucm_reloc_patch_t;

Expand Down