aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTianjie Xu <xunchang@google.com>2016-08-31 18:06:33 -0700
committerTianjie Xu <xunchang@google.com>2016-08-31 19:11:41 -0700
commit71e182bc3879a53f04a50de9d25c333163cb7c76 (patch)
tree4f116fad73bb81476238deb9a70313f54cd68246
parent818394869d36b9db1bf4984585a062d4bb91310f (diff)
downloadandroid_bootable_recovery-71e182bc3879a53f04a50de9d25c333163cb7c76.tar.gz
android_bootable_recovery-71e182bc3879a53f04a50de9d25c333163cb7c76.tar.bz2
android_bootable_recovery-71e182bc3879a53f04a50de9d25c333163cb7c76.zip
Check an edge case when read(2) returns 0
We might end up in an infinite loop if read(2) reached EOF unexpectedly. The problematic code in uncrypt mentioned in the bug has been fixed by switching to libbase ReadFully(). So I grepped through the recovery code and fixed some other occurences of the issue. Bug: 31073201 Change-Id: Ib867029158ba23363b8f85d61c25058a635c5a6b
-rw-r--r--applypatch/applypatch.cpp3
-rw-r--r--fuse_sdcard_provider.cpp13
-rw-r--r--updater/blockimg.cpp4
3 files changed, 12 insertions, 8 deletions
diff --git a/applypatch/applypatch.cpp b/applypatch/applypatch.cpp
index 02a3c6e4..e52ef99d 100644
--- a/applypatch/applypatch.cpp
+++ b/applypatch/applypatch.cpp
@@ -336,6 +336,9 @@ int WriteToPartition(const unsigned char* data, size_t len, const char* target)
printf("verify read error %s at %zu: %s\n",
partition, p, strerror(errno));
return -1;
+ } else if (read_count == 0) {
+ printf("verify read reached unexpected EOF, %s at %zu\n", partition, p);
+ return -1;
}
if (static_cast<size_t>(read_count) < to_read) {
printf("short verify read %s at %zu: %zd %zu %s\n",
diff --git a/fuse_sdcard_provider.cpp b/fuse_sdcard_provider.cpp
index df963127..b0ecf96b 100644
--- a/fuse_sdcard_provider.cpp
+++ b/fuse_sdcard_provider.cpp
@@ -23,6 +23,8 @@
#include <unistd.h>
#include <fcntl.h>
+#include <android-base/file.h>
+
#include "fuse_sideload.h"
struct file_data {
@@ -41,14 +43,9 @@ static int read_block_file(void* cookie, uint32_t block, uint8_t* buffer, uint32
return -EIO;
}
- while (fetch_size > 0) {
- ssize_t r = TEMP_FAILURE_RETRY(read(fd->fd, buffer, fetch_size));
- if (r == -1) {
- fprintf(stderr, "read on sdcard failed: %s\n", strerror(errno));
- return -EIO;
- }
- fetch_size -= r;
- buffer += r;
+ if (!android::base::ReadFully(fd->fd, buffer, fetch_size)) {
+ fprintf(stderr, "read on sdcard failed: %s\n", strerror(errno));
+ return -EIO;
}
return 0;
diff --git a/updater/blockimg.cpp b/updater/blockimg.cpp
index f00bc4bf..0caa1acb 100644
--- a/updater/blockimg.cpp
+++ b/updater/blockimg.cpp
@@ -151,6 +151,10 @@ static int read_all(int fd, uint8_t* data, size_t size) {
failure_type = kFreadFailure;
fprintf(stderr, "read failed: %s\n", strerror(errno));
return -1;
+ } else if (r == 0) {
+ failure_type = kFreadFailure;
+ fprintf(stderr, "read reached unexpected EOF.\n");
+ return -1;
}
so_far += r;
}