summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaichi Hirono2017-06-15 01:48:07 -0500
committerDaichi Hirono2017-06-19 19:25:28 -0500
commitafa345325647e66dc7add78f7100dc81bd066dbb (patch)
tree0ce95a8d9d3a94cf48b2ff1d231fd76b01a5bc93
parent7b1d736dac3eb1b3b75cfd1904a29cc9ec09c75d (diff)
downloadplatform-system-core-afa345325647e66dc7add78f7100dc81bd066dbb.tar.gz
platform-system-core-afa345325647e66dc7add78f7100dc81bd066dbb.tar.xz
platform-system-core-afa345325647e66dc7add78f7100dc81bd066dbb.zip
Skip FUSE request from /dev/fuse if unique=0
APCT log shows that we got FUSE request unique=0 and replying to such request causes a EINVAL. The possible reasons of getting unique=0 here are: * /dev/fuse actually submits such requests. In this case, not replying to such request probabbly safe as the kernel cannot wait corresponding response without a unique number. We can observing the kernel code to find out what unique=0 actually means. * Memory corruption happens and unique number are cleared with zero. In this case, if we skip unique=0 request, libappfuse does not reply to the kernel request and APCT result will become timeout . To see which case happens, the CL ScopedLogSeverity to output verbose logs and lets FuseBridgeLoop skip a request from /dev/fuse if unique=0. Bug: 62429763 Test: libappfuse_tests Change-Id: I8c4d532564b690d55573b92260170b0cd68150ab
-rw-r--r--libappfuse/FuseBridgeLoop.cc9
-rw-r--r--libappfuse/tests/FuseBridgeLoopTest.cc1
2 files changed, 9 insertions, 1 deletions
diff --git a/libappfuse/FuseBridgeLoop.cc b/libappfuse/FuseBridgeLoop.cc
index 07923071b..5a897a472 100644
--- a/libappfuse/FuseBridgeLoop.cc
+++ b/libappfuse/FuseBridgeLoop.cc
@@ -173,13 +173,20 @@ class FuseBridgeEntry {
173 } 173 }
174 174
175 FuseBridgeState ReadFromDevice(FuseBridgeLoopCallback* callback) { 175 FuseBridgeState ReadFromDevice(FuseBridgeLoopCallback* callback) {
176 // To observe APCT failures.
177 base::ScopedLogSeverity log_severity(base::VERBOSE);
178
176 LOG(VERBOSE) << "ReadFromDevice"; 179 LOG(VERBOSE) << "ReadFromDevice";
177 if (!buffer_.request.Read(device_fd_)) { 180 if (!buffer_.request.Read(device_fd_)) {
178 return FuseBridgeState::kClosing; 181 return FuseBridgeState::kClosing;
179 } 182 }
180 183
181 const uint32_t opcode = buffer_.request.header.opcode; 184 const uint32_t opcode = buffer_.request.header.opcode;
182 LOG(VERBOSE) << "Read a fuse packet, opcode=" << opcode; 185 const uint64_t unique = buffer_.request.header.unique;
186 LOG(VERBOSE) << "Read a fuse packet, opcode=" << opcode << " unique=" << unique;
187 if (unique == 0) {
188 return FuseBridgeState::kWaitToReadEither;
189 }
183 switch (opcode) { 190 switch (opcode) {
184 case FUSE_FORGET: 191 case FUSE_FORGET:
185 // Do not reply to FUSE_FORGET. 192 // Do not reply to FUSE_FORGET.
diff --git a/libappfuse/tests/FuseBridgeLoopTest.cc b/libappfuse/tests/FuseBridgeLoopTest.cc
index 51d605136..0a28451bf 100644
--- a/libappfuse/tests/FuseBridgeLoopTest.cc
+++ b/libappfuse/tests/FuseBridgeLoopTest.cc
@@ -67,6 +67,7 @@ class FuseBridgeLoopTest : public ::testing::Test {
67 memset(&request_, 0, sizeof(FuseRequest)); 67 memset(&request_, 0, sizeof(FuseRequest));
68 request_.header.opcode = opcode; 68 request_.header.opcode = opcode;
69 request_.header.len = sizeof(fuse_in_header); 69 request_.header.len = sizeof(fuse_in_header);
70 request_.header.unique = 1;
70 ASSERT_TRUE(request_.Write(dev_sockets_[0])); 71 ASSERT_TRUE(request_.Write(dev_sockets_[0]));
71 72
72 memset(&response_, 0, sizeof(FuseResponse)); 73 memset(&response_, 0, sizeof(FuseResponse));