Skip to content

Commit 1e85e60

Browse files
committed
8297242: Use-after-free during library unloading on Linux
Backport-of: 6f06f440bcf8a5db379b80e8765af38a15449356
1 parent e65f836 commit 1e85e60

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

src/hotspot/os/posix/os_posix.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -698,9 +698,20 @@ void* os::dll_lookup(void* handle, const char* name) {
698698
}
699699

700700
void os::dll_unload(void *lib) {
701-
const char* l_path = LINUX_ONLY(os::Linux::dll_path(lib))
702-
NOT_LINUX("<not available>");
703-
if (l_path == NULL) l_path = "<not available>";
701+
// os::Linux::dll_path returns a pointer to a string that is owned by the dynamic loader. Upon
702+
// calling dlclose the dynamic loader may free the memory containing the string, thus we need to
703+
// copy the string to be able to reference it after dlclose.
704+
const char* l_path = NULL;
705+
#ifdef LINUX
706+
char* l_pathdup = NULL;
707+
l_path = os::Linux::dll_path(lib);
708+
if (l_path != NULL) {
709+
l_path = l_pathdup = os::strdup(l_path);
710+
}
711+
#endif // LINUX
712+
if (l_path == NULL) {
713+
l_path = "<not available>";
714+
}
704715
int res = ::dlclose(lib);
705716

706717
if (res == 0) {
@@ -718,6 +729,7 @@ void os::dll_unload(void *lib) {
718729
log_info(os)("Attempt to unload shared library \"%s\" [" INTPTR_FORMAT "] failed, %s",
719730
l_path, p2i(lib), error_report);
720731
}
732+
LINUX_ONLY(os::free(l_pathdup));
721733
}
722734

723735
jlong os::lseek(int fd, jlong offset, int whence) {

0 commit comments

Comments
 (0)