Skip to content
Snippets Groups Projects
Commit b1911401 authored by Adam Lesinski's avatar Adam Lesinski
Browse files

libziparchive: ensure ReadAtOffset is atomic

ag/880725 modified ReadAtOffset to seek then read from the open
file descriptor. Previously pread64 was used to provide atomic
behaviour.

This causes races when multiple threads are trying to access data from
the file. This is supported, so this change reverts the relevant parts
of the above CL to restore the old behaviour.
Bug:27563413

Change-Id: I7bffd78da8c558745dfc3c072ba9691b1b15bb5b
parent dcdf300a
Branches
Tags
No related merge requests found
...@@ -152,6 +152,9 @@ void CloseArchive(ZipArchiveHandle handle); ...@@ -152,6 +152,9 @@ void CloseArchive(ZipArchiveHandle handle);
* if this file entry contains a data descriptor footer. To verify crc32s * if this file entry contains a data descriptor footer. To verify crc32s
* and length, a call to VerifyCrcAndLengths must be made after entry data * and length, a call to VerifyCrcAndLengths must be made after entry data
* has been processed. * has been processed.
*
* On non-Windows platforms this method does not modify internal state and
* can be called concurrently.
*/ */
int32_t FindEntry(const ZipArchiveHandle handle, const ZipString& entryName, int32_t FindEntry(const ZipArchiveHandle handle, const ZipString& entryName,
ZipEntry* data); ZipEntry* data);
......
...@@ -495,14 +495,20 @@ static int32_t UpdateEntryFromDataDescriptor(int fd, ...@@ -495,14 +495,20 @@ static int32_t UpdateEntryFromDataDescriptor(int fd,
} }
// Attempts to read |len| bytes into |buf| at offset |off|. // Attempts to read |len| bytes into |buf| at offset |off|.
// Callers should not rely on the |fd| offset being incremented // On non-Windows platforms, callers are guaranteed that the |fd|
// as a side effect of this call. // offset is unchanged and there is no side effect to this call.
//
// On Windows platforms this is not thread-safe.
static inline bool ReadAtOffset(int fd, uint8_t* buf, size_t len, off64_t off) { static inline bool ReadAtOffset(int fd, uint8_t* buf, size_t len, off64_t off) {
#if !defined(_WIN32)
return TEMP_FAILURE_RETRY(pread64(fd, buf, len, off));
#else
if (lseek64(fd, off, SEEK_SET) != off) { if (lseek64(fd, off, SEEK_SET) != off) {
ALOGW("Zip: failed seek to offset %" PRId64, off); ALOGW("Zip: failed seek to offset %" PRId64, off);
return false; return false;
} }
return android::base::ReadFully(fd, buf, len); return android::base::ReadFully(fd, buf, len);
#endif
} }
static int32_t FindEntry(const ZipArchive* archive, const int ent, static int32_t FindEntry(const ZipArchive* archive, const int ent,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment