diff --git a/src/appviewelf.c b/src/appviewelf.c index 321e3f66..74a47f22 100644 --- a/src/appviewelf.c +++ b/src/appviewelf.c @@ -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; @@ -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 @@ -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)); @@ -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; } diff --git a/src/appviewelf.h b/src/appviewelf.h index b2e24194..c5e3e6d4 100644 --- a/src/appviewelf.h +++ b/src/appviewelf.h @@ -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 *); diff --git a/src/fn.h b/src/fn.h index de5ddce1..5504a60d 100644 --- a/src/fn.h +++ b/src/fn.h @@ -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); diff --git a/src/wrap.c b/src/wrap.c index 66f7b27f..33cac282 100644 --- a/src/wrap.c +++ b/src/wrap.c @@ -45,6 +45,8 @@ #define SSL_FUNC_READ "SSL_read" #define SSL_FUNC_WRITE "SSL_write" +#define SSL_FUNC_READ_EX "SSL_read_ex" +#define SSL_FUNC_WRITE_EX "SSL_write_ex" static thread_timing g_thread = {0}; static config_t *g_staticfg = NULL; @@ -58,6 +60,8 @@ static rlim_t g_max_fds = 0; typedef int (*ssl_rdfunc_t)(SSL *, void *, int); typedef int (*ssl_wrfunc_t)(SSL *, const void *, int); +typedef int (*ssl_rdfuncex_t)(SSL *, void *, size_t, size_t *); +typedef int (*ssl_wrfuncex_t)(SSL *, const void *, size_t, size_t *); __thread int g_getdelim = 0; __thread int g_ssl_fd = -1; @@ -283,9 +287,9 @@ hookAll(struct dl_phdr_info *info, size_t size, void *data) struct link_map *lm; Elf64_Sym *sym = NULL; - Elf64_Rela *rel = NULL; + Elf64_Rela *rel = NULL, *rela = NULL; char *str = NULL; - int rsz = 0; + size_t rsz = 0, rasz = 0; bool *rules = data; appviewLog(CFG_LOG_DEBUG, "%s: shared obj: %s", __FUNCTION__, info->dlpi_name); @@ -310,13 +314,15 @@ hookAll(struct dl_phdr_info *info, size_t size, void *data) if (handle == NULL) return FALSE; // Get the link map and ELF sections in advance of something matching - if ((dlinfo(handle, RTLD_DI_LINKMAP, (void *)&lm) != -1) && (getElfEntries(lm, &rel, &sym, &str, &rsz) != -1)) { + if ((dlinfo(handle, RTLD_DI_LINKMAP, (void *)&lm) != -1) && + (getElfEntries(lm, &sym, &str, &rel, &rsz, &rela, &rasz) != -1)) { for (int i=0; inject_hook_list[i].symbol; i++) { // if the proc passes the rules then GOT hook all else only hook execve // TODO; all execv? if (((*rules == TRUE) || appview_strstr(inject_hook_list[i].symbol, "execve")) && dlsym(handle, inject_hook_list[i].symbol)) { - if (doGotcha(lm, (got_list_t *)&inject_hook_list[i], rel, sym, str, rsz, TRUE) != -1) { + if (doGotcha(lm, (got_list_t *)&inject_hook_list[i], sym, str, + rel, rsz, rela, rasz, TRUE) != -1) { appviewLog(CFG_LOG_DEBUG, "\tGOT patched %s from shared obj %s", inject_hook_list[i].symbol, info->dlpi_name); } @@ -335,9 +341,9 @@ hookAllAttach(struct dl_phdr_info *info, size_t size, void *data) struct link_map *lm; Elf64_Sym *sym = NULL; - Elf64_Rela *rel = NULL; + Elf64_Rela *rel = NULL, *rela = NULL; char *str = NULL; - int rsz = 0; + size_t rsz = 0, rasz = 0; bool *rules = data; appviewLog(CFG_LOG_DEBUG, "%s: shared obj: %s", __FUNCTION__, info->dlpi_name); @@ -351,13 +357,15 @@ hookAllAttach(struct dl_phdr_info *info, size_t size, void *data) if (handle == NULL) return FALSE; // Get the link map and ELF sections in advance of something matching - if ((dlinfo(handle, RTLD_DI_LINKMAP, (void *)&lm) != -1) && (getElfEntries(lm, &rel, &sym, &str, &rsz) != -1)) { + if ((dlinfo(handle, RTLD_DI_LINKMAP, (void *)&lm) != -1) && + (getElfEntries(lm, &sym, &str, &rel, &rsz, &rela, &rasz) != -1)) { for (int i=0; inject_hook_list[i].symbol; i++) { // if the proc passes the rules then GOT hook all else only hook execve // TODO; all execv? if (((*rules == TRUE) || appview_strstr(inject_hook_list[i].symbol, "execve")) && dlsym(handle, inject_hook_list[i].symbol)) { - if (doGotcha(lm, (got_list_t *)&inject_hook_list[i], rel, sym, str, rsz, TRUE) != -1) { + if (doGotcha(lm, (got_list_t *)&inject_hook_list[i], sym, str, + rel, rsz, rela, rasz, TRUE) != -1) { appviewLog(CFG_LOG_DEBUG, "\tGOT patched %s from shared obj %s", inject_hook_list[i].symbol, info->dlpi_name); } @@ -374,21 +382,23 @@ hookMain(bool rules) { struct link_map *lm; Elf64_Sym *sym = NULL; - Elf64_Rela *rel = NULL; + Elf64_Rela *rel = NULL, *rela = NULL; char *str = NULL; - int rsz = 0; + size_t rsz = 0, rasz = 0; void *handle = g_fn.dlopen(NULL, RTLD_NOW); if (handle == NULL) return FALSE; // Get the link map and ELF sections in advance of something matching - if ((dlinfo(handle, RTLD_DI_LINKMAP, (void *)&lm) != -1) && (getElfEntries(lm, &rel, &sym, &str, &rsz) != -1)) { + if ((dlinfo(handle, RTLD_DI_LINKMAP, (void *)&lm) != -1) && + (getElfEntries(lm, &sym, &str, &rel, &rsz, &rela, &rasz) != -1)) { for (int i=0; inject_hook_list[i].symbol; i++) { // if the proc passes the rules then GOT hook all else only hook execve // TODO; all execv? if (((rules == TRUE) || appview_strstr(inject_hook_list[i].symbol, "execve")) && dlsym(handle, inject_hook_list[i].symbol)) { - if (doGotcha(lm, (got_list_t *)&inject_hook_list[i], rel, sym, str, rsz, TRUE) != -1) { + if (doGotcha(lm, (got_list_t *)&inject_hook_list[i], sym, str, + rel, rsz, rela, rasz, TRUE) != -1) { appviewLog(CFG_LOG_DEBUG, "\tGOT patched %s from main", inject_hook_list[i].symbol); } } @@ -409,9 +419,9 @@ unHookAll(struct dl_phdr_info *info, size_t size, void *data) struct link_map *lm; Elf64_Sym *sym = NULL; - Elf64_Rela *rel = NULL; + Elf64_Rela *rel = NULL, *rela = NULL; char *str = NULL; - int rsz = 0; + size_t rsz = 0, rasz = 0; appviewLog(CFG_LOG_DEBUG, "%s: shared obj: %s", __FUNCTION__, info->dlpi_name); @@ -422,9 +432,11 @@ unHookAll(struct dl_phdr_info *info, size_t size, void *data) if (handle == NULL) return FALSE; // Get the link map and ELF sections in advance of something matching - if ((dlinfo(handle, RTLD_DI_LINKMAP, (void *)&lm) != -1) && (getElfEntries(lm, &rel, &sym, &str, &rsz) != -1)) { + if ((dlinfo(handle, RTLD_DI_LINKMAP, (void *)&lm) != -1) && + (getElfEntries(lm, &sym, &str, &rel, &rsz, &rela, &rasz) != -1)) { for (int i=0; inject_hook_list[i].symbol; i++) { - if (doGotcha(lm, (got_list_t *)&inject_hook_list[i], rel, sym, str, rsz, FALSE) != -1) { + if (doGotcha(lm, (got_list_t *)&inject_hook_list[i], sym, str, + rel, rsz, rela, rasz, FALSE) != -1) { appviewLog(CFG_LOG_DEBUG, "\tGOT detached %s from shared obj %s", inject_hook_list[i].symbol, info->dlpi_name); } @@ -1330,6 +1342,42 @@ ssl_write_hook(SSL *ssl, void *buf, int num) return rc; } +static int +ssl_read_ex_hook(SSL *ssl, void *buf, size_t num, size_t *readbytes) +{ + int rc; + + WRAP_CHECK(SSL_read_ex, -1); + rc = g_fn.SSL_read_ex(ssl, buf, num, readbytes); + + if (rc) { + int fd = -1; + if (SYMBOL_LOADED(SSL_get_fd)) fd = g_fn.SSL_get_fd(ssl); + if ((fd == -1) && (g_ssl_fd != -1)) fd = g_ssl_fd; + doProtocol((uint64_t)ssl, fd, buf, *readbytes, TLSRX, BUF); + } + return rc; +} + +static int +ssl_write_ex_hook(SSL *ssl, const void *buf, size_t num, size_t *writebytes) +{ + int rc; + + WRAP_CHECK(SSL_write_ex, -1); + + rc = g_fn.SSL_write_ex(ssl, buf, num, writebytes); + + if (rc) { + int fd = -1; + if (SYMBOL_LOADED(SSL_get_fd)) fd = g_fn.SSL_get_fd(ssl); + if ((fd == -1) && (g_ssl_fd != -1)) fd = g_ssl_fd; + doProtocol((uint64_t)ssl, fd, (void *)buf, *writebytes, TLSTX, BUF); + } + return rc; +} + + static void * load_func(const char *module, const char *func) { @@ -1440,9 +1488,9 @@ hookSharedObjs(struct dl_phdr_info *info, size_t size, void *data) struct link_map *lm; Elf64_Sym *sym = NULL; - Elf64_Rela *rel = NULL; + Elf64_Rela *rel = NULL, *rela = NULL; char *str = NULL; - int rsz = 0; + size_t rsz = 0, rasz = 0; const char *libname = NULL; // don't attempt to hook libappview.so, libc*.so, ld-*.so @@ -1462,11 +1510,13 @@ hookSharedObjs(struct dl_phdr_info *info, size_t size, void *data) if (handle == NULL) return FALSE; // Get the link map and ELF sections in advance of something matching - if ((dlinfo(handle, RTLD_DI_LINKMAP, (void *)&lm) != -1) && (getElfEntries(lm, &rel, &sym, &str, &rsz) != -1)) { + if ((dlinfo(handle, RTLD_DI_LINKMAP, (void *)&lm) != -1) && + (getElfEntries(lm, &sym, &str, &rel, &rsz, &rela, &rasz) != -1)) { for (int i=0; inject_hook_list[i].symbol; i++) { if ((dlsym(handle, inject_hook_list[i].symbol)) && - (doGotcha(lm, (got_list_t *)&inject_hook_list[i], rel, sym, str, rsz, TRUE) != -1)) { + (doGotcha(lm, (got_list_t *)&inject_hook_list[i], sym, str, + rel, rsz, rela, rasz, TRUE) != -1)) { appviewLog(CFG_LOG_DEBUG, "\tGOT patched %s from shared obj %s", inject_hook_list[i].symbol, info->dlpi_name); } @@ -2014,6 +2064,13 @@ isSystemFunc(char *func) static int inspectLib(struct dl_phdr_info *info, size_t size, void *data) { + if (!info || !info->dlpi_name) return 0; + + // don't test funcs from libappview, ld.so or main + if (appview_strstr(info->dlpi_name, "libappview") || + appview_strstr(info->dlpi_name, "ld-") || + (appview_strstr(info->dlpi_name, "lib") == NULL)) return 0; + void *handle = g_fn.dlopen(info->dlpi_name, RTLD_LAZY); if (!handle) return 0; @@ -2021,24 +2078,42 @@ inspectLib(struct dl_phdr_info *info, size_t size, void *data) if (dlinfo(handle, RTLD_DI_LINKMAP, &lm) == -1) return 0; Elf64_Sym *sym = NULL; - Elf64_Rela *rel = NULL; + Elf64_Rela *rel = NULL, *rela = NULL; char *str = NULL; - int rsz = 0; - if (getElfEntries(lm, &rel, &sym, &str, &rsz) == -1) return 0; + size_t rsz = 0, rasz = 0; + + if (getElfEntries(lm, &sym, &str, &rel, &rsz, &rela, &rasz) == -1) return 0; + if (!rel || !sym || !str || (rsz == 0)) return 0; + rsz /= sizeof(Elf64_Rela); + // TODO: we only walk the rel table. Need to update to also walk rela if defined. for (int i = 0; i < rsz; i++) { // get info that is derived from the link map char *fname = sym[ELF64_R_SYM(rel[i].r_info)].st_name + str; uint64_t got_addr = rel[i].r_offset + lm->l_addr; + if (!got_addr) continue; + uint64_t got_value = *((uint64_t *)got_addr); if (!fname || !got_value) continue; + // when DT_RELA is used in relro execs it's possible that a sym is not found + if (!appview_strlen(fname)) continue; + char *file_from_got_value = osFileNameFromAddr(got_value); if (!file_from_got_value) goto next; // FYI: file_from_link_map is sometimes NULL and that's legit. - char *file_from_link_map = appview_realpath(info->dlpi_name, NULL); + char *file_from_link_map = NULL; + if (g_isgo) { + // Try not to create a large stack with Go + file_from_link_map = appview_realpath(info->dlpi_name, NULL); + } else { + char link_map_file[PATH_MAX]; + if (appview_realpath(info->dlpi_name, link_map_file) != NULL) { + file_from_link_map = link_map_file; + } + } /* * Ignore got values that are resolved within it's own library. @@ -2108,17 +2183,17 @@ inspectLib(struct dl_phdr_info *info, size_t size, void *data) !appview_strcmp(file_from_got_value, "[vdso]")) goto next; #ifdef DEBUG - printf("%s:%d fname link map %s fname dladdr1 %s addr GOT 0x%lx addr dladdr1 %p\n", - __FUNCTION__, __LINE__, fname, dl_info.dli_sname, got_value, dl_info.dli_saddr); + appview_printf("%s:%d fname link map %s fname dladdr1 %s addr GOT 0x%lx addr dladdr1 %p\n", + __FUNCTION__, __LINE__, fname, dl_info.dli_sname, got_value, dl_info.dli_saddr); if (fname && dl_info.dli_sname && appview_strncmp(fname, dl_info.dli_sname, appview_strlen(dl_info.dli_sname))) { - printf("%s:%d len link map %ld dladdr1 %ld\n", __FUNCTION__, __LINE__, - appview_strlen(fname), appview_strlen(dl_info.dli_sname)); + appview_printf("%s:%d len link map %ld dladdr1 %ld\n", __FUNCTION__, __LINE__, + appview_strlen(fname), appview_strlen(dl_info.dli_sname)); } if ((void*)got_value != dl_info.dli_saddr) { - printf("%s:%d\n", __FUNCTION__, __LINE__); + appview_printf("%s:%d\n", __FUNCTION__, __LINE__); } #endif @@ -2130,7 +2205,7 @@ inspectLib(struct dl_phdr_info *info, size_t size, void *data) next: appview_free(file_from_got_value); - appview_free(file_from_link_map); + if (g_isgo) appview_free(file_from_link_map); } dlclose(handle); @@ -4474,19 +4549,21 @@ dlopen(const char *filename, int flags) if (handle) { Elf64_Sym *sym = NULL; - Elf64_Rela *rel = NULL; + Elf64_Rela *rel = NULL, *rela = NULL; char *str = NULL; - int i, rsz = 0; + int i; + size_t rsz = 0, rasz = 0; // Get the link map and ELF sections in advance of something matching if ((dlinfo(handle, RTLD_DI_LINKMAP, (void *)&lm) != -1) && - (getElfEntries(lm, &rel, &sym, &str, &rsz) != -1)) { + (getElfEntries(lm, &sym, &str, &rel, &rsz, &rela, &rasz) != -1)) { appviewLog(CFG_LOG_DEBUG, "\tlibrary: %s", lm->l_name); // for each symbol in the list try to hook for (i=0; inject_hook_list[i].symbol; i++) { if ((dlsym(handle, inject_hook_list[i].symbol)) && - (doGotcha(lm, (got_list_t *)&inject_hook_list[i], rel, sym, str, rsz, TRUE) != -1)) { + (doGotcha(lm, (got_list_t *)&inject_hook_list[i], sym, str, + rel, rsz, rela, rasz, TRUE) != -1)) { appviewLog(CFG_LOG_DEBUG, "\tdlopen interposed %s", inject_hook_list[i].symbol); } } @@ -6436,5 +6513,7 @@ static got_list_t inject_hook_list[] = { {"__register_atfork", __register_atfork, &g_fn.__register_atfork}, {"setrlimit", setrlimit, &g_fn.setrlimit}, {"SSL_ImportFD", SSL_ImportFD, &g_fn.SSL_ImportFD}, + {"SSL_read_ex", ssl_read_ex_hook, &g_fn.SSL_read_ex}, + {"SSL_write_ex", ssl_write_ex_hook, &g_fn.SSL_write_ex}, {NULL, NULL, NULL} }; diff --git a/src/wrap.h b/src/wrap.h index 91d49e9c..8314096e 100644 --- a/src/wrap.h +++ b/src/wrap.h @@ -30,6 +30,8 @@ typedef struct { extern int close$NOCANCEL(int); extern int guarded_close_np(int, void *); +extern int SSL_read_ex(SSL *, void *, size_t, size_t *); +extern int SSL_write_ex(SSL *, const void *, size_t, size_t *); // struct to hold the next 6 numeric (int/ptr etc) variadic arguments // use LOAD_FUNC_ARGS_VALIST to populate this structure diff --git a/test/integration/alpine/Dockerfile b/test/integration/alpine/Dockerfile index 6400977a..3f401653 100644 --- a/test/integration/alpine/Dockerfile +++ b/test/integration/alpine/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.15 +FROM alpine:latest RUN apk add go openssl make file bash curl autoconf automake libtool openssl-dev rust nodejs ruby python3 php php-openssl apache2 apache2-ssl python3-dev py3-pip libffi-dev cargo py3-openssl && \ go clean -cache diff --git a/test/integration/attach/test_attach.sh b/test/integration/attach/test_attach.sh index b6c0a305..0646b55e 100755 --- a/test/integration/attach/test_attach.sh +++ b/test/integration/attach/test_attach.sh @@ -521,7 +521,8 @@ echo "- procname: systemd-networkd" >> $APPVIEW_RULES appview -z ./systemd-networkd & PID=$! sleep 1 -appview inspect --all | grep systemd-networkd +#appview inspect --all | grep systemd-networkd +grep appview /proc/`pidof systemd-networkd`/maps > /dev/null if [ $? -ne "0" ]; then echo "systemd-networkd is not actively viewed but should be" ERR+=1 @@ -557,7 +558,8 @@ if [ $? -eq "0" ]; then # 3) the implicit allow list overrides the filter and allows runc to be viewed ./runc & - appview inspect --all | grep runc + #appview inspect --all | grep runc + grep appview /proc/`pidof runc`/maps > /dev/null if [ $? -ne "0" ]; then echo "runc is not actively viewed but should be" ERR+=1 diff --git a/test/integration/detect_proto/Dockerfile b/test/integration/detect_proto/Dockerfile index 578ab6cf..fa923cc9 100644 --- a/test/integration/detect_proto/Dockerfile +++ b/test/integration/detect_proto/Dockerfile @@ -1,10 +1,10 @@ -FROM quay.io/centos/centos:stream8 +FROM quay.io/centos/centos:stream9 COPY detect_proto/mongodb.repo /etc/yum.repos.d/. RUN yum -y update && \ yum -y install epel-release && \ yum -y install redis wget gdb openssl net-tools -RUN [ "aarch64" = "$(uname -m)" ] || yum -y install mongodb-org +#RUN [ "aarch64" = "$(uname -m)" ] || yum -y install mongodb-org RUN mkdir /opt/test-runner/ RUN mkdir /opt/test-runner/logs/ diff --git a/test/integration/detect_proto/test_protocols.sh b/test/integration/detect_proto/test_protocols.sh index 56c1a1fb..248835d0 100644 --- a/test/integration/detect_proto/test_protocols.sh +++ b/test/integration/detect_proto/test_protocols.sh @@ -79,7 +79,15 @@ else echo "*************** Redis Test Failed ***************" fi -if [ "x86_64" = "$(uname -m)" ]; then # x86_64 only +# mongodb 4.4 can't be downloaded anymore. +# version 5 & above require the use of the AVX instruction set. +# without AVX we get an illegal instruction. example: vmovq -0x80(%rbp),%xmm1 +# given that we can't download a version below 5.0 we need specific hardware. +# therefore, disable mongo until this can be resolved. +# probably need to validate the specific CPU type before attempting to start mongod. + +#if [ "x86_64" = "$(uname -m)" ]; then # x86_64 only +if [ "x86_64_tiger_lake_or_above" = "$(uname -m)" ]; then MONGO_ERR=0 echo diff --git a/test/integration/http/Dockerfile b/test/integration/http/Dockerfile index d1df7e65..9709ab01 100644 --- a/test/integration/http/Dockerfile +++ b/test/integration/http/Dockerfile @@ -18,6 +18,7 @@ COPY http/conf_1 /opt/test/conf_1 COPY http/conf_2 /opt/test/conf_2 ENV PATH="/usr/local/appview:/usr/local/appview/bin:${PATH}" +ENV APPVIEW_CRIBL_ENABLE=true COPY appview-profile.sh /etc/profile.d/appview.sh COPY gdbinit /root/.gdbinit diff --git a/test/integration/http/appview-test b/test/integration/http/appview-test index 82be56bd..22783bbd 100755 --- a/test/integration/http/appview-test +++ b/test/integration/http/appview-test @@ -84,7 +84,7 @@ sleep 30 # Should get HTTP events from HTTP/1.x traffic starttest "HTTP/1.1" rm -rf ${DEST} -appview run -c tcp://localhost:10090 -- curl -Lso /dev/null --http1.1 $H1_URL +appview run -c tcp://127.0.0.1:10090 -- curl -Lso /dev/null --http1.1 $H1_URL if [ "$(wait_for_files "${DEST}/CriblOut-*.json")" ]; then if grep '"source":"http.req"' ${DEST}/CriblOut-*.json >/dev/null; then echo "PASS: http.req found" @@ -107,7 +107,7 @@ endtest # Should still work when ALL payloads are enabled. starttest "HTTP/1.1 + Payloads" rm -rf ${DEST} -appview run -p -c tcp://localhost:10090 -- curl -Lso /dev/null --http1.1 $H1_URL +appview run -p -c tcp://127.0.0.1:10090 -- curl -Lso /dev/null --http1.1 $H1_URL if [ "$(wait_for_files "${DEST}/CriblOut-*.json")" ]; then if grep '"source":"http.req"' ${DEST}/CriblOut-*.json >/dev/null; then echo "PASS: http.req found" @@ -130,7 +130,7 @@ endtest # Should get HTTP events from HTTP/2 traffic starttest "HTTP/2" rm -rf ${DEST} -appview run -c tcp://localhost:10090 -- curl -Lso /dev/null --http2-prior-knowledge $H2_URL +appview run -c tcp://127.0.0.1:10090 -- curl -Lso /dev/null --http2-prior-knowledge $H2_URL if [ "$(wait_for_files "${DEST}/CriblOut-*.json")" ]; then if grep '"source":"http.req"' ${DEST}/CriblOut-*.json >/dev/null; then echo "PASS: http.req found" @@ -153,7 +153,7 @@ endtest # Should still work when ALL payloads are enabled. starttest "HTTP/2 + Payloads" rm -rf ${DEST} -appview run -p -c tcp://localhost:10090 -- curl -Lso /dev/null --http2-prior-knowledge $H2_URL +appview run -p -c tcp://127.0.0.1:10090 -- curl -Lso /dev/null --http2-prior-knowledge $H2_URL if [ "$(wait_for_files "${DEST}/CriblOut-*.json")" ]; then if grep '"source":"http.req"' ${DEST}/CriblOut-*.json >/dev/null; then echo "PASS: http.req found" @@ -229,7 +229,7 @@ endtest # Should get HTTP events from HTTP/1.x traffic via HTTPS starttest "HTTP/1.1 + HTTPS" rm -rf ${DEST} -appview run -c tcp://localhost:10090 -- curl -Lso /dev/null --http1.1 $H1_URL_HTTPS +appview run -c tcp://127.0.0.1:10090 -- curl -Lso /dev/null --http1.1 $H1_URL_HTTPS if [ "$(wait_for_files "${DEST}/CriblOut-*.json")" ]; then if grep '"source":"http.req"' ${DEST}/CriblOut-*.json >/dev/null; then echo "PASS: http.req found" @@ -252,7 +252,7 @@ endtest # Should get HTTP events from HTTP/2 traffic via HTTPS starttest "HTTP/2 + HTTPS" rm -rf ${DEST} -appview run -c tcp://localhost:10090 -- curl -Lso /dev/null --http2-prior-knowledge $H2_URL_HTTPS +appview run -c tcp://127.0.0.1:10090 -- curl -Lso /dev/null --http2-prior-knowledge $H2_URL_HTTPS if [ "$(wait_for_files "${DEST}/CriblOut-*.json")" ]; then if grep '"source":"http.req"' ${DEST}/CriblOut-*.json >/dev/null; then echo "PASS: http.req found" @@ -276,7 +276,8 @@ endtest # AppView should aggregate http events within the default summary period # even when we exit early (before the summary period elapses) starttest "HTTP aggregation" -appview run -m out.txt -- nginx +APPVIEW_CRIBL_ENABLE=false appview run -m out.txt -- nginx +#appview run -m out.txt -- nginx sleep 2 curl 127.0.0.1 >/dev/null 2>&1 curl 127.0.0.1 >/dev/null 2>&1 diff --git a/test/integration/java/test-ssl.sh b/test/integration/java/test-ssl.sh index be0c1ccc..068cffb3 100644 --- a/test/integration/java/test-ssl.sh +++ b/test/integration/java/test-ssl.sh @@ -104,7 +104,7 @@ appview -z /opt/tomcat/bin/catalina.sh run & evaltest CURL_MAX_RETRY=10 -until [[ "`curl $CURL_PARAMS -k --silent --connect-timeout 1 -I https://localhost:8443 | grep 'Coyote'`" != "" ]] || [[ "$CURL_MAX_RETRY" -lt 0 ]]; +until [[ "`curl $CURL_PARAMS -k --silent --connect-timeout 1 -I https://127.0.0.1:8443 | grep 'Coyote'`" != "" ]] || [[ "$CURL_MAX_RETRY" -lt 0 ]]; do echo waiting for tomcat... sleep 1 @@ -123,7 +123,7 @@ ERR+=$? grep http.resp $EVT_FILE > /dev/null ERR+=$? -grep '"net_peer_ip":"127.0.0.1"' $EVT_FILE > /dev/null +grep '"net_peer_ip":"::ffff:127.0.0.1"' $EVT_FILE > /dev/null ERR+=$? grep '"net_peer_port":' $EVT_FILE > /dev/null @@ -145,7 +145,7 @@ ERR+=$? grep http.resp $EVT_FILE > /dev/null ERR+=$? -grep '"net_peer_ip":"127.0.0.1"' $EVT_FILE > /dev/null +grep '"net_peer_ip":"::ffff:127.0.0.1"' $EVT_FILE > /dev/null ERR+=$? grep -E '"net_peer_port":' $EVT_FILE > /dev/null diff --git a/test/integration/logstream/Dockerfile b/test/integration/logstream/Dockerfile index e668da1e..fe4a63b1 100644 --- a/test/integration/logstream/Dockerfile +++ b/test/integration/logstream/Dockerfile @@ -16,7 +16,7 @@ COPY logstream/cribl/ /opt/cribl/local/cribl/ RUN mkdir -p /opt/test-runner/logs/ ENV APPVIEW_CRIBL_ENABLE=false -ENV APPVIEW_METRIC_DEST=udp://localhost:8125 +ENV APPVIEW_METRIC_DEST=udp://127.0.0.1:8125 ENV APPVIEW_LOG_LEVEL=info ENV APPVIEW_LOG_DEST=file:///opt/test-runner/logs/appview.log ENV APPVIEW_METRIC_VERBOSITY=4 diff --git a/test/integration/syscalls/Dockerfile b/test/integration/syscalls/Dockerfile index 9eec2631..d6714b04 100644 --- a/test/integration/syscalls/Dockerfile +++ b/test/integration/syscalls/Dockerfile @@ -23,7 +23,7 @@ RUN cd /opt/test && \ ENV APPVIEW_CRIBL_ENABLE=false ENV APPVIEW_LOG_LEVEL=info -ENV APPVIEW_METRIC_DEST=tcp://localhost:8125 +ENV APPVIEW_METRIC_DEST=tcp://127.0.0.1:8125 ENV APPVIEW_METRIC_VERBOSITY=4 ENV APPVIEW_EVENT_LOGFILE=true ENV APPVIEW_EVENT_CONSOLE=true diff --git a/test/integration/syscalls/Dockerfile.alpine b/test/integration/syscalls/Dockerfile.alpine index 18aa1413..6dca16d2 100644 --- a/test/integration/syscalls/Dockerfile.alpine +++ b/test/integration/syscalls/Dockerfile.alpine @@ -23,7 +23,7 @@ RUN virtualenv -p python3 /opt/test-runner/ ENV APPVIEW_CRIBL_ENABLE=false ENV APPVIEW_LOG_LEVEL=info -ENV APPVIEW_METRIC_DEST=tcp://localhost:8125 +ENV APPVIEW_METRIC_DEST=tcp://127.0.0.1:8125 ENV APPVIEW_METRIC_VERBOSITY=4 ENV APPVIEW_EVENT_LOGFILE=true ENV APPVIEW_EVENT_CONSOLE=true