summaryrefslogtreecommitdiffstats
path: root/toolbox
diff options
context:
space:
mode:
authorNick Kralevich <nnk@google.com>2013-04-16 16:41:32 -0700
committerNick Kralevich <nnk@google.com>2013-04-24 08:53:26 -0700
commite18c0d508a6d8b4376c6f0b8c22600e5aca37f69 (patch)
treefcc32d8ac71aa67dba344a8a71114a49ee9430d0 /toolbox
parent072ee0143048a6bbd4068002352a4201ac853b6e (diff)
downloadsystem_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.c22
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) {