Mercurial > hg > truffle
diff src/share/vm/memory/filemap.cpp @ 20730:8210e5f2e21b
8044269: Analysis of archive files.
Summary: Add checksum verification.
Reviewed-by: iklam, dholmes, mschoene
author | jiangli |
---|---|
date | Tue, 12 Aug 2014 17:46:16 -0400 |
parents | 78bbf4d43a14 |
children | 8cb56c8cb30d |
line wrap: on
line diff
--- a/src/share/vm/memory/filemap.cpp Fri Aug 08 15:15:52 2014 -0700 +++ b/src/share/vm/memory/filemap.cpp Tue Aug 12 17:46:16 2014 -0400 @@ -177,7 +177,14 @@ fail_continue("The shared archive file has the wrong version."); return false; } - _file_offset = (long)n; + size_t len = lseek(fd, 0, SEEK_END); + struct FileMapInfo::FileMapHeader::space_info* si = + &_header._space[MetaspaceShared::mc]; + if (si->_file_offset >= len || len - si->_file_offset < si->_used) { + fail_continue("The shared archive file has been truncated."); + return false; + } + _file_offset = n; return true; } @@ -268,6 +275,7 @@ si->_capacity = capacity; si->_read_only = read_only; si->_allow_exec = allow_exec; + si->_crc = ClassLoader::crc32(0, base, (jint)size); write_bytes_aligned(base, (int)size); } @@ -292,14 +300,15 @@ // Align file position to an allocation unit boundary. void FileMapInfo::align_file_position() { - long new_file_offset = align_size_up(_file_offset, os::vm_allocation_granularity()); + size_t new_file_offset = align_size_up(_file_offset, + os::vm_allocation_granularity()); if (new_file_offset != _file_offset) { _file_offset = new_file_offset; if (_file_open) { // Seek one byte back from the target and write a byte to insure // that the written file is the correct length. _file_offset -= 1; - if (lseek(_fd, _file_offset, SEEK_SET) < 0) { + if (lseek(_fd, (long)_file_offset, SEEK_SET) < 0) { fail_stop("Unable to seek.", NULL); } char zero = 0; @@ -406,6 +415,19 @@ return base; } +bool FileMapInfo::verify_region_checksum(int i) { + if (!VerifySharedSpaces) { + return true; + } + const char* buf = _header._space[i]._base; + size_t sz = _header._space[i]._used; + int crc = ClassLoader::crc32(0, buf, (jint)sz); + if (crc != _header._space[i]._crc) { + fail_continue("Checksum verification failed."); + return false; + } + return true; +} // Unmap a memory region in the address space. @@ -457,8 +479,20 @@ return true; } +int FileMapInfo::compute_header_crc() { + char* header = (char*)&_header; + // start computing from the field after _crc + char* buf = (char*)&_header._crc + sizeof(int); + size_t sz = sizeof(FileMapInfo::FileMapHeader) - (buf - header); + int crc = ClassLoader::crc32(0, buf, (jint)sz); + return crc; +} bool FileMapInfo::validate() { + if (VerifySharedSpaces && compute_header_crc() != _header._crc) { + fail_continue("Header checksum verification failed."); + return false; + } if (_header._version != current_version()) { fail_continue("The shared archive file is the wrong version."); return false;