diff options
author | Daichi Hirono | 2017-06-15 01:48:07 -0500 |
---|---|---|
committer | Daichi Hirono | 2017-06-19 19:25:28 -0500 |
commit | afa345325647e66dc7add78f7100dc81bd066dbb (patch) | |
tree | 0ce95a8d9d3a94cf48b2ff1d231fd76b01a5bc93 | |
parent | 7b1d736dac3eb1b3b75cfd1904a29cc9ec09c75d (diff) | |
download | platform-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.cc | 9 | ||||
-rw-r--r-- | libappfuse/tests/FuseBridgeLoopTest.cc | 1 |
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)); |