OSDN Git Service

Rename library_offset to library_fd_offset
authorDmitriy Ivanov <dimitry@google.com>
Tue, 21 Oct 2014 19:09:18 +0000 (12:09 -0700)
committerDmitriy Ivanov <dimitry@google.com>
Tue, 21 Oct 2014 20:51:08 +0000 (13:51 -0700)
 replace lseek() and use pread() instead
 add test for library_fd_offset > file_size case

Bug: 17762003
Change-Id: I4555f0be635124efe849c1f226985bcba72ffcbd

libc/include/android/dlext.h
linker/linker.cpp
linker/linker_phdr.cpp
tests/dlext_test.cpp

index f81ec70..f27e4e5 100644 (file)
@@ -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);
index cd691af..41557e2 100644 (file)
@@ -787,8 +787,8 @@ static soinfo* load_library(LoadTaskList& load_tasks, const char* name, int rtld
 
   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.
@@ -802,13 +802,13 @@ static soinfo* load_library(LoadTaskList& load_tasks, const char* name, int rtld
   }
 
   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;
   }
 
@@ -1060,8 +1060,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;
     }
   }
index 6856405..61ae5ab 100644 (file)
@@ -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));
index c5443a8..58add6b 100644 (file)
@@ -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) {