aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--install.cpp6
-rw-r--r--otautil/SysUtil.cpp126
-rw-r--r--otautil/SysUtil.h50
-rw-r--r--tests/component/updater_test.cpp4
-rw-r--r--tests/component/verifier_test.cpp2
-rw-r--r--tests/unit/sysutil_test.cpp60
-rw-r--r--tests/unit/zip_test.cpp5
-rw-r--r--updater/updater.cpp3
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
35static bool sysMapFD(int fd, MemMapping* pMap) { 33bool 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].
68static int sysMapBlockFile(const char* filename, MemMapping* pMap) { 65bool 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
173int sysMapFile(const char* fn, MemMapping* pMap) { 167bool 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/* 195MemMapping::~MemMapping() {
203 * Release a memory mapping. 196 for (const auto& range : ranges_) {
204 */
205void 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
24struct 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 */
32struct MemMapping { 28class 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 */
46int 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 */
53void 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
34TEST(SysUtilTest, sysMapFileRegularFile) { 33TEST(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
50TEST(SysUtilTest, sysMapFileBlockMap) { 46TEST(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
98TEST(SysUtilTest, sysMapFileBlockMapInvalidBlockMap) { 91TEST(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
68TEST(ZipTest, OpenFromMemory) { 68TEST(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}