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
This commit is contained in:
Daichi Hirono 2017-06-15 15:48:07 +09:00
parent 7b1d736dac
commit afa3453256
2 changed files with 9 additions and 1 deletions

View file

@ -173,13 +173,20 @@ class FuseBridgeEntry {
}
FuseBridgeState ReadFromDevice(FuseBridgeLoopCallback* callback) {
// To observe APCT failures.
base::ScopedLogSeverity log_severity(base::VERBOSE);
LOG(VERBOSE) << "ReadFromDevice";
if (!buffer_.request.Read(device_fd_)) {
return FuseBridgeState::kClosing;
}
const uint32_t opcode = buffer_.request.header.opcode;
LOG(VERBOSE) << "Read a fuse packet, opcode=" << opcode;
const uint64_t unique = buffer_.request.header.unique;
LOG(VERBOSE) << "Read a fuse packet, opcode=" << opcode << " unique=" << unique;
if (unique == 0) {
return FuseBridgeState::kWaitToReadEither;
}
switch (opcode) {
case FUSE_FORGET:
// Do not reply to FUSE_FORGET.

View file

@ -67,6 +67,7 @@ class FuseBridgeLoopTest : public ::testing::Test {
memset(&request_, 0, sizeof(FuseRequest));
request_.header.opcode = opcode;
request_.header.len = sizeof(fuse_in_header);
request_.header.unique = 1;
ASSERT_TRUE(request_.Write(dev_sockets_[0]));
memset(&response_, 0, sizeof(FuseResponse));