diff options
-rw-r--r-- | install.cpp | 6 | ||||
-rw-r--r-- | otautil/SysUtil.cpp | 126 | ||||
-rw-r--r-- | otautil/SysUtil.h | 50 | ||||
-rw-r--r-- | tests/component/updater_test.cpp | 4 | ||||
-rw-r--r-- | tests/component/verifier_test.cpp | 2 | ||||
-rw-r--r-- | tests/unit/sysutil_test.cpp | 60 | ||||
-rw-r--r-- | tests/unit/zip_test.cpp | 5 | ||||
-rw-r--r-- | updater/updater.cpp | 3 |
8 files changed, 114 insertions, 142 deletions
diff --git a/install.cpp b/install.cpp index d86f46ca..689f4a0c 100644 --- a/install.cpp +++ b/install.cpp | |||
@@ -569,7 +569,7 @@ static int really_install_package(const std::string& path, bool* wipe_cache, boo | |||
569 | } | 569 | } |
570 | 570 | ||
571 | MemMapping map; | 571 | MemMapping map; |
572 | if (sysMapFile(path.c_str(), &map) != 0) { | 572 | if (!map.MapFile(path)) { |
573 | LOG(ERROR) << "failed to map file"; | 573 | LOG(ERROR) << "failed to map file"; |
574 | return INSTALL_CORRUPT; | 574 | return INSTALL_CORRUPT; |
575 | } | 575 | } |
@@ -577,7 +577,6 @@ static int really_install_package(const std::string& path, bool* wipe_cache, boo | |||
577 | // Verify package. | 577 | // Verify package. |
578 | if (!verify_package(map.addr, map.length)) { | 578 | if (!verify_package(map.addr, map.length)) { |
579 | log_buffer->push_back(android::base::StringPrintf("error: %d", kZipVerificationFailure)); | 579 | log_buffer->push_back(android::base::StringPrintf("error: %d", kZipVerificationFailure)); |
580 | sysReleaseMap(&map); | ||
581 | return INSTALL_CORRUPT; | 580 | return INSTALL_CORRUPT; |
582 | } | 581 | } |
583 | 582 | ||
@@ -588,7 +587,6 @@ static int really_install_package(const std::string& path, bool* wipe_cache, boo | |||
588 | LOG(ERROR) << "Can't open " << path << " : " << ErrorCodeString(err); | 587 | LOG(ERROR) << "Can't open " << path << " : " << ErrorCodeString(err); |
589 | log_buffer->push_back(android::base::StringPrintf("error: %d", kZipOpenFailure)); | 588 | log_buffer->push_back(android::base::StringPrintf("error: %d", kZipOpenFailure)); |
590 | 589 | ||
591 | sysReleaseMap(&map); | ||
592 | CloseArchive(zip); | 590 | CloseArchive(zip); |
593 | return INSTALL_CORRUPT; | 591 | return INSTALL_CORRUPT; |
594 | } | 592 | } |
@@ -596,7 +594,6 @@ static int really_install_package(const std::string& path, bool* wipe_cache, boo | |||
596 | // Additionally verify the compatibility of the package. | 594 | // Additionally verify the compatibility of the package. |
597 | if (!verify_package_compatibility(zip)) { | 595 | if (!verify_package_compatibility(zip)) { |
598 | log_buffer->push_back(android::base::StringPrintf("error: %d", kPackageCompatibilityFailure)); | 596 | log_buffer->push_back(android::base::StringPrintf("error: %d", kPackageCompatibilityFailure)); |
599 | sysReleaseMap(&map); | ||
600 | CloseArchive(zip); | 597 | CloseArchive(zip); |
601 | return INSTALL_CORRUPT; | 598 | return INSTALL_CORRUPT; |
602 | } | 599 | } |
@@ -611,7 +608,6 @@ static int really_install_package(const std::string& path, bool* wipe_cache, boo | |||
611 | ui->SetEnableReboot(true); | 608 | ui->SetEnableReboot(true); |
612 | ui->Print("\n"); | 609 | ui->Print("\n"); |
613 | 610 | ||
614 | sysReleaseMap(&map); | ||
615 | CloseArchive(zip); | 611 | CloseArchive(zip); |
616 | return result; | 612 | return result; |
617 | } | 613 | } |
diff --git a/otautil/SysUtil.cpp b/otautil/SysUtil.cpp index a2133b95..dfa21507 100644 --- a/otautil/SysUtil.cpp +++ b/otautil/SysUtil.cpp | |||
@@ -16,14 +16,12 @@ | |||
16 | 16 | ||
17 | #include "SysUtil.h" | 17 | #include "SysUtil.h" |
18 | 18 | ||
19 | #include <errno.h> | ||
20 | #include <fcntl.h> | 19 | #include <fcntl.h> |
21 | #include <stdint.h> | 20 | #include <stdint.h> // SIZE_MAX |
22 | #include <sys/mman.h> | 21 | #include <sys/mman.h> |
23 | #include <sys/stat.h> | 22 | #include <sys/stat.h> |
24 | #include <sys/types.h> | 23 | #include <sys/types.h> |
25 | 24 | ||
26 | #include <algorithm> | ||
27 | #include <string> | 25 | #include <string> |
28 | #include <vector> | 26 | #include <vector> |
29 | 27 | ||
@@ -32,9 +30,7 @@ | |||
32 | #include <android-base/strings.h> | 30 | #include <android-base/strings.h> |
33 | #include <android-base/unique_fd.h> | 31 | #include <android-base/unique_fd.h> |
34 | 32 | ||
35 | static bool sysMapFD(int fd, MemMapping* pMap) { | 33 | bool MemMapping::MapFD(int fd) { |
36 | CHECK(pMap != nullptr); | ||
37 | |||
38 | struct stat sb; | 34 | struct stat sb; |
39 | if (fstat(fd, &sb) == -1) { | 35 | if (fstat(fd, &sb) == -1) { |
40 | PLOG(ERROR) << "fstat(" << fd << ") failed"; | 36 | PLOG(ERROR) << "fstat(" << fd << ") failed"; |
@@ -47,50 +43,49 @@ static bool sysMapFD(int fd, MemMapping* pMap) { | |||
47 | return false; | 43 | return false; |
48 | } | 44 | } |
49 | 45 | ||
50 | pMap->addr = static_cast<unsigned char*>(memPtr); | 46 | addr = static_cast<unsigned char*>(memPtr); |
51 | pMap->length = sb.st_size; | 47 | length = sb.st_size; |
52 | pMap->ranges.push_back({ memPtr, static_cast<size_t>(sb.st_size) }); | 48 | ranges_.clear(); |
49 | ranges_.emplace_back(MappedRange{ memPtr, static_cast<size_t>(sb.st_size) }); | ||
53 | 50 | ||
54 | return true; | 51 | return true; |
55 | } | 52 | } |
56 | 53 | ||
57 | // A "block map" which looks like this (from uncrypt/uncrypt.cpp): | 54 | // A "block map" which looks like this (from uncrypt/uncrypt.cpp): |
58 | // | 55 | // |
59 | // /dev/block/platform/msm_sdcc.1/by-name/userdata # block device | 56 | // /dev/block/platform/msm_sdcc.1/by-name/userdata # block device |
60 | // 49652 4096 # file size in bytes, block size | 57 | // 49652 4096 # file size in bytes, block size |
61 | // 3 # count of block ranges | 58 | // 3 # count of block ranges |
62 | // 1000 1008 # block range 0 | 59 | // 1000 1008 # block range 0 |
63 | // 2100 2102 # ... block range 1 | 60 | // 2100 2102 # ... block range 1 |
64 | // 30 33 # ... block range 2 | 61 | // 30 33 # ... block range 2 |
65 | // | 62 | // |
66 | // Each block range represents a half-open interval; the line "30 33" | 63 | // Each block range represents a half-open interval; the line "30 33" reprents the blocks |
67 | // reprents the blocks [30, 31, 32]. | 64 | // [30, 31, 32]. |
68 | static int sysMapBlockFile(const char* filename, MemMapping* pMap) { | 65 | bool MemMapping::MapBlockFile(const std::string& filename) { |
69 | CHECK(pMap != nullptr); | ||
70 | |||
71 | std::string content; | 66 | std::string content; |
72 | if (!android::base::ReadFileToString(filename, &content)) { | 67 | if (!android::base::ReadFileToString(filename, &content)) { |
73 | PLOG(ERROR) << "Failed to read " << filename; | 68 | PLOG(ERROR) << "Failed to read " << filename; |
74 | return -1; | 69 | return false; |
75 | } | 70 | } |
76 | 71 | ||
77 | std::vector<std::string> lines = android::base::Split(android::base::Trim(content), "\n"); | 72 | std::vector<std::string> lines = android::base::Split(android::base::Trim(content), "\n"); |
78 | if (lines.size() < 4) { | 73 | if (lines.size() < 4) { |
79 | LOG(ERROR) << "Block map file is too short: " << lines.size(); | 74 | LOG(ERROR) << "Block map file is too short: " << lines.size(); |
80 | return -1; | 75 | return false; |
81 | } | 76 | } |
82 | 77 | ||
83 | size_t size; | 78 | size_t size; |
84 | unsigned int blksize; | 79 | size_t blksize; |
85 | if (sscanf(lines[1].c_str(), "%zu %u", &size, &blksize) != 2) { | 80 | if (sscanf(lines[1].c_str(), "%zu %zu", &size, &blksize) != 2) { |
86 | LOG(ERROR) << "Failed to parse file size and block size: " << lines[1]; | 81 | LOG(ERROR) << "Failed to parse file size and block size: " << lines[1]; |
87 | return -1; | 82 | return false; |
88 | } | 83 | } |
89 | 84 | ||
90 | size_t range_count; | 85 | size_t range_count; |
91 | if (sscanf(lines[2].c_str(), "%zu", &range_count) != 1) { | 86 | if (sscanf(lines[2].c_str(), "%zu", &range_count) != 1) { |
92 | LOG(ERROR) << "Failed to parse block map header: " << lines[2]; | 87 | LOG(ERROR) << "Failed to parse block map header: " << lines[2]; |
93 | return -1; | 88 | return false; |
94 | } | 89 | } |
95 | 90 | ||
96 | size_t blocks; | 91 | size_t blocks; |
@@ -101,14 +96,14 @@ static int sysMapBlockFile(const char* filename, MemMapping* pMap) { | |||
101 | lines.size() != 3 + range_count) { | 96 | lines.size() != 3 + range_count) { |
102 | LOG(ERROR) << "Invalid data in block map file: size " << size << ", blksize " << blksize | 97 | LOG(ERROR) << "Invalid data in block map file: size " << size << ", blksize " << blksize |
103 | << ", range_count " << range_count << ", lines " << lines.size(); | 98 | << ", range_count " << range_count << ", lines " << lines.size(); |
104 | return -1; | 99 | return false; |
105 | } | 100 | } |
106 | 101 | ||
107 | // Reserve enough contiguous address space for the whole file. | 102 | // Reserve enough contiguous address space for the whole file. |
108 | void* reserve = mmap64(nullptr, blocks * blksize, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0); | 103 | void* reserve = mmap64(nullptr, blocks * blksize, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0); |
109 | if (reserve == MAP_FAILED) { | 104 | if (reserve == MAP_FAILED) { |
110 | PLOG(ERROR) << "failed to reserve address space"; | 105 | PLOG(ERROR) << "failed to reserve address space"; |
111 | return -1; | 106 | return false; |
112 | } | 107 | } |
113 | 108 | ||
114 | const std::string& block_dev = lines[0]; | 109 | const std::string& block_dev = lines[0]; |
@@ -116,10 +111,10 @@ static int sysMapBlockFile(const char* filename, MemMapping* pMap) { | |||
116 | if (fd == -1) { | 111 | if (fd == -1) { |
117 | PLOG(ERROR) << "failed to open block device " << block_dev; | 112 | PLOG(ERROR) << "failed to open block device " << block_dev; |
118 | munmap(reserve, blocks * blksize); | 113 | munmap(reserve, blocks * blksize); |
119 | return -1; | 114 | return false; |
120 | } | 115 | } |
121 | 116 | ||
122 | pMap->ranges.resize(range_count); | 117 | ranges_.clear(); |
123 | 118 | ||
124 | unsigned char* next = static_cast<unsigned char*>(reserve); | 119 | unsigned char* next = static_cast<unsigned char*>(reserve); |
125 | size_t remaining_size = blocks * blksize; | 120 | size_t remaining_size = blocks * blksize; |
@@ -129,84 +124,79 @@ static int sysMapBlockFile(const char* filename, MemMapping* pMap) { | |||
129 | 124 | ||
130 | size_t start, end; | 125 | size_t start, end; |
131 | if (sscanf(line.c_str(), "%zu %zu\n", &start, &end) != 2) { | 126 | if (sscanf(line.c_str(), "%zu %zu\n", &start, &end) != 2) { |
132 | LOG(ERROR) << "failed to parse range " << i << " in block map: " << line; | 127 | LOG(ERROR) << "failed to parse range " << i << ": " << line; |
133 | success = false; | 128 | success = false; |
134 | break; | 129 | break; |
135 | } | 130 | } |
136 | size_t length = (end - start) * blksize; | 131 | size_t range_size = (end - start) * blksize; |
137 | if (end <= start || (end - start) > SIZE_MAX / blksize || length > remaining_size) { | 132 | if (end <= start || (end - start) > SIZE_MAX / blksize || range_size > remaining_size) { |
138 | LOG(ERROR) << "unexpected range in block map: " << start << " " << end; | 133 | LOG(ERROR) << "Invalid range: " << start << " " << end; |
139 | success = false; | 134 | success = false; |
140 | break; | 135 | break; |
141 | } | 136 | } |
142 | 137 | ||
143 | void* addr = mmap64(next, length, PROT_READ, MAP_PRIVATE | MAP_FIXED, fd, | 138 | void* range_start = mmap64(next, range_size, PROT_READ, MAP_PRIVATE | MAP_FIXED, fd, |
144 | static_cast<off64_t>(start) * blksize); | 139 | static_cast<off64_t>(start) * blksize); |
145 | if (addr == MAP_FAILED) { | 140 | if (range_start == MAP_FAILED) { |
146 | PLOG(ERROR) << "failed to map block " << i; | 141 | PLOG(ERROR) << "failed to map range " << i << ": " << line; |
147 | success = false; | 142 | success = false; |
148 | break; | 143 | break; |
149 | } | 144 | } |
150 | pMap->ranges[i].addr = addr; | 145 | ranges_.emplace_back(MappedRange{ range_start, range_size }); |
151 | pMap->ranges[i].length = length; | ||
152 | 146 | ||
153 | next += length; | 147 | next += range_size; |
154 | remaining_size -= length; | 148 | remaining_size -= range_size; |
155 | } | 149 | } |
156 | if (success && remaining_size != 0) { | 150 | if (success && remaining_size != 0) { |
157 | LOG(ERROR) << "ranges in block map are invalid: remaining_size = " << remaining_size; | 151 | LOG(ERROR) << "Invalid ranges: remaining_size " << remaining_size; |
158 | success = false; | 152 | success = false; |
159 | } | 153 | } |
160 | if (!success) { | 154 | if (!success) { |
161 | munmap(reserve, blocks * blksize); | 155 | munmap(reserve, blocks * blksize); |
162 | return -1; | 156 | return false; |
163 | } | 157 | } |
164 | 158 | ||
165 | pMap->addr = static_cast<unsigned char*>(reserve); | 159 | addr = static_cast<unsigned char*>(reserve); |
166 | pMap->length = size; | 160 | length = size; |
167 | 161 | ||
168 | LOG(INFO) << "mmapped " << range_count << " ranges"; | 162 | LOG(INFO) << "mmapped " << range_count << " ranges"; |
169 | 163 | ||
170 | return 0; | 164 | return true; |
171 | } | 165 | } |
172 | 166 | ||
173 | int sysMapFile(const char* fn, MemMapping* pMap) { | 167 | bool MemMapping::MapFile(const std::string& fn) { |
174 | if (fn == nullptr || pMap == nullptr) { | 168 | if (fn.empty()) { |
175 | LOG(ERROR) << "Invalid argument(s)"; | 169 | LOG(ERROR) << "Empty filename"; |
176 | return -1; | 170 | return false; |
177 | } | 171 | } |
178 | 172 | ||
179 | *pMap = {}; | ||
180 | |||
181 | if (fn[0] == '@') { | 173 | if (fn[0] == '@') { |
182 | if (sysMapBlockFile(fn + 1, pMap) != 0) { | 174 | // Block map file "@/cache/recovery/block.map". |
175 | if (!MapBlockFile(fn.substr(1))) { | ||
183 | LOG(ERROR) << "Map of '" << fn << "' failed"; | 176 | LOG(ERROR) << "Map of '" << fn << "' failed"; |
184 | return -1; | 177 | return false; |
185 | } | 178 | } |
186 | } else { | 179 | } else { |
187 | // This is a regular file. | 180 | // This is a regular file. |
188 | android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(fn, O_RDONLY))); | 181 | android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(fn.c_str(), O_RDONLY))); |
189 | if (fd == -1) { | 182 | if (fd == -1) { |
190 | PLOG(ERROR) << "Unable to open '" << fn << "'"; | 183 | PLOG(ERROR) << "Unable to open '" << fn << "'"; |
191 | return -1; | 184 | return false; |
192 | } | 185 | } |
193 | 186 | ||
194 | if (!sysMapFD(fd, pMap)) { | 187 | if (!MapFD(fd)) { |
195 | LOG(ERROR) << "Map of '" << fn << "' failed"; | 188 | LOG(ERROR) << "Map of '" << fn << "' failed"; |
196 | return -1; | 189 | return false; |
197 | } | 190 | } |
198 | } | 191 | } |
199 | return 0; | 192 | return true; |
200 | } | 193 | } |
201 | 194 | ||
202 | /* | 195 | MemMapping::~MemMapping() { |
203 | * Release a memory mapping. | 196 | for (const auto& range : ranges_) { |
204 | */ | ||
205 | void sysReleaseMap(MemMapping* pMap) { | ||
206 | std::for_each(pMap->ranges.cbegin(), pMap->ranges.cend(), [](const MappedRange& range) { | ||
207 | if (munmap(range.addr, range.length) == -1) { | 197 | if (munmap(range.addr, range.length) == -1) { |
208 | PLOG(ERROR) << "munmap(" << range.addr << ", " << range.length << ") failed"; | 198 | PLOG(ERROR) << "Failed to munmap(" << range.addr << ", " << range.length << ")"; |
209 | } | 199 | } |
210 | }); | 200 | }; |
211 | pMap->ranges.clear(); | 201 | ranges_.clear(); |
212 | } | 202 | } |
diff --git a/otautil/SysUtil.h b/otautil/SysUtil.h index 6a79bf31..52f6d20a 100644 --- a/otautil/SysUtil.h +++ b/otautil/SysUtil.h | |||
@@ -19,37 +19,35 @@ | |||
19 | 19 | ||
20 | #include <sys/types.h> | 20 | #include <sys/types.h> |
21 | 21 | ||
22 | #include <string> | ||
22 | #include <vector> | 23 | #include <vector> |
23 | 24 | ||
24 | struct MappedRange { | ||
25 | void* addr; | ||
26 | size_t length; | ||
27 | }; | ||
28 | |||
29 | /* | 25 | /* |
30 | * Use this to keep track of mapped segments. | 26 | * Use this to keep track of mapped segments. |
31 | */ | 27 | */ |
32 | struct MemMapping { | 28 | class MemMapping { |
33 | unsigned char* addr; /* start of data */ | 29 | public: |
34 | size_t length; /* length of data */ | 30 | ~MemMapping(); |
35 | 31 | // Map a file into a private, read-only memory segment. If 'filename' begins with an '@' | |
36 | std::vector<MappedRange> ranges; | 32 | // character, it is a map of blocks to be mapped, otherwise it is treated as an ordinary file. |
33 | bool MapFile(const std::string& filename); | ||
34 | size_t ranges() const { | ||
35 | return ranges_.size(); | ||
36 | }; | ||
37 | |||
38 | unsigned char* addr; // start of data | ||
39 | size_t length; // length of data | ||
40 | |||
41 | private: | ||
42 | struct MappedRange { | ||
43 | void* addr; | ||
44 | size_t length; | ||
45 | }; | ||
46 | |||
47 | bool MapBlockFile(const std::string& filename); | ||
48 | bool MapFD(int fd); | ||
49 | |||
50 | std::vector<MappedRange> ranges_; | ||
37 | }; | 51 | }; |
38 | 52 | ||
39 | /* | ||
40 | * Map a file into a private, read-only memory segment. If 'fn' | ||
41 | * begins with an '@' character, it is a map of blocks to be mapped, | ||
42 | * otherwise it is treated as an ordinary file. | ||
43 | * | ||
44 | * On success, "pMap" is filled in, and zero is returned. | ||
45 | */ | ||
46 | int sysMapFile(const char* fn, MemMapping* pMap); | ||
47 | |||
48 | /* | ||
49 | * Release the pages associated with a shared memory segment. | ||
50 | * | ||
51 | * This does not free "pMap"; it just releases the memory. | ||
52 | */ | ||
53 | void sysReleaseMap(MemMapping* pMap); | ||
54 | |||
55 | #endif // _OTAUTIL_SYSUTIL | 53 | #endif // _OTAUTIL_SYSUTIL |
diff --git a/tests/component/updater_test.cpp b/tests/component/updater_test.cpp index dc4b5d72..35e87fd5 100644 --- a/tests/component/updater_test.cpp +++ b/tests/component/updater_test.cpp | |||
@@ -570,7 +570,7 @@ TEST_F(UpdaterTest, block_image_update) { | |||
570 | ASSERT_EQ(0, fclose(zip_file_ptr)); | 570 | ASSERT_EQ(0, fclose(zip_file_ptr)); |
571 | 571 | ||
572 | MemMapping map; | 572 | MemMapping map; |
573 | ASSERT_EQ(0, sysMapFile(zip_file.path, &map)); | 573 | ASSERT_TRUE(map.MapFile(zip_file.path)); |
574 | ZipArchiveHandle handle; | 574 | ZipArchiveHandle handle; |
575 | ASSERT_EQ(0, OpenArchiveFromMemory(map.addr, map.length, zip_file.path, &handle)); | 575 | ASSERT_EQ(0, OpenArchiveFromMemory(map.addr, map.length, zip_file.path, &handle)); |
576 | 576 | ||
@@ -646,7 +646,7 @@ TEST_F(UpdaterTest, new_data_short_write) { | |||
646 | ASSERT_EQ(0, fclose(zip_file_ptr)); | 646 | ASSERT_EQ(0, fclose(zip_file_ptr)); |
647 | 647 | ||
648 | MemMapping map; | 648 | MemMapping map; |
649 | ASSERT_EQ(0, sysMapFile(zip_file.path, &map)); | 649 | ASSERT_TRUE(map.MapFile(zip_file.path)); |
650 | ZipArchiveHandle handle; | 650 | ZipArchiveHandle handle; |
651 | ASSERT_EQ(0, OpenArchiveFromMemory(map.addr, map.length, zip_file.path, &handle)); | 651 | ASSERT_EQ(0, OpenArchiveFromMemory(map.addr, map.length, zip_file.path, &handle)); |
652 | 652 | ||
diff --git a/tests/component/verifier_test.cpp b/tests/component/verifier_test.cpp index 2cfb6d30..5338f05c 100644 --- a/tests/component/verifier_test.cpp +++ b/tests/component/verifier_test.cpp | |||
@@ -38,7 +38,7 @@ class VerifierTest : public testing::TestWithParam<std::vector<std::string>> { | |||
38 | void SetUp() override { | 38 | void SetUp() override { |
39 | std::vector<std::string> args = GetParam(); | 39 | std::vector<std::string> args = GetParam(); |
40 | std::string package = from_testdata_base(args[0]); | 40 | std::string package = from_testdata_base(args[0]); |
41 | if (sysMapFile(package.c_str(), &memmap) != 0) { | 41 | if (!memmap.MapFile(package)) { |
42 | FAIL() << "Failed to mmap " << package << ": " << strerror(errno) << "\n"; | 42 | FAIL() << "Failed to mmap " << package << ": " << strerror(errno) << "\n"; |
43 | } | 43 | } |
44 | 44 | ||
diff --git a/tests/unit/sysutil_test.cpp b/tests/unit/sysutil_test.cpp index f4699664..434ee25b 100644 --- a/tests/unit/sysutil_test.cpp +++ b/tests/unit/sysutil_test.cpp | |||
@@ -27,27 +27,23 @@ TEST(SysUtilTest, InvalidArgs) { | |||
27 | MemMapping mapping; | 27 | MemMapping mapping; |
28 | 28 | ||
29 | // Invalid argument. | 29 | // Invalid argument. |
30 | ASSERT_EQ(-1, sysMapFile(nullptr, &mapping)); | 30 | ASSERT_FALSE(mapping.MapFile("")); |
31 | ASSERT_EQ(-1, sysMapFile("/somefile", nullptr)); | ||
32 | } | 31 | } |
33 | 32 | ||
34 | TEST(SysUtilTest, sysMapFileRegularFile) { | 33 | TEST(SysUtilTest, MapFileRegularFile) { |
35 | TemporaryFile temp_file1; | 34 | TemporaryFile temp_file1; |
36 | std::string content = "abc"; | 35 | std::string content = "abc"; |
37 | ASSERT_TRUE(android::base::WriteStringToFile(content, temp_file1.path)); | 36 | ASSERT_TRUE(android::base::WriteStringToFile(content, temp_file1.path)); |
38 | 37 | ||
39 | // sysMapFile() should map the file to one range. | 38 | // MemMapping::MapFile() should map the file to one range. |
40 | MemMapping mapping; | 39 | MemMapping mapping; |
41 | ASSERT_EQ(0, sysMapFile(temp_file1.path, &mapping)); | 40 | ASSERT_TRUE(mapping.MapFile(temp_file1.path)); |
42 | ASSERT_NE(nullptr, mapping.addr); | 41 | ASSERT_NE(nullptr, mapping.addr); |
43 | ASSERT_EQ(content.size(), mapping.length); | 42 | ASSERT_EQ(content.size(), mapping.length); |
44 | ASSERT_EQ(1U, mapping.ranges.size()); | 43 | ASSERT_EQ(1U, mapping.ranges()); |
45 | |||
46 | sysReleaseMap(&mapping); | ||
47 | ASSERT_EQ(0U, mapping.ranges.size()); | ||
48 | } | 44 | } |
49 | 45 | ||
50 | TEST(SysUtilTest, sysMapFileBlockMap) { | 46 | TEST(SysUtilTest, MapFileBlockMap) { |
51 | // Create a file that has 10 blocks. | 47 | // Create a file that has 10 blocks. |
52 | TemporaryFile package; | 48 | TemporaryFile package; |
53 | std::string content; | 49 | std::string content; |
@@ -63,78 +59,72 @@ TEST(SysUtilTest, sysMapFileBlockMap) { | |||
63 | std::string block_map_content = std::string(package.path) + "\n40960 4096\n1\n0 10\n"; | 59 | std::string block_map_content = std::string(package.path) + "\n40960 4096\n1\n0 10\n"; |
64 | ASSERT_TRUE(android::base::WriteStringToFile(block_map_content, block_map_file.path)); | 60 | ASSERT_TRUE(android::base::WriteStringToFile(block_map_content, block_map_file.path)); |
65 | 61 | ||
66 | ASSERT_EQ(0, sysMapFile(filename.c_str(), &mapping)); | 62 | ASSERT_TRUE(mapping.MapFile(filename)); |
67 | ASSERT_EQ(file_size, mapping.length); | 63 | ASSERT_EQ(file_size, mapping.length); |
68 | ASSERT_EQ(1U, mapping.ranges.size()); | 64 | ASSERT_EQ(1U, mapping.ranges()); |
69 | 65 | ||
70 | // It's okay to not have the trailing '\n'. | 66 | // It's okay to not have the trailing '\n'. |
71 | block_map_content = std::string(package.path) + "\n40960 4096\n1\n0 10"; | 67 | block_map_content = std::string(package.path) + "\n40960 4096\n1\n0 10"; |
72 | ASSERT_TRUE(android::base::WriteStringToFile(block_map_content, block_map_file.path)); | 68 | ASSERT_TRUE(android::base::WriteStringToFile(block_map_content, block_map_file.path)); |
73 | 69 | ||
74 | ASSERT_EQ(0, sysMapFile(filename.c_str(), &mapping)); | 70 | ASSERT_TRUE(mapping.MapFile(filename)); |
75 | ASSERT_EQ(file_size, mapping.length); | 71 | ASSERT_EQ(file_size, mapping.length); |
76 | ASSERT_EQ(1U, mapping.ranges.size()); | 72 | ASSERT_EQ(1U, mapping.ranges()); |
77 | 73 | ||
78 | // Or having multiple trailing '\n's. | 74 | // Or having multiple trailing '\n's. |
79 | block_map_content = std::string(package.path) + "\n40960 4096\n1\n0 10\n\n\n"; | 75 | block_map_content = std::string(package.path) + "\n40960 4096\n1\n0 10\n\n\n"; |
80 | ASSERT_TRUE(android::base::WriteStringToFile(block_map_content, block_map_file.path)); | 76 | ASSERT_TRUE(android::base::WriteStringToFile(block_map_content, block_map_file.path)); |
81 | 77 | ||
82 | ASSERT_EQ(0, sysMapFile(filename.c_str(), &mapping)); | 78 | ASSERT_TRUE(mapping.MapFile(filename)); |
83 | ASSERT_EQ(file_size, mapping.length); | 79 | ASSERT_EQ(file_size, mapping.length); |
84 | ASSERT_EQ(1U, mapping.ranges.size()); | 80 | ASSERT_EQ(1U, mapping.ranges()); |
85 | 81 | ||
86 | // Multiple ranges. | 82 | // Multiple ranges. |
87 | block_map_content = std::string(package.path) + "\n40960 4096\n3\n0 3\n3 5\n5 10\n"; | 83 | block_map_content = std::string(package.path) + "\n40960 4096\n3\n0 3\n3 5\n5 10\n"; |
88 | ASSERT_TRUE(android::base::WriteStringToFile(block_map_content, block_map_file.path)); | 84 | ASSERT_TRUE(android::base::WriteStringToFile(block_map_content, block_map_file.path)); |
89 | 85 | ||
90 | ASSERT_EQ(0, sysMapFile(filename.c_str(), &mapping)); | 86 | ASSERT_TRUE(mapping.MapFile(filename)); |
91 | ASSERT_EQ(file_size, mapping.length); | 87 | ASSERT_EQ(file_size, mapping.length); |
92 | ASSERT_EQ(3U, mapping.ranges.size()); | 88 | ASSERT_EQ(3U, mapping.ranges()); |
93 | |||
94 | sysReleaseMap(&mapping); | ||
95 | ASSERT_EQ(0U, mapping.ranges.size()); | ||
96 | } | 89 | } |
97 | 90 | ||
98 | TEST(SysUtilTest, sysMapFileBlockMapInvalidBlockMap) { | 91 | TEST(SysUtilTest, MapFileBlockMapInvalidBlockMap) { |
99 | MemMapping mapping; | 92 | MemMapping mapping; |
100 | TemporaryFile temp_file; | 93 | TemporaryFile temp_file; |
101 | std::string filename = std::string("@") + temp_file.path; | 94 | std::string filename = std::string("@") + temp_file.path; |
102 | 95 | ||
103 | // Block map file is too short. | 96 | // Block map file is too short. |
104 | ASSERT_TRUE(android::base::WriteStringToFile("/somefile\n", temp_file.path)); | 97 | ASSERT_TRUE(android::base::WriteStringToFile("/somefile\n", temp_file.path)); |
105 | ASSERT_EQ(-1, sysMapFile(filename.c_str(), &mapping)); | 98 | ASSERT_FALSE(mapping.MapFile(filename)); |
106 | 99 | ||
107 | ASSERT_TRUE(android::base::WriteStringToFile("/somefile\n4096 4096\n0\n", temp_file.path)); | 100 | ASSERT_TRUE(android::base::WriteStringToFile("/somefile\n4096 4096\n0\n", temp_file.path)); |
108 | ASSERT_EQ(-1, sysMapFile(filename.c_str(), &mapping)); | 101 | ASSERT_FALSE(mapping.MapFile(filename)); |
109 | 102 | ||
110 | // Block map file has unexpected number of lines. | 103 | // Block map file has unexpected number of lines. |
111 | ASSERT_TRUE(android::base::WriteStringToFile("/somefile\n4096 4096\n1\n", temp_file.path)); | 104 | ASSERT_TRUE(android::base::WriteStringToFile("/somefile\n4096 4096\n1\n", temp_file.path)); |
112 | ASSERT_EQ(-1, sysMapFile(filename.c_str(), &mapping)); | 105 | ASSERT_FALSE(mapping.MapFile(filename)); |
113 | 106 | ||
114 | ASSERT_TRUE(android::base::WriteStringToFile("/somefile\n4096 4096\n2\n0 1\n", temp_file.path)); | 107 | ASSERT_TRUE(android::base::WriteStringToFile("/somefile\n4096 4096\n2\n0 1\n", temp_file.path)); |
115 | ASSERT_EQ(-1, sysMapFile(filename.c_str(), &mapping)); | 108 | ASSERT_FALSE(mapping.MapFile(filename)); |
116 | 109 | ||
117 | // Invalid size/blksize/range_count. | 110 | // Invalid size/blksize/range_count. |
118 | ASSERT_TRUE(android::base::WriteStringToFile("/somefile\nabc 4096\n1\n0 1\n", temp_file.path)); | 111 | ASSERT_TRUE(android::base::WriteStringToFile("/somefile\nabc 4096\n1\n0 1\n", temp_file.path)); |
119 | ASSERT_EQ(-1, sysMapFile(filename.c_str(), &mapping)); | 112 | ASSERT_FALSE(mapping.MapFile(filename)); |
120 | 113 | ||
121 | ASSERT_TRUE(android::base::WriteStringToFile("/somefile\n4096 4096\n\n0 1\n", temp_file.path)); | 114 | ASSERT_TRUE(android::base::WriteStringToFile("/somefile\n4096 4096\n\n0 1\n", temp_file.path)); |
122 | ASSERT_EQ(-1, sysMapFile(filename.c_str(), &mapping)); | 115 | ASSERT_FALSE(mapping.MapFile(filename)); |
123 | 116 | ||
124 | // size/blksize/range_count don't match. | 117 | // size/blksize/range_count don't match. |
125 | ASSERT_TRUE(android::base::WriteStringToFile("/somefile\n0 4096\n1\n0 1\n", temp_file.path)); | 118 | ASSERT_TRUE(android::base::WriteStringToFile("/somefile\n0 4096\n1\n0 1\n", temp_file.path)); |
126 | ASSERT_EQ(-1, sysMapFile(filename.c_str(), &mapping)); | 119 | ASSERT_FALSE(mapping.MapFile(filename)); |
127 | 120 | ||
128 | ASSERT_TRUE(android::base::WriteStringToFile("/somefile\n4096 0\n1\n0 1\n", temp_file.path)); | 121 | ASSERT_TRUE(android::base::WriteStringToFile("/somefile\n4096 0\n1\n0 1\n", temp_file.path)); |
129 | ASSERT_EQ(-1, sysMapFile(filename.c_str(), &mapping)); | 122 | ASSERT_FALSE(mapping.MapFile(filename)); |
130 | 123 | ||
131 | ASSERT_TRUE(android::base::WriteStringToFile("/somefile\n4096 4096\n0\n0 1\n", temp_file.path)); | 124 | ASSERT_TRUE(android::base::WriteStringToFile("/somefile\n4096 4096\n0\n0 1\n", temp_file.path)); |
132 | ASSERT_EQ(-1, sysMapFile(filename.c_str(), &mapping)); | 125 | ASSERT_FALSE(mapping.MapFile(filename)); |
133 | 126 | ||
134 | // Invalid block dev path. | 127 | // Invalid block dev path. |
135 | ASSERT_TRUE(android::base::WriteStringToFile("/doesntexist\n4096 4096\n1\n0 1\n", temp_file.path)); | 128 | ASSERT_TRUE(android::base::WriteStringToFile("/doesntexist\n4096 4096\n1\n0 1\n", temp_file.path)); |
136 | ASSERT_EQ(-1, sysMapFile(filename.c_str(), &mapping)); | 129 | ASSERT_FALSE(mapping.MapFile(filename)); |
137 | |||
138 | sysReleaseMap(&mapping); | ||
139 | ASSERT_EQ(0U, mapping.ranges.size()); | ||
140 | } | 130 | } |
diff --git a/tests/unit/zip_test.cpp b/tests/unit/zip_test.cpp index 4a1a49b9..df4e38ca 100644 --- a/tests/unit/zip_test.cpp +++ b/tests/unit/zip_test.cpp | |||
@@ -66,9 +66,9 @@ TEST(ZipTest, ExtractPackageRecursive) { | |||
66 | } | 66 | } |
67 | 67 | ||
68 | TEST(ZipTest, OpenFromMemory) { | 68 | TEST(ZipTest, OpenFromMemory) { |
69 | MemMapping map; | ||
70 | std::string zip_path = from_testdata_base("ziptest_dummy-update.zip"); | 69 | std::string zip_path = from_testdata_base("ziptest_dummy-update.zip"); |
71 | ASSERT_EQ(0, sysMapFile(zip_path.c_str(), &map)); | 70 | MemMapping map; |
71 | ASSERT_TRUE(map.MapFile(zip_path)); | ||
72 | 72 | ||
73 | // Map an update package into memory and open the archive from there. | 73 | // Map an update package into memory and open the archive from there. |
74 | ZipArchiveHandle handle; | 74 | ZipArchiveHandle handle; |
@@ -85,6 +85,5 @@ TEST(ZipTest, OpenFromMemory) { | |||
85 | ASSERT_EQ(0, ExtractEntryToFile(handle, &binary_entry, tmp_binary.fd)); | 85 | ASSERT_EQ(0, ExtractEntryToFile(handle, &binary_entry, tmp_binary.fd)); |
86 | 86 | ||
87 | CloseArchive(handle); | 87 | CloseArchive(handle); |
88 | sysReleaseMap(&map); | ||
89 | } | 88 | } |
90 | 89 | ||
diff --git a/updater/updater.cpp b/updater/updater.cpp index c09e267a..749c86a1 100644 --- a/updater/updater.cpp +++ b/updater/updater.cpp | |||
@@ -89,7 +89,7 @@ int main(int argc, char** argv) { | |||
89 | 89 | ||
90 | const char* package_filename = argv[3]; | 90 | const char* package_filename = argv[3]; |
91 | MemMapping map; | 91 | MemMapping map; |
92 | if (sysMapFile(package_filename, &map) != 0) { | 92 | if (!map.MapFile(package_filename)) { |
93 | LOG(ERROR) << "failed to map package " << argv[3]; | 93 | LOG(ERROR) << "failed to map package " << argv[3]; |
94 | return 3; | 94 | return 3; |
95 | } | 95 | } |
@@ -213,7 +213,6 @@ int main(int argc, char** argv) { | |||
213 | if (updater_info.package_zip) { | 213 | if (updater_info.package_zip) { |
214 | CloseArchive(updater_info.package_zip); | 214 | CloseArchive(updater_info.package_zip); |
215 | } | 215 | } |
216 | sysReleaseMap(&map); | ||
217 | 216 | ||
218 | return 0; | 217 | return 0; |
219 | } | 218 | } |