diff options
author | Nick Kralevich <nnk@google.com> | 2013-04-16 16:41:32 -0700 |
---|---|---|
committer | Nick Kralevich <nnk@google.com> | 2013-04-24 08:53:26 -0700 |
commit | e18c0d508a6d8b4376c6f0b8c22600e5aca37f69 (patch) | |
tree | fcc32d8ac71aa67dba344a8a71114a49ee9430d0 /toolbox | |
parent | 072ee0143048a6bbd4068002352a4201ac853b6e (diff) | |
download | system_core-e18c0d508a6d8b4376c6f0b8c22600e5aca37f69.zip system_core-e18c0d508a6d8b4376c6f0b8c22600e5aca37f69.tar.gz system_core-e18c0d508a6d8b4376c6f0b8c22600e5aca37f69.tar.bz2 |
fs_mgr: make block devices read-only
When a filesystem is mounted read-only, make the underlying
block device read-only too. This helps prevent an attacker
who is able to change permissions on the files in /dev
(for example, symlink attack) from modifying the block device.
In particular, this change would have stopped the LG Thrill / Optimus
3D rooting exploit
(http://vulnfactory.org/blog/2012/02/26/rooting-the-lg-thrill-optimus-3d/)
as that exploit modified the raw block device corresponding to /system.
This change also makes UID=0 less powerful. Block devices cannot
be made writable again without CAP_SYS_ADMIN, so an escalation
to UID=0 by itself doesn't give full root access.
adb/mount: Prior to mounting something read-write, remove the
read-only restrictions on the underlying block device. This avoids
messing up developer workflows.
Change-Id: I135098a8fe06f327336f045aab0d48ed9de33807
Diffstat (limited to 'toolbox')
-rw-r--r-- | toolbox/mount.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/toolbox/mount.c b/toolbox/mount.c index b7adce2..164efcd 100644 --- a/toolbox/mount.c +++ b/toolbox/mount.c @@ -137,6 +137,24 @@ parse_mount_options(char *arg, unsigned long rwflag, struct extra_opts *extra, i return rwflag; } +/* + * Mark the given block device as read-write, using the BLKROSET ioctl. + */ +static void fs_set_blk_rw(const char *blockdev) +{ + int fd; + int OFF = 0; + + fd = open(blockdev, O_RDONLY); + if (fd < 0) { + // should never happen + return; + } + + ioctl(fd, BLKROSET, &OFF); + close(fd); +} + static char *progname; static struct extra_opts extra; @@ -178,6 +196,10 @@ do_mount(char *dev, char *dir, char *type, unsigned long rwflag, void *data, int dev = loopdev; } + if ((rwflag & MS_RDONLY) == 0) { + fs_set_blk_rw(dev); + } + while ((s = strsep(&type, ",")) != NULL) { retry: if (mount(dev, dir, s, rwflag, data) == -1) { |