mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-15 08:34:30 +02:00
8183262: noexecstack check in os::dll_load on Linux is too expensive
Convert ElfFile::specifies_noexecstack() to static method which read file header and check executable stack flag. Reviewed-by: iklam, stuefe
This commit is contained in:
parent
907093af23
commit
eb20e62194
4 changed files with 39 additions and 24 deletions
|
@ -1639,8 +1639,7 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
|
|||
//
|
||||
// See Linux man page execstack(8) for more info.
|
||||
if (os::uses_stack_guard_pages() && !os::Linux::_stack_is_executable) {
|
||||
ElfFile ef(filename);
|
||||
if (!ef.specifies_noexecstack()) {
|
||||
if (!ElfFile::specifies_noexecstack(filename)) {
|
||||
if (!is_init_completed()) {
|
||||
os::Linux::_stack_is_executable = true;
|
||||
// This is OK - No Java threads have been created yet, and hence no
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "oops/method.hpp"
|
||||
#include "prims/jvm.h"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/timerTrace.hpp"
|
||||
|
||||
GrowableArray<AOTCodeHeap*>* AOTLoader::_heaps = new(ResourceObj::C_HEAP, mtCode) GrowableArray<AOTCodeHeap*> (2, true);
|
||||
GrowableArray<AOTLib*>* AOTLoader::_libraries = new(ResourceObj::C_HEAP, mtCode) GrowableArray<AOTLib*> (2, true);
|
||||
|
@ -112,6 +113,8 @@ static const char* modules[] = {
|
|||
};
|
||||
|
||||
void AOTLoader::initialize() {
|
||||
TraceTime timer("AOT initialization", TRACETIME_LOG(Info, aot, startuptime));
|
||||
|
||||
if (FLAG_IS_DEFAULT(UseAOT) && AOTLibrary != NULL) {
|
||||
// Don't need to set UseAOT on command line when AOTLibrary is specified
|
||||
FLAG_SET_DEFAULT(UseAOT, true);
|
||||
|
|
|
@ -242,32 +242,45 @@ ElfStringTable* ElfFile::get_string_table(int index) {
|
|||
}
|
||||
|
||||
#ifdef LINUX
|
||||
bool ElfFile::specifies_noexecstack() {
|
||||
Elf_Phdr phdr;
|
||||
if (!m_file) return true;
|
||||
bool ElfFile::specifies_noexecstack(const char* filepath) {
|
||||
// Returns true if the elf file is marked NOT to require an executable stack,
|
||||
// or if the file could not be opened.
|
||||
// Returns false if the elf file requires an executable stack, the stack flag
|
||||
// is not set at all, or if the file can not be read.
|
||||
if (filepath == NULL) return true;
|
||||
|
||||
if (!fseek(m_file, m_elfHdr.e_phoff, SEEK_SET)) {
|
||||
for (int index = 0; index < m_elfHdr.e_phnum; index ++) {
|
||||
if (fread((void*)&phdr, sizeof(Elf_Phdr), 1, m_file) != 1) {
|
||||
m_status = NullDecoder::file_invalid;
|
||||
return false;
|
||||
FILE* file = fopen(filepath, "r");
|
||||
if (file == NULL) return true;
|
||||
|
||||
// AARCH64 defaults to noexecstack. All others default to execstack.
|
||||
#ifdef AARCH64
|
||||
bool result = true;
|
||||
#else
|
||||
bool result = false;
|
||||
#endif
|
||||
|
||||
// Read file header
|
||||
Elf_Ehdr head;
|
||||
if (fread(&head, sizeof(Elf_Ehdr), 1, file) == 1 &&
|
||||
is_elf_file(head) &&
|
||||
fseek(file, head.e_phoff, SEEK_SET) == 0) {
|
||||
|
||||
// Read program header table
|
||||
Elf_Phdr phdr;
|
||||
for (int index = 0; index < head.e_phnum; index ++) {
|
||||
if (fread((void*)&phdr, sizeof(Elf_Phdr), 1, file) != 1) {
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
if (phdr.p_type == PT_GNU_STACK) {
|
||||
if (phdr.p_flags == (PF_R | PF_W)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
result = (phdr.p_flags == (PF_R | PF_W));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// AARCH64 defaults to noexecstack. All others default to execstack.
|
||||
#ifdef AARCH64
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
fclose(file);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
#endif // LINUX
|
||||
|
||||
#endif // !_WINDOWS && !__APPLE__
|
||||
|
|
|
@ -108,7 +108,7 @@ class ElfFile: public CHeapObj<mtInternal> {
|
|||
|
||||
private:
|
||||
// sanity check, if the file is a real elf file
|
||||
bool is_elf_file(Elf_Ehdr&);
|
||||
static bool is_elf_file(Elf_Ehdr&);
|
||||
|
||||
// load string tables from the elf file
|
||||
bool load_tables();
|
||||
|
@ -132,7 +132,7 @@ protected:
|
|||
// Returns false if the elf file requires an executable stack, the stack flag
|
||||
// is not set at all, or if the file can not be read.
|
||||
// On systems other than linux it always returns false.
|
||||
bool specifies_noexecstack() NOT_LINUX({ return false; });
|
||||
static bool specifies_noexecstack(const char* filepath) NOT_LINUX({ return false; });
|
||||
|
||||
protected:
|
||||
ElfFile* m_next;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue