diff options
author | Mark Johnston <markj@FreeBSD.org> | 2017-02-05 02:44:08 +0000 |
---|---|---|
committer | Mark Johnston <markj@FreeBSD.org> | 2017-02-05 02:44:08 +0000 |
commit | 273efb05a21a9b60088b887440fafa062837a392 (patch) | |
tree | 66376309890dd477ada06259c1de7a04abd69095 | |
parent | e801af6fba428bbac170018f9ff69e4596d06b3b (diff) | |
download | src-273efb05a21a9b60088b887440fafa062837a392.tar.gz src-273efb05a21a9b60088b887440fafa062837a392.zip |
Fix a double free of libelf data buffers in the USDT link code.
libdtrace needs to append to the input object files' string and symbol
tables. Currently it does so by allocating a larger buffer, copying the
existing sections into them, and swapping pointers in the libelf data
descriptors. However, it also frees those buffers when its processing is
complete, which leads to a double free since the elftoolchain libelf
owns them and also frees them in elf_end(3). Instead, free the buffers
originally allocated by libelf.
MFC after: 2 weeks
Notes
Notes:
svn path=/head/; revision=313263
-rw-r--r-- | cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c index ac4af00ee4f2..c52826c6b818 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c @@ -1205,6 +1205,7 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp) key_t objkey; dt_link_pair_t *pair, *bufs = NULL; dt_strtab_t *strtab; + void *tmp; if ((fd = open64(obj, O_RDWR)) == -1) { return (dt_link_error(dtp, elf, fd, bufs, @@ -1463,7 +1464,9 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp) bufs = pair; bcopy(data_str->d_buf, pair->dlp_str, data_str->d_size); + tmp = data_str->d_buf; data_str->d_buf = pair->dlp_str; + pair->dlp_str = tmp; data_str->d_size += len; (void) elf_flagdata(data_str, ELF_C_SET, ELF_F_DIRTY); @@ -1471,7 +1474,9 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp) (void) gelf_update_shdr(scn_str, &shdr_str); bcopy(data_sym->d_buf, pair->dlp_sym, data_sym->d_size); + tmp = data_sym->d_buf; data_sym->d_buf = pair->dlp_sym; + pair->dlp_sym = tmp; data_sym->d_size += nsym * symsize; (void) elf_flagdata(data_sym, ELF_C_SET, ELF_F_DIRTY); @@ -1657,9 +1662,6 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp) (void) elf_end(elf); (void) close(fd); -#ifndef illumos - if (nsym > 0) -#endif while ((pair = bufs) != NULL) { bufs = pair->dlp_next; dt_free(dtp, pair->dlp_str); |