Skip to content

Commit ba50392

Browse files
authored
Merge pull request #35 from appview-team/alpine-latest
Resolve Alpine Latest Bug
2 parents 26800bb + cefd3bf commit ba50392

File tree

15 files changed

+212
-70
lines changed

15 files changed

+212
-70
lines changed

src/appviewelf.c

Lines changed: 60 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -159,14 +159,8 @@ getElf(char *path)
159159
return ebuf;
160160
}
161161

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

249+
/*
250+
* Find the GOT ptr as defined in RELA/DYNSYM (.rela.dyn) for symbol & hook it.
251+
* .rela.dyn section:
252+
* The address of relocation entries associated solely with the PLT.
253+
* The relocation table's entries have a one-to-one correspondence with the PLT.
254+
*
255+
* There are 2 relocation tables potentially used in an Elf object;
256+
* 1) relocation rel 2) relocation with addends rela
257+
* When one or the other is defined, no question. Use what is defined.
258+
* When both rel and rela are defined we need to walk both tables. Some of the symbols we want to
259+
* match are in rel and others in rela. Therefore, walk both.
260+
*
261+
* TODO: we should use a struct for param definition instead of so many passed params.
262+
*/
263+
int
264+
doGotcha(struct link_map *lm, got_list_t *hook, Elf64_Sym *sym, char *str, Elf64_Rela *rel, size_t rsz,
265+
Elf64_Rela *rela, size_t rasz, bool attach)
266+
{
267+
int matchrel = -1, matchrela = -1;
268+
269+
if (rel && (rsz > sizeof(Elf64_Rela))) {
270+
matchrel = setGot(lm, hook, sym, str, rel, rsz, attach);
271+
}
272+
273+
if (rela && (rasz > sizeof(Elf64_Rela))) {
274+
matchrela = setGot(lm, hook, sym, str, rela, rasz, attach);
275+
}
276+
277+
if ((matchrel != -1) || (matchrela != -1)) {
278+
return 0;
279+
} else {
280+
return -1;
281+
}
282+
}
283+
255284
// Locate the needed elf entries from a given link map.
285+
// TODO: we should use a struct for param definition instead of so many passed params.
256286
int
257-
getElfEntries(struct link_map *lm, Elf64_Rela **rel, Elf64_Sym **sym, char **str, int *rsz)
287+
getElfEntries(struct link_map *lm, Elf64_Sym **sym, char **str,
288+
Elf64_Rela **rel, size_t *rsz, Elf64_Rela **rela, size_t *rasz)
258289
{
259290
Elf64_Dyn *dyn = NULL;
260291
char *got = NULL; // TODO; got is not needed, debug, remove
@@ -274,6 +305,14 @@ getElfEntries(struct link_map *lm, Elf64_Rela **rel, Elf64_Sym **sym, char **str
274305
} else {
275306
*str = (char *)(dyn->d_un.d_ptr + lm->l_addr);
276307
}
308+
} else if (dyn->d_tag == DT_PLTGOT) {
309+
if (osGetPageProt((uint64_t)dyn->d_un.d_ptr) != -1) {
310+
got = (char *)(dyn->d_un.d_ptr);
311+
} else {
312+
got = (char *)(dyn->d_un.d_ptr + lm->l_addr);
313+
}
314+
appviewLog(CFG_LOG_DEBUG, "%s:%d DT_PLTGOT: 0x%lx",
315+
__FUNCTION__, __LINE__, (unsigned long int)got);
277316
} else if (dyn->d_tag == DT_JMPREL) {
278317
if (osGetPageProt((uint64_t)dyn->d_un.d_ptr) != -1) {
279318
*rel = (Elf64_Rela *)((char *)(dyn->d_un.d_ptr));
@@ -282,19 +321,25 @@ getElfEntries(struct link_map *lm, Elf64_Rela **rel, Elf64_Sym **sym, char **str
282321
}
283322
} else if (dyn->d_tag == DT_PLTRELSZ) {
284323
*rsz = dyn->d_un.d_val;
285-
} else if (dyn->d_tag == DT_PLTGOT) {
324+
} else if (dyn->d_tag == DT_RELA) {
325+
// This is a 'new' tag. Use it if present instead of DT_JMPREL
286326
if (osGetPageProt((uint64_t)dyn->d_un.d_ptr) != -1) {
287-
got = (char *)(dyn->d_un.d_ptr);
327+
*rela = (Elf64_Rela *)((char *)(dyn->d_un.d_ptr));
288328
} else {
289-
got = (char *)(dyn->d_un.d_ptr + lm->l_addr);
329+
*rela = (Elf64_Rela *)((char *)(dyn->d_un.d_ptr + lm->l_addr));
290330
}
331+
} else if (dyn->d_tag == DT_RELASZ) {
332+
// This is a 'new' tag. Use it if present instead of DT_PLTRELSZ
333+
*rasz = dyn->d_un.d_val;
291334
}
292335
}
293336

294-
appviewLog(CFG_LOG_TRACE, "%s:%d name: %s dyn %p sym %p rel %p str %p rsz %d got %p laddr 0x%lx\n",
295-
__FUNCTION__, __LINE__, lm->l_name, dyn, *sym, *rel, *str, *rsz, got, lm->l_addr);
337+
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",
338+
__FUNCTION__, __LINE__, lm->l_name, dyn, *sym, *str, *rel, *rsz, *rela, *rasz, got, lm->l_addr);
296339

297-
if (*sym == NULL || *rel == NULL || (*rsz < sizeof(Elf64_Rela))) {
340+
// if we have neither rel or rela then we have no entries
341+
if ((*sym == NULL) || (((*rel == NULL) || (*rsz < sizeof(Elf64_Rela))) &&
342+
((*rela == NULL) || (*rasz < sizeof(Elf64_Rela))))) {
298343
return -1;
299344
}
300345

src/appviewelf.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ typedef struct {
2222

2323
void freeElf(char *, size_t);
2424
elf_buf_t * getElf(char *);
25-
int doGotcha(struct link_map *, got_list_t *, Elf64_Rela *, Elf64_Sym *, char *, int, bool);
26-
int getElfEntries(struct link_map *, Elf64_Rela **, Elf64_Sym **, char **, int *rsz);
25+
int doGotcha(struct link_map *, got_list_t *, Elf64_Sym *, char *,
26+
Elf64_Rela *, size_t, Elf64_Rela *, size_t, bool);
27+
int getElfEntries(struct link_map *, Elf64_Sym **, char **,
28+
Elf64_Rela **, size_t *, Elf64_Rela **, size_t *);
2729
Elf64_Shdr* getElfSection(char *, const char *);
2830
void * getSymbol(const char *, char *);
2931
void * getDynSymbol(const char *, char *);

src/fn.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,8 @@ typedef struct {
188188
int (*SSL_read)(SSL *, void *, int);
189189
int (*SSL_write)(SSL *, const void *, int);
190190
int (*SSL_get_fd)(const SSL *);
191+
int (*SSL_read_ex)(SSL *, void *, size_t, size_t *);
192+
int (*SSL_write_ex)(SSL *, const void *, size_t, size_t *);
191193
ssize_t (*gnutls_record_recv)(gnutls_session_t, void *, size_t);
192194
ssize_t (*gnutls_record_send)(gnutls_session_t, const void *, size_t);
193195
ssize_t (*gnutls_record_recv_early_data)(gnutls_session_t, void *, size_t);

0 commit comments

Comments
 (0)