Skip to content

Alpine Latest Bug #35

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

Merged
merged 7 commits into from
Jun 25, 2024
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
75 changes: 60 additions & 15 deletions src/appviewelf.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,14 +159,8 @@ getElf(char *path)
return ebuf;
}

/*
* Find the GOT ptr as defined in RELA/DYNSYM (.rela.dyn) for symbol & hook it.
* .rela.dyn section:
* The address of relocation entries associated solely with the PLT.
* The relocation table's entries have a one-to-one correspondence with the PLT.
*/
int
doGotcha(struct link_map *lm, got_list_t *hook, Elf64_Rela *rel, Elf64_Sym *sym, char *str, int rsz, bool attach)
static int
setGot(struct link_map *lm, got_list_t *hook, Elf64_Sym *sym, char *str, Elf64_Rela *rel, size_t rsz, bool attach)
{
int i, match = -1;
uint64_t prev;
Expand Down Expand Up @@ -252,9 +246,46 @@ doGotcha(struct link_map *lm, got_list_t *hook, Elf64_Rela *rel, Elf64_Sym *sym,
return match;
}

/*
* Find the GOT ptr as defined in RELA/DYNSYM (.rela.dyn) for symbol & hook it.
* .rela.dyn section:
* The address of relocation entries associated solely with the PLT.
* The relocation table's entries have a one-to-one correspondence with the PLT.
*
* There are 2 relocation tables potentially used in an Elf object;
* 1) relocation rel 2) relocation with addends rela
* When one or the other is defined, no question. Use what is defined.
* When both rel and rela are defined we need to walk both tables. Some of the symbols we want to
* match are in rel and others in rela. Therefore, walk both.
*
* TODO: we should use a struct for param definition instead of so many passed params.
*/
int
doGotcha(struct link_map *lm, got_list_t *hook, Elf64_Sym *sym, char *str, Elf64_Rela *rel, size_t rsz,
Elf64_Rela *rela, size_t rasz, bool attach)
{
int matchrel = -1, matchrela = -1;

if (rel && (rsz > sizeof(Elf64_Rela))) {
matchrel = setGot(lm, hook, sym, str, rel, rsz, attach);
}

if (rela && (rasz > sizeof(Elf64_Rela))) {
matchrela = setGot(lm, hook, sym, str, rela, rasz, attach);
}

if ((matchrel != -1) || (matchrela != -1)) {
return 0;
} else {
return -1;
}
}

// Locate the needed elf entries from a given link map.
// TODO: we should use a struct for param definition instead of so many passed params.
int
getElfEntries(struct link_map *lm, Elf64_Rela **rel, Elf64_Sym **sym, char **str, int *rsz)
getElfEntries(struct link_map *lm, Elf64_Sym **sym, char **str,
Elf64_Rela **rel, size_t *rsz, Elf64_Rela **rela, size_t *rasz)
{
Elf64_Dyn *dyn = NULL;
char *got = NULL; // TODO; got is not needed, debug, remove
Expand All @@ -274,6 +305,14 @@ getElfEntries(struct link_map *lm, Elf64_Rela **rel, Elf64_Sym **sym, char **str
} else {
*str = (char *)(dyn->d_un.d_ptr + lm->l_addr);
}
} else if (dyn->d_tag == DT_PLTGOT) {
if (osGetPageProt((uint64_t)dyn->d_un.d_ptr) != -1) {
got = (char *)(dyn->d_un.d_ptr);
} else {
got = (char *)(dyn->d_un.d_ptr + lm->l_addr);
}
appviewLog(CFG_LOG_DEBUG, "%s:%d DT_PLTGOT: 0x%lx",
__FUNCTION__, __LINE__, (unsigned long int)got);
} else if (dyn->d_tag == DT_JMPREL) {
if (osGetPageProt((uint64_t)dyn->d_un.d_ptr) != -1) {
*rel = (Elf64_Rela *)((char *)(dyn->d_un.d_ptr));
Expand All @@ -282,19 +321,25 @@ getElfEntries(struct link_map *lm, Elf64_Rela **rel, Elf64_Sym **sym, char **str
}
} else if (dyn->d_tag == DT_PLTRELSZ) {
*rsz = dyn->d_un.d_val;
} else if (dyn->d_tag == DT_PLTGOT) {
} else if (dyn->d_tag == DT_RELA) {
// This is a 'new' tag. Use it if present instead of DT_JMPREL
if (osGetPageProt((uint64_t)dyn->d_un.d_ptr) != -1) {
got = (char *)(dyn->d_un.d_ptr);
*rela = (Elf64_Rela *)((char *)(dyn->d_un.d_ptr));
} else {
got = (char *)(dyn->d_un.d_ptr + lm->l_addr);
*rela = (Elf64_Rela *)((char *)(dyn->d_un.d_ptr + lm->l_addr));
}
} else if (dyn->d_tag == DT_RELASZ) {
// This is a 'new' tag. Use it if present instead of DT_PLTRELSZ
*rasz = dyn->d_un.d_val;
}
}

appviewLog(CFG_LOG_TRACE, "%s:%d name: %s dyn %p sym %p rel %p str %p rsz %d got %p laddr 0x%lx\n",
__FUNCTION__, __LINE__, lm->l_name, dyn, *sym, *rel, *str, *rsz, got, lm->l_addr);
appviewLog(CFG_LOG_DEBUG, "%s:%d name: %s dyn %p sym %p str %p rel %p rsz %ld rela %p rasz %ld got %p laddr 0x%lx",
__FUNCTION__, __LINE__, lm->l_name, dyn, *sym, *str, *rel, *rsz, *rela, *rasz, got, lm->l_addr);

if (*sym == NULL || *rel == NULL || (*rsz < sizeof(Elf64_Rela))) {
// if we have neither rel or rela then we have no entries
if ((*sym == NULL) || (((*rel == NULL) || (*rsz < sizeof(Elf64_Rela))) &&
((*rela == NULL) || (*rasz < sizeof(Elf64_Rela))))) {
return -1;
}

Expand Down
6 changes: 4 additions & 2 deletions src/appviewelf.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ typedef struct {

void freeElf(char *, size_t);
elf_buf_t * getElf(char *);
int doGotcha(struct link_map *, got_list_t *, Elf64_Rela *, Elf64_Sym *, char *, int, bool);
int getElfEntries(struct link_map *, Elf64_Rela **, Elf64_Sym **, char **, int *rsz);
int doGotcha(struct link_map *, got_list_t *, Elf64_Sym *, char *,
Elf64_Rela *, size_t, Elf64_Rela *, size_t, bool);
int getElfEntries(struct link_map *, Elf64_Sym **, char **,
Elf64_Rela **, size_t *, Elf64_Rela **, size_t *);
Elf64_Shdr* getElfSection(char *, const char *);
void * getSymbol(const char *, char *);
void * getDynSymbol(const char *, char *);
Expand Down
2 changes: 2 additions & 0 deletions src/fn.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ typedef struct {
int (*SSL_read)(SSL *, void *, int);
int (*SSL_write)(SSL *, const void *, int);
int (*SSL_get_fd)(const SSL *);
int (*SSL_read_ex)(SSL *, void *, size_t, size_t *);
int (*SSL_write_ex)(SSL *, const void *, size_t, size_t *);
ssize_t (*gnutls_record_recv)(gnutls_session_t, void *, size_t);
ssize_t (*gnutls_record_send)(gnutls_session_t, const void *, size_t);
ssize_t (*gnutls_record_recv_early_data)(gnutls_session_t, void *, size_t);
Expand Down
Loading
Loading