Skip to content

Commit 635a975

Browse files
Łukasz Szymczykkagwind
authored andcommitted
Reserve space on disk using fallocate
There were crashes when android failed to extract zip archives due to out of free space on disk, with stacks like: #00 pc 00000000000156b0 /system/lib64/libc.so (memcpy+176) SlimRoms#1 pc 000000000002e5b8 /system/lib64/libandroidfw.so SlimRoms#2 pc 000000000002f488 /system/lib64/libandroidfw.so (ExtractToMemory+328) SlimRoms#3 pc 000000000002f5c8 /system/lib64/libandroidfw.so (ExtractEntryToFile+268) SlimRoms#4 pc 00000000000287d8 /system/lib64/libandroidfw.so (android::ZipFileRO::\ uncompressEntry(void*, int) const+12) Space for the file is now allocated using fallocate rather than ftruncate, since ftruncate dont actually reserve space on disk. When writes to the mmaped pointer fails to be realized due to out of space SIGBUS is the result. With this change we make sure that there is space available before mmaping the pointer. Change-Id: Ic5e8c33dbe729edb57919dacff73811b34cc2dc2
1 parent a1391ab commit 635a975

File tree

1 file changed

+16
-1
lines changed

1 file changed

+16
-1
lines changed

libziparchive/zip_archive.cc

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1124,7 +1124,22 @@ int32_t ExtractEntryToFile(ZipArchiveHandle handle,
11241124
return kIoError;
11251125
}
11261126

1127-
int result = TEMP_FAILURE_RETRY(ftruncate(fd, declared_length + current_offset));
1127+
int result = 0;
1128+
#if defined(__linux__)
1129+
// Make sure we have enough space on the volume to extract the compressed
1130+
// entry. Note that the call to ftruncate below will change the file size but
1131+
// will not allocate space on disk.
1132+
if (declared_length > 0) {
1133+
result = TEMP_FAILURE_RETRY(fallocate(fd, 0, current_offset, declared_length));
1134+
if (result == -1) {
1135+
ALOGW("Zip: unable to allocate space for file to %" PRId64 ": %s",
1136+
static_cast<int64_t>(declared_length + current_offset), strerror(errno));
1137+
return kIoError;
1138+
}
1139+
}
1140+
#endif // defined(__linux__)
1141+
1142+
result = TEMP_FAILURE_RETRY(ftruncate(fd, declared_length + current_offset));
11281143
if (result == -1) {
11291144
ALOGW("Zip: unable to truncate file to %" PRId64 ": %s",
11301145
(int64_t)(declared_length + current_offset), strerror(errno));

0 commit comments

Comments
 (0)