sdcard.c is a *really* big file. This makes it hard to do things like
improving priv dropping or adding more sandboxing. Extract all
FUSE-related code to a separate unit, fuse.{h|c}, which exports only
two functions. Convert the rest of sdcard.c to C++ as sdcard.cpp.
fuse.c is kept as C (at least for now) since interacting with the FUSE
API is realistically easier from C.
Bug: 30110940
Change-Id: I188bfdc21c184742117e07539adb09090d4d747c
The previous false positive fix (df9c4a01) is enough to pass tests, and
it doesn't appear that there are any remaining issues.
Change-Id: Ib9812f1201ff0cd2ae8c8371737754fc328765b5
This allows inotify requests on FUSE to be alerted when any
other stacked filesystem would trigger an inotify for the
same file.
Bug: 23904372
Change-Id: I4289b38230c314432eaf2c0d20d4ccefc058f59e
An incorrect size was causing an unsigned value
to wrap, causing it to write past the end of
the buffer.
Bug: 28085658
Change-Id: Ie9625c729cca024d514ba2880ff97209d435a165
am: 20ca983
* commit '20ca9836b9a780c41a22850f478a29f29677553e':
Give users and devices control over sdcardfs.
Change-Id: I0144b346157952f79fdde5100f0fdc01daa58d9b
Instead of relying only on kernel support for sdcardfs, give each
device the ability to quickly toggle between sdcardfs and FUSE. Also
add the ability to users to explicitly enable/disable the behavior
for testing and debugging purposes.
Bug: 27991427
Change-Id: Ie188cb044be2ad87166f2d43c32a1f6b97660de0
Add ability to use sdcardfs if kernel support is found.
In the future, we will likely remove the fuse components
entirely, but for now, just use sdcardfs when possible.
Bug: 19160983
Change-Id: I35e4d6cb5976c00c6f87ff7fc478ba9f9d212c05
Signed-off-by: Daniel Rosenberg <drosen@google.com>
Use a non yet maintainer reviewed kernel patch from QCOM that greatly
improves IO speed in case it is available from the device specific
kernel headers.
Bug: 24216004
Change-Id: I4101d80082c9ad9d042dde5c620ddb309d193d52
When packages change, existing package-specific directories may have
gained/lost a UID mapping, so we need to update the permissions for
any in-memory nodes.
This allows an app to deliver data for another package before that
package is installed, which is the typical pattern of how OBB files
are delivered.
Also fix bug by re-deriving permissions when files are moved.
Bug: 25399427
Change-Id: I06f38a24ad7dee5f5099ba81429aef03208e5683
When packages change, existing package-specific directories may have
gained/lost a UID mapping, so we need to update the permissions for
any in-memory nodes.
This allows an app to deliver data for another package before that
package is installed, which is the typical pattern of how OBB files
are delivered.
Also fix bug by re-deriving permissions when files are moved.
Bug: 25399427
Change-Id: I06f38a24ad7dee5f5099ba81429aef03208e5683
When packages change, existing package-specific directories may have
gained/lost a UID mapping, so we need to update the permissions for
any in-memory nodes.
This allows an app to deliver data for another package before that
package is installed, which is the typical pattern of how OBB files
are delivered.
Also fix bug by re-deriving permissions when files are moved.
Bug: 25399427
Change-Id: I06f38a24ad7dee5f5099ba81429aef03208e5683
Switch from the internal packages.list file parser
implementation to a common parser library.
See Change-Id: I87a406802f95d8e7bfd8ee85f723f80e9e6b6c0c
for all of the details.
Change-Id: I98924dce406b322e0d402bca7fdac51f6a1e6a4b
Signed-off-by: William Roberts <william.c.roberts@intel.com>
We have a bunch of magic that mounts the correct view of storage
access based on the runtime permissions of an app, but we forgot to
protect the real underlying data sources; oops.
This series of changes just bumps the directory heirarchy one level
to give us /mnt/runtime which we can mask off as 0700 to prevent
people from jumping to the exposed internals.
Also add CTS tests to verify that we're protecting access to
internal mount points like this.
Bug: 22964288
Change-Id: I32068e63a3362b37e8ebca1418f900bb8537b498
Long ago, we mounted secondary physical cards as readable by all
users on the device, which enabled the use-case of loading media on
a card and viewing it from all users.
More recently, we started giving write access to these secondary
physical cards, but this created a one-directional channel for
communication across user boundaries; something that CDD disallows.
This change is designed to give us the best of both worlds: the
package-specific directories are writable for the user that mounted
the card, but access to those "Android" directories are blocked for
all other users. Other users remain able to read content elsewhere
on the card.
Bug: 22787184
Change-Id: I4a04a1a857a65becf5fd37d775d927af022b40ca
Instead of having each view build and maintain its own tree
representing the underlying storage, switch to building a single tree
that each view augments with GID/mode specific behavior.
This has the nice property of a single file always having the same
node ID when presented across multiple views, giving us a firm handle
that we can use to invalidate kernel caches.
Specifically, when a file is deleted through one view, we now tell
the kernel to invalidate that file in the other two views.
Bug: 22477678, 22375891
Change-Id: I3ff041d549d41040839cde9773504719a508219f
Typical apps are restricted so they can only view shared storage
belonging to the user they're running as. However, a handful of
system components need access to shared storage across all users,
such as DefaultContainerService and SystemUI.
Since WRITE_MEDIA_STORAGE already offers this functionality by
bypassing any FUSE emulation, reuse it to grant the "sdcard_rw" GID
which is no longer handed out to third-party apps. Then we change
the FUSE daemon to allow the "sdcard_rw" GID to see shared storage
of all users.
Bug: 19995822
Change-Id: Id2fe846aefbf13fc050e9b00ddef120021e817f4
When someone force-unmounts our target endpoint, gracefully handle by
terminating, instead of looping on the same errno forever.
Bug: 22197797
Change-Id: I7e71632f69d47152ea78a94431c23ae69aba9b93
Now that we're treating storage as a runtime permission, we need to
grant read/write access without killing the app. This is really
tricky, since we had been using GIDs for access control, and they're
set in stone once Zygote drops privileges.
The only thing left that can change dynamically is the filesystem
itself, so let's do that. This means changing the FUSE daemon to
present itself as three different views:
/mnt/runtime_default/foo - view for apps with no access
/mnt/runtime_read/foo - view for apps with read access
/mnt/runtime_write/foo - view for apps with write access
There is still a single location for all the backing files, and
filesystem permissions are derived the same way for each view, but
the file modes are masked off differently for each mountpoint.
During Zygote fork, it wires up the appropriate storage access into
an isolated mount namespace based on the current app permissions. When
the app is granted permissions dynamically at runtime, the system
asks vold to jump into the existing mount namespace and bind mount
the newly granted access model into place.
Bug: 21858077
Change-Id: I5a016f0958a92fd390c02b5ae159f8008bd4f4b7
The umount2 call was using the magic constant 2 which is
has a defined and proper macro in mount.h as MNT_DETATCH.
Change-Id: I4ca4a6d31cbf5495c545088e3d90a8894a9f912f
To support external storage devices that are dynamically added and
removed at runtime, we're changing /mnt and /storage to be tmpfs that
are managed by vold.
To support primary storage being inserted/ejected at runtime in a
multi-user environment, we can no longer bind-mount each user into
place. Instead, we have a new /storage/self/primary symlink which
is resolved through /mnt/user/n/primary, and which vold updates at
runtime.
Fix small mode bugs in FUSE daemon so it can be safely mounted
visible to all users on device.
Bug: 19993667
Change-Id: I0ebf4d10aba03d73d9a6fa37d4d43766be8a173b
This will eventually allow us to have a single unified filesystem
instead of requiring zygote to use bind mounts.
Change-Id: I1fc4ada4874698a00e7e0b8800617732e69348f0
The sdcard fuse deamon is not properly handling deleted nodes that are
still in use (opened by some process). Typically Linux filesystems makes
it possible to open a file, unlink it and then still use it. In case of a
storage emulated by sdcard deamon this does not work as expected - other
process are not able to recreate file/dir with the same name until all
references to deleted file are closed.
The easiest way to trigger this problem is:
process1: mkdir /sdcard/test1; cd /sdcard/test1
process2: rm -r /sdcard/test1
process2: mkdir /sdcard/test1
After that, process2 will get an error:
mkdir failed for /sdcard/test1, Device or resource busy
There is exactly the same problem with files as directories.
This may case issues for example with directories that are
automatically recreated when they are missing (like DCIM directory). If
some process holds file opened inside of such directory but that
directory is removed, process trying to recreate the directory will get
EBUSY error and possibly crash.
Verified on the Z Ultra GPE.
Change-Id: I1cbf0bec135e6aaafba0ce8e5bb594e3639e0007
This works around a bug on on 64 bit kernels + sdcard daemons
where we were using memory addresses as inode numbers.
bug: 19012244
(cherry picked from commit faa0935ffb)
Change-Id: Idbf9e285e507e702e04e7461a10153df68ef2322
Vold mounts the sdcard with noexec, but the fuse deamon
mounts with exec, so it is still possible to execute
binaries:
/dev/fuse /storage/sdcard1 fuse rw,nosuid,nodev,relatime,
user_id=1023,group_id=1023,default_permissions,allow_other 0 0
/dev/block/vold/179:65 /mnt/media_rw/sdcard1 vfat rw,dirsync,
nosuid,nodev,noexec,relatime,uid=1023,gid=1023,fmask=0007,
dmask=0007,allow_utime=0020,codepage=cp437,iocharset=iso8859-1,
shortname=mixed,utf8,errors=remount-ro 0 0
With this change both vold and fuse mounts with noexec.
Change-Id: I66cbfc3a3a89a26958f83577f5e7a5e27f99184e
Add initialization of the output value in handle_write.
This value is referred to in FUSE so initialization is
necessary.
See also handle_open and handle_opendir.
Change-Id: I6507f113da9f6823fbfa459624d6594fc20afa51
Right now we still have the kernel names, but they're only there by
"virtue" of macro namespace pollution, so I'd like to get rid of them.
Bug: 18298106
Change-Id: Ifed0b3a9238c79a99d8a2b62e0f5897c50a725d1
Kernel 2.6.16 is the first stable kernel with struct fuse_init_out
defined (fuse version 7.6). The structure is the same from 7.6 through
7.22. Beginning with 7.23, the structure increased in size and added
new parameters.
If the kernel only works on minor revs older than or equal to 22,
then use the older structure size since this code only uses the 7.22
version of the structure.
Change-Id: If2507a02ad674fcf02869a325221339ae1ace64d
Use truncate64 instead of truncate so we don't truncate (ho ho) the offset.
(cherrypick of 4568565e85bf2e1ea11b2e09d72e244088c05dbc.)
Bug: https://code.google.com/p/android/issues/detail?id=74039
Change-Id: I63711ccd299e3ebc475563b1999817d1919571ab
Before running the sdcard daemon, make sure that installd has
completed all upgrades to /data that it needs to complete.
This avoids race conditions between installd and the sdcard daemon.
Maybe fixes bug 16329437.
Bug: 16329437
Change-Id: I5e164f08009c1036469f8734ec07cbae9c5e262b
When built with "#define FUSE_TRACE 1" numerous TRACE statements
failed to compile because of mismatches between format strings and
types (uint64_t and size_t). These have been corrected by using the
format strings from the inttype.h header file, or %zu.
Signed-off-by: Marcus Oakland <marcus.oakland@arm.com>
(cherry picked from commit d33308752f)
Change-Id: I550b422a6b7c92ea903b4dd8f5e4aec5637cdf67
Before running the sdcard daemon, make sure that installd has
completed all upgrades to /data that it needs to complete.
This avoids race conditions between installd and the sdcard daemon.
Maybe fixes bug 16329437.
(cherrypicked from commit 8d28fa71fc)
Bug: 16329437
Change-Id: I5e164f08009c1036469f8734ec07cbae9c5e262b
When built with "#define FUSE_TRACE 1" numerous TRACE statements
failed to compile because of mismatches between format strings and
types (uint64_t and size_t). These have been corrected by using the
format strings from the inttype.h header file, or %zu.
Change-Id: I36cd6f8da0790f1218d7dbaaa5b3bbfa4df7fdee
Signed-off-by: Marcus Oakland <marcus.oakland@arm.com>
For a file the FUSE fh is a struct handle containing an int fd;
for a directory it's a struct dirhandle containing a DIR*. Fix
handle_fsync to extract the file descriptor appropriately in
both cases.
Bug: 14613980
Change-Id: I45515cff6638e27a99b849e6fc639d355dbb4d27
This change defines per-app directories on external storage that
will be scanned and included in MediaStore. This gives apps a way
to write content to secondary shared storage in a way that can
easily be surfaced to other apps.
Bug: 14382377
Change-Id: I6f03d8076a9391d8b9eb8421ec3fc93669b3ba0d
There have been issues with sdcard data corruption even after
successfully calling fsync for /sdcard. This is caused by
the sdcard daemon doing nothing in this case.
Change-Id: I48149ceabdac79ac535b35c2598bb1fbb5410883
It is not enough to align the read buffer only, because
consequent writes might still fail with EINVAL. The write
buffer should be also aligned according to the write(2)
manual page.
Change-Id: I7547dec5208732c56f4466c1b0c88f36dabacf5b
If a file is opened in direct I/O mode (with O_DIRECT flag),
the read buffer addess must be aligned to memory page size
boundary. The Direct I/O is not needed for normal files,
however, some special hardware access (e.g. smart SD cards)
will not work without it.
Change-Id: I42babeee86dba1880fd23e2592fddd7060da3e20
Add sdcard FUSE daemon flag to specify the GID required for a package
to have write access. Normally sdcard_rw, but it will be media_rw
for secondary external storage devices, so DefaultContainerService
can still clean up package directories after uninstall.
Create /mnt/media_rw which is where vold will mount raw secondary
external storage devices before wrapping them in a FUSE instance.
Bug: 10330128, 10330229
Change-Id: I4385c36fd9035cdf56892aaf7b36ef4b81f4418a
Before this change, FUSE lookup() would have the side effect of
creating the directory on behalf of apps. This resulted in most
directories being created just by Settings trying to measure disk
space. Instead, we're switching to have vold do directory creation
when an app doesn't have enough permissions.
Create fs_mkdirs() utility to create all parent directories in a
path as needed. Allow traversal (+x) into /storage directories.
Fix FUSE derived permissions to be case insensitive. Mark well-known
directories as .nomedia when created.
Bug: 10577808, 10330221
Change-Id: I53114f2e63ffbe6de4ba6a72d94a232523231cad
handle_rename() would end up acquiring the lock twice. Change to
always derive has_rw inside earlier locks (instead of acquiring a
second time), and pass the value into check_caller_access_to_name().
Bug: 10547597
Change-Id: If5744d6d226a4785676c19d0f7fdf1c05060ed76
The fuse_open_out structure returned to the kernel by handle_opendir()
was not properly initializing all the fields. The symptom was recursive
ls (ls -R) failing on the emulated sdcard filesystem, because rewinddir(3)
was failing with ESPIPE.
Bug: 7168594
Change-Id: I56ddfd3453e6aac34fe6e001e88c4c46fb2eb271
The legacy internal layout places users at the top-level of the
filesystem, so handle with new PERM_LEGACY_PRE_ROOT when requested.
Mirror single OBB directory between all users without requiring fancy
bind mounts by letting a nodes graft in another part of the
underlying tree.
Move to everything having "sdcard_r" GID by default, and verify that
calling apps hold "sdcard_rw" when performing mutations. Determines
app group membership from new packages.list column.
Flag to optionally enable sdcard_pics/sdcard_av permissions
splitting. Flag to supply a default GID for all files. Ignore
attempts to access security sensitive files. Fix run-as to check for
new "package_info" GID.
Change-Id: Id5f3680779109141c65fb8fa1daf56597f49ea0d
Changes the FUSE daemon to synthesize an Android-specific set of
filesystem permissions, even when the underlying media storage is
permissionless. This is designed to support several features:
First, apps can access their own files in /Android/data/com.example/
without requiring any external storage permissions. This is enabled
by allowing o+x on parent directories, and assigning the UID owner
based on the directory name (package name). The mapping from package
to appId is parsed from packages.list, which is updated when apps are
added/removed. Changes are observed through inotify. It creates
missing package name directories when requested and valid.
Second, support for separate permissions for photos and audio/video
content on the device through new GIDs which are assigned based on
top-level directory names.
Finally, support for multi-user separation on the same physical media
through new /Android/user/ directory, which will be bind-mounted
into place. It recursively applies the above rules to each secondary
user.
rwxrwx--x root:sdcard_rw /
rwxrwx--- root:sdcard_pics /Pictures
rwxrwx--- root:sdcard_av /Music
rwxrwx--x root:sdcard_rw /Android
rwxrwx--x root:sdcard_rw /Android/data
rwxrwx--- u0_a12:sdcard_rw /Android/data/com.example
rwxrwx--x root:sdcard_rw /Android/obb/
rwxrwx--- u0_a12:sdcard_rw /Android/obb/com.example
rwxrwx--- root:sdcard_all /Android/user
rwxrwx--x root:sdcard_rw /Android/user/10
rwxrwx--- u10_a12:sdcard_rw /Android/user/10/Android/data/com.example
These derived permissions are disabled by default. Switched option
parsing to getopt().
Change-Id: I21bf5d79d13f0f07a6a116122b16395f4f97505b
The default is 1024 files, and in some testing, the limit has been
hit. This raises the limit to 8192. Going higher starts to cause
performance issues (I started to notice that around 16K open files
in my testing) as sdcard does linear searches. If a higher max
is needed, then the sdcard daemon will need some optimizations.
Bug: 7442187
Change-Id: I7aba7f4556ed70651f36244294a6756f3d6b8963
Clang turned up some signed/unsigned comparison warnings. These warnings
have been fixed by cleaning up sdcard slightly:
- Don't use negative numbers for invalid gid/uid.
- sdcard takes a fixed number of arguments now so assert on that instead
of using a for loop.
- Also fixed usage string to reflect this fact.
Change-Id: Iee58a8e9aaedb3d40ad7dfeef63d8cd1fe1cd248
Author: Edwin Vane <edwin.vane@intel.com>
Reviewed-by: Kevin P Schoedel <kevin.p.schoedel@intel.com>
The essential idea here is that a handler thread only needs to
hold a lock on the global node table while it is manipulating
nodes. The actual I/O operation is then performed without
holding any locks.
By default, we use 2 threads but this can be configured on the
command-line. Work is sheduled somewhat arbitrarily by the
handler threads. Whichever thread happens to read() the next
request first wins the right process it. This policy is very
simple but potentially wastes threads when there isn't much
work to be done. We can always improve this later if needed.
Change-Id: Id27a27c2c9b40d4f8e35a6bef9dd84f0dfacf337
This is mostly a structural change. The handlers have been moved
into individual functions, which will help with upcoming changes.
Change-Id: I774739d859e177d6b5d4186d2771444166b734fa
This request is needed for application correctness, without which
data corruption may result.
Bug: 6488845
Change-Id: I3d676c2e40f6e6b37d5d270c7cb40f1bf8c1fa47
Use constants to specify MAX_READ and MAX_WRITE buffer sizes and
use that to determine the size of the buffers that we need.
Be more careful about how the request header and data payload are
extracted. For example, the old code did len -= hdr->len, but
since len == hdr->len, this value was always 0. It turns out we
didn't use len thereafter, but we might want to for sanity checking
incoming requests.
Use const to make it clearer what data is coming out of the request.
Removed spurious error reply from FUSE_WRITE. It serves no purpose
and is ignored by the kernel.
Bug: 6488845
Change-Id: Ia328532979868f0aaea43744a49662f2f4511bfe
Slightly optimizes the writes used by sdcard to increase
throughput and decrease cpu load. Update the read
size to 256 x 1024 + 128 from current 8192 bytes since
writes can go as high as that.
Change-Id: I3bad425f31d4aa6f44f546e3d31439fd5bdca9ea
Signed-off-by: Sundar Raman <sunds@ti.com>