Skip to content

rtld: Tweak handling of mismatched dynamic tags for PLTs #2366

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

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
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
47 changes: 23 additions & 24 deletions libexec/rtld-elf/rtld.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@
*/
static const char *basename(const char *);
static bool digest_dynamic(Obj_Entry *, int);
static void digest_dynamic1(Obj_Entry *, int, const Elf_Dyn **,
static bool digest_dynamic1(Obj_Entry *, int, const Elf_Dyn **,
const Elf_Dyn **, const Elf_Dyn **);
static bool digest_dynamic2(Obj_Entry *, const Elf_Dyn *, const Elf_Dyn *,
const Elf_Dyn *);
Expand Down Expand Up @@ -1580,7 +1580,7 @@
* Process a shared object's DYNAMIC section, and save the important
* information in its Obj_Entry structure.
*/
static void
static bool
digest_dynamic1(Obj_Entry *obj, int early, const Elf_Dyn **dyn_rpath,
const Elf_Dyn **dyn_soname, const Elf_Dyn **dyn_runpath)
{
Expand All @@ -1604,7 +1604,7 @@
obj->bind_now = false;
dynp = obj->dynamic;
if (dynp == NULL)
return;
return (true);
obj->nplts = count_plts(dynp);
if (obj->nplts != 0)
obj->plts = xcalloc(obj->nplts, sizeof(*obj->plts));
Expand Down Expand Up @@ -1934,12 +1934,19 @@
free(obj->plts);
obj->plts = NULL;
obj->nplts = 0;
pltrelsz = 0;
}
#endif

if (plttype == DT_RELA) {
for (i = 0; i < obj->nplts; i++) {
plt = &obj->plts[i];
if (!(jmprel == pltrelsz && jmprel == pltgot)) {
_rtld_error("PLT dynamic tag mismatch");
return (false);
}

for (i = 0; i < obj->nplts; i++) {
plt = &obj->plts[i];
plt->obj = obj;
if (plttype == DT_RELA) {
plt->rela = (const Elf_Rela *) plt->rel;
plt->rel = NULL;
plt->relasize = plt->relsize;
Expand All @@ -1966,6 +1973,8 @@
if (obj->linkmap.l_refname != NULL)
obj->linkmap.l_refname = obj->strtab + (unsigned long)obj->
linkmap.l_refname;

return (true);
}

static bool
Expand All @@ -1982,19 +1991,6 @@
digest_dynamic2(Obj_Entry *obj, const Elf_Dyn *dyn_rpath,
const Elf_Dyn *dyn_soname, const Elf_Dyn *dyn_runpath)
{
Plt_Entry *plt;
unsigned long i;

for (i = 0; i < obj->nplts; i++) {
plt = &obj->plts[i];
if (plt->pltgot == NULL)
return (false);
if (plt->rel == NULL && plt->rela == NULL)
return (false);
if (plt->relsize == 0 && plt->relasize == 0)
return (false);
plt->obj = obj;
}
if (obj->z_origin && !obj_resolve_origin(obj))
return (false);

Expand All @@ -2017,8 +2013,8 @@
// any overflows at runtime.
set_bounds_if_nonnull(obj->rel, obj->relsize);
set_bounds_if_nonnull(obj->rela, obj->relasize);
for (i = 0; i < obj->nplts; i++) {
plt = &obj->plts[i];
for (unsigned long i = 0; i < obj->nplts; i++) {
Plt_Entry *plt = &obj->plts[i];
set_bounds_if_nonnull(plt->rel, plt->relsize);
set_bounds_if_nonnull(plt->rela, plt->relasize);
}
Expand Down Expand Up @@ -2049,7 +2045,8 @@
const Elf_Dyn *dyn_soname;
const Elf_Dyn *dyn_runpath;

digest_dynamic1(obj, early, &dyn_rpath, &dyn_soname, &dyn_runpath);
if (!digest_dynamic1(obj, early, &dyn_rpath, &dyn_soname, &dyn_runpath))
return (false);
return (digest_dynamic2(obj, dyn_rpath, dyn_soname, dyn_runpath));
}

Expand Down Expand Up @@ -2911,7 +2908,8 @@
#endif

objtmp.dynamic = rtld_dynamic(&objtmp);
digest_dynamic1(&objtmp, 1, &dyn_rpath, &dyn_soname, &dyn_runpath);
if (!digest_dynamic1(&objtmp, 1, &dyn_rpath, &dyn_soname, &dyn_runpath))
rtld_die();
assert(objtmp.needed == NULL);
assert(!objtmp.textrel);
ehdr = (Elf_Ehdr *)mapbase;
Expand Down Expand Up @@ -2965,10 +2963,11 @@
if (aux_info[AT_OSRELDATE] != NULL)
osreldate = aux_info[AT_OSRELDATE]->a_un.a_val;

digest_dynamic2(&obj_rtld, dyn_rpath, dyn_soname, dyn_runpath);
if (!digest_dynamic2(&obj_rtld, dyn_rpath, dyn_soname, dyn_runpath))
rtld_die();

/* Replace the path with a dynamically allocated copy. */
obj_rtld.path = xstrdup(ld_path_rtld);

Check warning on line 2970 in libexec/rtld-elf/rtld.c

View workflow job for this annotation

GitHub Actions / Style Checker

Missing Signed-off-by: line

Check warning on line 2970 in libexec/rtld-elf/rtld.c

View workflow job for this annotation

GitHub Actions / Style Checker

Missing Signed-off-by: line

parse_rtld_phdr(&obj_rtld);
#ifndef __CHERI_PURE_CAPABILITY__
Expand Down