Commit graph

13 commits

Author SHA1 Message Date
hyeeun.jun@samsung.com
49545ab897 Fix Deadlock Issue On AppFuseBridge
There are two locks used by AppFuseBridge.
First is it's object lock, and the second is a mutex lock in app fuse library.
There are two oppsite routines to get those locks.

  (Thread A) Got Java lock -> Try to get Native lock
  (Thread B)        Got Native lock -> Try to get Java lock

Bug : https://issuetracker.google.com/issues/145707568
Signed-off-by: hyeeun.jun@samsung.com <hyeeun.jun@samsung.com>

The order must be followed to obtain two locks.
If not, the dead lock will be caused.
Therefore we change the routine to get the mutex lock first, and the object lock later.
2020-02-18 04:33:06 +00:00
Anton Hansson
b6d9fbddc6 Merge "Close /dev/fuse FD before calling onClosed" into qt-dev 2019-05-31 15:59:39 +00:00
Anton Hansson
c9e873f274 Close /dev/fuse FD before calling onClosed
This works around a deadlock when a bridge that is about to be closed
is reused for a new call to openFile. The call to open() ends up holding
the vold lock, waiting for appfuse to respond. The appfuse event loop
calls onClosed(), which ends up calling vold.unmountAppFuse(), which
cannot get the lock.

Closing this file descriptor causes any current calls to open() on its
mount path to fail with either ECONNABORTED or ENOTCONN, allowing the
event loop to make progress, call onClosed() and unmount the path.

Note that the failed call to open() will result in a retry, which
will create a new appfuse bridge. This is not ideal but not a new
problem -- the common case here is that that each call to
openProxyFileDescriptor creates a new bridge. This should ideally
be improved.

Bug: 132344997
Test: flick through info of photos with location info attached
Exempt-From-Owner-Approval: verbal approval of approach
Change-Id: I878e5cf86f18c5233f8505f52eb9db076bd72d01
2019-05-31 15:58:45 +00:00
Daichi Hirono
ca0d4ffbe3 Fix BridgeEpollController to handles EAGAIN correctly
When reading/writing proxy FD, if it returns EAGAIN,
BridgeEpollController updates epoll entries to observe specific FD
events. Before updating epoll entries, BridgeEpollController checks if
it really needs to update by comparing |state_| and |last_state_|.
|last_state_| has not been updated correctly so it resulted in wrong
epoll settings and keeps blocking the event loop.

Bug: 134104939
Test: atest libappfuse_test
Change-Id: I1c4a0164c1c016baf24ecfd523476ced981d3b28
2019-05-31 12:51:05 +09:00
Nick Kralevich
f47c91053f use epoll_create1(EPOLL_CLOEXEC)
epoll_create(0) leaks file descriptors. Use epoll_create1(EPOLL_CLOEXEC)
instead.

Bug: 120983106
Test: compiles and boots
Change-Id: I2a733d4482d6a74ceb3254e501cdb5f6de0cd5dc
2018-12-17 09:32:23 -08:00
Daichi Hirono
926acb637f Remove ScopedLogSeverity for debugging
The ScopedLogSeverity was added to observe APCT failures, which turned
out to be a compiler optimization error.

Bug: 62429763
Test: None
Change-Id: Ibb45d018d8eaf4b29cb417da80ae5f0b000dda8e
2017-07-14 16:44:16 +09:00
Daichi Hirono
afa3453256 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
2017-06-20 00:25:28 +00:00
Daichi Hirono
e5a1556d40 Add more logs for writing failures.
Bug: 62429763
Test: libappfuse_test
Change-Id: Ie0eabd09ae9ad3f8ba8c4f38f871dad16b5c58ff
2017-06-12 10:37:08 +09:00
Daichi Hirono
96c6aa4f20 Enable FuseBridgeLoop to accept new mount point after starting
The CL turns StartFuseBridgeLoop function into FuseBridgeLoop class, and
adds a method adding new appfuse mount to the loop.

After doing this, one FuseBridgeLoop can process FUSE commands from
multiple AppFuse mounts.

Bug: 34903085
Test: libappfuse_test
Change-Id: I54f11f54bc26c551281b9c32e9bb91f8f043774c
2017-03-23 16:22:03 +09:00
Daichi Hirono
691739b334 Remove FuseBridgeLoop class.
Bug: 32779923
Test: libappfuse_test
Change-Id: I29a76701d141ae061ec1fe32993d27460a0c694a
2016-11-17 09:49:51 +09:00
Daichi Hirono
30e6808895 Stops the loop when all files are closed.
The CL changes FuseBridgeLoop so that it exits when all files opened on
the AppFuse mount point are closed. Note that the client code will
unmount the FUSE mount point after the loop exits.

Bug: 32260320
Test: libappfuse_test
Change-Id: I4965fbb48de8a280c6306e70757a07376b1956a7
2016-11-17 09:10:53 +09:00
Daichi Hirono
a0aecda12b Add FuseAppLoop to libappfuse.
The class is used at the app side (StorageManager) to parse FUSE
commands.

Bug: 32260320
Test: libappfuse_test
Change-Id: I1ae2904d3290a041f1efbf8fc10ba032eda5449c
2016-11-15 09:47:31 +09:00
Daichi Hirono
c613476297 Add FuseBridgeLoop to libappfuse.
The CL adds FuseBridgeLoop class to libappfuse, which is used in the
system service to proxy fuse commands to applications.

Bug: 29970149
Test: libappfuse_test
Change-Id: I0708f608b3868721ab16ba4028fd2c17a6735af7
2016-10-27 15:04:15 +09:00