Rename library_offset to library_fd_offset
replace lseek() and use pread() instead
add test for library_fd_offset > file_size case
Bug: 17762003
(cherry picked from commit a6c1279098
)
Change-Id: Ie117c745081ee33d07db5341115ff6c8e98b0dec
This commit is contained in:
parent
3c5c720b0b
commit
702ab5b37e
4 changed files with 29 additions and 26 deletions
|
@ -54,11 +54,11 @@ enum {
|
|||
*/
|
||||
ANDROID_DLEXT_USE_LIBRARY_FD = 0x10,
|
||||
|
||||
/* When opening library using library_fd read it starting with library_offset
|
||||
/* If opening a library using library_fd read it starting at library_fd_offset.
|
||||
* This flag is only valid when ANDROID_DLEXT_USE_LIBRARY_FD is set.
|
||||
*/
|
||||
|
||||
ANDROID_DLEXT_USE_LIBRARY_OFFSET = 0x20,
|
||||
ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET = 0x20,
|
||||
|
||||
/* Mask of valid bits */
|
||||
ANDROID_DLEXT_VALID_FLAG_BITS = ANDROID_DLEXT_RESERVED_ADDRESS |
|
||||
|
@ -66,7 +66,7 @@ enum {
|
|||
ANDROID_DLEXT_WRITE_RELRO |
|
||||
ANDROID_DLEXT_USE_RELRO |
|
||||
ANDROID_DLEXT_USE_LIBRARY_FD |
|
||||
ANDROID_DLEXT_USE_LIBRARY_OFFSET,
|
||||
ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
@ -75,7 +75,7 @@ typedef struct {
|
|||
size_t reserved_size;
|
||||
int relro_fd;
|
||||
int library_fd;
|
||||
off64_t library_offset;
|
||||
off64_t library_fd_offset;
|
||||
} android_dlextinfo;
|
||||
|
||||
extern void* android_dlopen_ext(const char* filename, int flag, const android_dlextinfo* extinfo);
|
||||
|
|
|
@ -817,8 +817,8 @@ static soinfo* load_library(LoadTaskList& load_tasks, const char* name, int dlfl
|
|||
|
||||
if (extinfo != nullptr && (extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD) != 0) {
|
||||
fd = extinfo->library_fd;
|
||||
if ((extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_OFFSET) != 0) {
|
||||
file_offset = extinfo->library_offset;
|
||||
if ((extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET) != 0) {
|
||||
file_offset = extinfo->library_fd_offset;
|
||||
}
|
||||
} else {
|
||||
// Open the file.
|
||||
|
@ -832,13 +832,13 @@ static soinfo* load_library(LoadTaskList& load_tasks, const char* name, int dlfl
|
|||
}
|
||||
|
||||
if ((file_offset % PAGE_SIZE) != 0) {
|
||||
DL_ERR("file offset for the library %s is not page-aligned: %" PRId64, name, file_offset);
|
||||
DL_ERR("file offset for the library \"%s\" is not page-aligned: %" PRId64, name, file_offset);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct stat file_stat;
|
||||
if (TEMP_FAILURE_RETRY(fstat(fd, &file_stat)) != 0) {
|
||||
DL_ERR("unable to stat file for the library %s: %s", name, strerror(errno));
|
||||
DL_ERR("unable to stat file for the library \"%s\": %s", name, strerror(errno));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -1085,8 +1085,8 @@ soinfo* do_dlopen(const char* name, int flags, const android_dlextinfo* extinfo)
|
|||
return nullptr;
|
||||
}
|
||||
if ((extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD) == 0 &&
|
||||
(extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_OFFSET) != 0) {
|
||||
DL_ERR("invalid extended flag combination (ANDROID_DLEXT_USE_LIBRARY_OFFSET without ANDROID_DLEXT_USE_LIBRARY_FD): 0x%" PRIx64, extinfo->flags);
|
||||
(extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET) != 0) {
|
||||
DL_ERR("invalid extended flag combination (ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET without ANDROID_DLEXT_USE_LIBRARY_FD): 0x%" PRIx64, extinfo->flags);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -142,18 +142,12 @@ bool ElfReader::Load(const android_dlextinfo* extinfo) {
|
|||
}
|
||||
|
||||
bool ElfReader::ReadElfHeader() {
|
||||
off64_t actual_offset = lseek64(fd_, file_offset_, SEEK_SET);
|
||||
|
||||
if (actual_offset != file_offset_) {
|
||||
DL_ERR("seek to %" PRId64 " failed: %s", file_offset_, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
ssize_t rc = TEMP_FAILURE_RETRY(read(fd_, &header_, sizeof(header_)));
|
||||
ssize_t rc = TEMP_FAILURE_RETRY(pread64(fd_, &header_, sizeof(header_), file_offset_));
|
||||
if (rc < 0) {
|
||||
DL_ERR("can't read file \"%s\": %s", name_, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rc != sizeof(header_)) {
|
||||
DL_ERR("\"%s\" is too small to be an ELF executable: only found %zd bytes", name_,
|
||||
static_cast<size_t>(rc));
|
||||
|
|
|
@ -121,9 +121,9 @@ TEST_F(DlExtTest, ExtInfoUseFdWithOffset) {
|
|||
snprintf(lib_path, sizeof(lib_path), LIBZIPPATH, android_data);
|
||||
|
||||
android_dlextinfo extinfo;
|
||||
extinfo.flags = ANDROID_DLEXT_USE_LIBRARY_FD | ANDROID_DLEXT_USE_LIBRARY_OFFSET;
|
||||
extinfo.flags = ANDROID_DLEXT_USE_LIBRARY_FD | ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET;
|
||||
extinfo.library_fd = TEMP_FAILURE_RETRY(open(lib_path, O_RDONLY | O_CLOEXEC));
|
||||
extinfo.library_offset = LIBZIP_OFFSET;
|
||||
extinfo.library_fd_offset = LIBZIP_OFFSET;
|
||||
|
||||
handle_ = android_dlopen_ext(lib_path, RTLD_NOW, &extinfo);
|
||||
ASSERT_DL_NOTNULL(handle_);
|
||||
|
@ -141,23 +141,32 @@ TEST_F(DlExtTest, ExtInfoUseFdWithInvalidOffset) {
|
|||
snprintf(lib_path, sizeof(lib_path), LIBZIPPATH, android_data);
|
||||
|
||||
android_dlextinfo extinfo;
|
||||
extinfo.flags = ANDROID_DLEXT_USE_LIBRARY_FD | ANDROID_DLEXT_USE_LIBRARY_OFFSET;
|
||||
extinfo.flags = ANDROID_DLEXT_USE_LIBRARY_FD | ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET;
|
||||
extinfo.library_fd = TEMP_FAILURE_RETRY(open(lib_path, O_RDONLY | O_CLOEXEC));
|
||||
extinfo.library_offset = 17;
|
||||
extinfo.library_fd_offset = 17;
|
||||
|
||||
handle_ = android_dlopen_ext("libname_placeholder", RTLD_NOW, &extinfo);
|
||||
ASSERT_TRUE(handle_ == nullptr);
|
||||
ASSERT_STREQ("dlopen failed: file offset for the library libname_placeholder is not page-aligned: 17", dlerror());
|
||||
ASSERT_STREQ("dlopen failed: file offset for the library \"libname_placeholder\" is not page-aligned: 17", dlerror());
|
||||
|
||||
extinfo.library_fd_offset = (5LL<<58) + PAGE_SIZE;
|
||||
handle_ = android_dlopen_ext("libname_placeholder", RTLD_NOW, &extinfo);
|
||||
|
||||
ASSERT_TRUE(handle_ == nullptr);
|
||||
// TODO: Better error message when reading with offset > file_size
|
||||
ASSERT_STREQ("dlopen failed: \"libname_placeholder\" has bad ELF magic", dlerror());
|
||||
|
||||
close(extinfo.library_fd);
|
||||
}
|
||||
|
||||
TEST_F(DlExtTest, ExtInfoUseOffsetWihtoutFd) {
|
||||
android_dlextinfo extinfo;
|
||||
extinfo.flags = ANDROID_DLEXT_USE_LIBRARY_OFFSET;
|
||||
extinfo.library_offset = LIBZIP_OFFSET;
|
||||
extinfo.flags = ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET;
|
||||
extinfo.library_fd_offset = LIBZIP_OFFSET;
|
||||
|
||||
handle_ = android_dlopen_ext("/some/lib/that/does_not_exist", RTLD_NOW, &extinfo);
|
||||
ASSERT_TRUE(handle_ == nullptr);
|
||||
ASSERT_STREQ("dlopen failed: invalid extended flag combination (ANDROID_DLEXT_USE_LIBRARY_OFFSET without ANDROID_DLEXT_USE_LIBRARY_FD): 0x20", dlerror());
|
||||
ASSERT_STREQ("dlopen failed: invalid extended flag combination (ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET without ANDROID_DLEXT_USE_LIBRARY_FD): 0x20", dlerror());
|
||||
}
|
||||
|
||||
TEST_F(DlExtTest, Reserved) {
|
||||
|
|
Loading…
Reference in a new issue