From dfd00261c95a9839ba528f7e052d9bcac19f2b14 Mon Sep 17 00:00:00 2001 From: Chuck Silvers Date: Fri, 3 Dec 2021 11:03:32 -0800 Subject: [PATCH] librtld_db: Handle shlibs with discontiguous mappings. Some shared libraries specify mappings that leave a gap (actually a MAP_GUARD mapping) in between the file mappings (libcrypto.so was the one I found), and this would cause rd_loadobj_iter() to report the mapping info incorrectly, leaving out rdl_path and misreporting rdl_offset for file mappings after the gap. Fix rd_loadobj_iter() to handle this situation. Reviewed by: markj Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D32950 --- lib/librtld_db/rtld_db.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/librtld_db/rtld_db.c b/lib/librtld_db/rtld_db.c index 9edeecfb95c5..18e16f36e62c 100644 --- a/lib/librtld_db/rtld_db.c +++ b/lib/librtld_db/rtld_db.c @@ -165,6 +165,7 @@ rd_loadobj_iter(rd_agent_t *rdap, rl_iter_f *cb, void *clnt_data) rd_loadobj_t rdl; rd_err_e ret; uintptr_t base; + uint32_t offset; int cnt, i; DPRINTF("%s\n", __func__); @@ -190,11 +191,12 @@ rd_loadobj_iter(rd_agent_t *rdap, rl_iter_f *cb, void *clnt_data) if (kve->kve_vn_fileid != fileid) { base = kve->kve_start; fileid = kve->kve_vn_fileid; - path = kve->kve_path; } + path = kve->kve_path; + offset = kve->kve_start - base; } else { - base = 0; path = NULL; + offset = 0; } memset(&rdl, 0, sizeof(rdl)); /* @@ -202,7 +204,7 @@ rd_loadobj_iter(rd_agent_t *rdap, rl_iter_f *cb, void *clnt_data) */ rdl.rdl_saddr = kve->kve_start; rdl.rdl_eaddr = kve->kve_end; - rdl.rdl_offset = kve->kve_start - base; + rdl.rdl_offset = offset; if (kve->kve_protection & KVME_PROT_READ) rdl.rdl_prot |= RD_RDL_R; if (kve->kve_protection & KVME_PROT_WRITE)