Issue metadata
Sign in to add a comment
|
Security: Chrome OS runs ancient unrar in CAP_SYS_ADMIN context |
||||||||||||||||||||||
Issue descriptionTested on: "Version 69.0.3473.0 (Official Build) dev (64-bit)" "10820.0.0 (Official Build) dev-channel eve" The Chrome OS "Files" application supports opening RAR files. When you open a RAR archive, the archive's contents are accessed through the FUSE daemon avfsd. This daemon runs with the following privileges: ============================= chronos@localhost / $ cat /proc/8641/status Name: avfsd [...] Pid: 8641 [...] Uid: 301 301 301 301 Gid: 1001 1001 1001 1001 FDSize: 64 Groups: [...] CapInh: 00000000002000c1 CapPrm: 00000000002000c1 CapEff: 00000000002000c1 CapBnd: 00000000002000c1 CapAmb: 00000000002000c1 NoNewPrivs: 1 Seccomp: 2 [...] chronos@localhost / $ sudo ls -l /proc/8641/ns total 0 lrwxrwxrwx. 1 root root 0 Jul 20 21:34 cgroup -> 'cgroup:[4026531835]' lrwxrwxrwx. 1 root root 0 Jul 20 21:34 ipc -> 'ipc:[4026532589]' lrwxrwxrwx. 1 root root 0 Jul 20 21:34 mnt -> 'mnt:[4026531840]' lrwxrwxrwx. 1 root root 0 Jul 20 21:34 net -> 'net:[4026531960]' lrwxrwxrwx. 1 root root 0 Jul 20 21:34 pid -> 'pid:[4026531836]' lrwxrwxrwx. 1 root root 0 Jul 20 21:34 user -> 'user:[4026531837]' lrwxrwxrwx. 1 root root 0 Jul 20 21:34 uts -> 'uts:[4026531838]' chronos@localhost / $ sudo ls -l /proc/1/ns total 0 lrwxrwxrwx. 1 root root 0 Jul 20 21:35 cgroup -> 'cgroup:[4026531835]' lrwxrwxrwx. 1 root root 0 Jul 20 21:35 ipc -> 'ipc:[4026531839]' lrwxrwxrwx. 1 root root 0 Jul 20 21:35 mnt -> 'mnt:[4026531840]' lrwxrwxrwx. 1 root root 0 Jul 20 20:35 net -> 'net:[4026531960]' lrwxrwxrwx. 1 root root 0 Jul 20 21:35 pid -> 'pid:[4026531836]' lrwxrwxrwx. 1 root root 0 Jul 20 21:35 user -> 'user:[4026531837]' lrwxrwxrwx. 1 root root 0 Jul 20 21:35 uts -> 'uts:[4026531838]' ============================= So, it's running in the init user namespace, and it has the capability set 0x2000c1, which means: $ capsh --decode=2000c1 0x00000000002000c1=cap_chown,cap_setgid,cap_setuid,cap_sys_admin Note that even though the process doesn't have UID 0, it is still highly privileged thanks to its capabilities in the initial user namespace! It is subject to a seccomp policy, but that policy doesn't look particularly strict: https://chromium.googlesource.com/chromiumos/platform2/+/master/cros-disks/avfsd-seccomp-x86.policy Some interesting snippets from that policy: read/write access to any files to which you have access: read: 1 write: 1 # TODO(benchan): Prohibit or restrict write access. # Investigate if open('/dev/fuse', O_RDWR) can be avoided. open: 1 ability to mount filesystems (should be usable to e.g. bind-mount arbitrary directories over important system libraries): mount: 1 ability to override process credentials (especially useful in combination with the ability to open/read/write): setfsuid32: 1 setfsgid32: 1 setgroups32: 1 setresgid32: 1 setresuid32: 1 To confirm that the version of "unrar" that Chrome OS ships is outdated and contains publicly known vulnerabilities (testcase from https://bugs.chromium.org/p/project-zero/issues/detail?id=1286): ============================= chronos@localhost /home/chronos/u-98f63bfacd7086c303788fb107ff099ff85f3202/tmp $ which unrar /usr/bin/unrar chronos@localhost /home/chronos/u-98f63bfacd7086c303788fb107ff099ff85f3202/tmp $ unrar | head -n2 UNRAR 4.20 freeware Copyright (c) 1993-2012 Alexander Roshal chronos@localhost /home/chronos/u-98f63bfacd7086c303788fb107ff099ff85f3202/tmp $ cat > repro.b64 UmFyIRoHAPlOcwAADgAAAAAAAAAAMAh0AAAmAI4AAAAAAAAAAhBBUiEAAAAAHQAGAAAAACBzdGRv dXQgIVUMzRDNmBGByDAda+AXaSv4KvQr1K/oejL05mXmXmww5tEk8gA9k8nmieyeyeswuOR6cx69 a2Hd6zQwu3aoMDDwMEswADAAMD4P938w+dydoRFwAmwAAAAAvv////+/////+9W3QFgAAQAGAAAA Ooimhd12AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA chronos@localhost /home/chronos/u-98f63bfacd7086c303788fb107ff099ff85f3202/tmp $ base64 -d < repro.b64 > repro.rar chronos@localhost /home/chronos/u-98f63bfacd7086c303788fb107ff099ff85f3202/tmp $ unrar e repro.rar UNRAR 4.20 freeware Copyright (c) 1993-2012 Alexander Roshal Extracting from repro.rar Extracting stdout 81%Segmentation fault (core dumped) chronos@localhost /home/chronos/u-98f63bfacd7086c303788fb107ff099ff85f3202/tmp $ ============================= Note that this testcase doesn't seem to actually be mountable through avfsd because avfsd has its own code for parsing some metadata from RAR files, which rejects this testcase; only when a file needs to actually be extracted, unrar is invoked. To confirm that avfsd actually does invoke unrar without changing privileges, I'm using a statically linked strace from another machine. Here are the syscalls performed by avfsd when I open a file that's stored in some random harmless RAR file: ============================= localhost / # /media/exec/strace -f -p8641 /media/exec/strace: Process 8641 attached with 5 threads [pid 22819] read(3, <unfinished ...> [pid 18521] read(3, <unfinished ...> [pid 8979] read(3, <unfinished ...> [pid 8642] read(3, <unfinished ...> [pid 8641] futex(0x7ffc34701550, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, 0, NULL, 0xffffffff <unfinished ...> [pid 22819] <... read resumed> [...]..., 135168) = 51 [pid 22819] open("/home/chronos/u-98f63bfacd7086c303788fb107ff099ff85f3202/Downloads/harmless2.rar#urar", O_RDONLY) = -1 ENOENT (No such file or directory) [pid 22819] open("/home/chronos/u-98f63bfacd7086c303788fb107ff099ff85f3202/Downloads/harmless2.rar", O_RDONLY) = 6 [pid 22819] fcntl(6, F_SETFD, FD_CLOEXEC) = 0 [pid 22819] close(6) = 0 [pid 22819] stat("/home/chronos/u-98f63bfacd7086c303788fb107ff099ff85f3202/Downloads/harmless2.rar", {st_mode=S_IFREG|0644, st_size=2505067, ...}) = 0 [pid 22819] writev(3, [...], 2) = 144 [pid 22819] read(3, <unfinished ...> [pid 18521] <... read resumed> "[...]"..., 135168) = 48 [pid 18521] open("/home/chronos/u-98f63bfacd7086c303788fb107ff099ff85f3202/Downloads/harmless2.rar#urar", O_RDONLY) = -1 ENOENT (No such file or directory) [pid 18521] open("/home/chronos/u-98f63bfacd7086c303788fb107ff099ff85f3202/Downloads/harmless2.rar", O_RDONLY) = 6 [pid 18521] fcntl(6, F_SETFD, FD_CLOEXEC) = 0 [pid 18521] close(6) = 0 [pid 18521] stat("/home/chronos/u-98f63bfacd7086c303788fb107ff099ff85f3202/Downloads/harmless2.rar", {st_mode=S_IFREG|0644, st_size=2505067, ...}) = 0 [pid 18521] writev(3, [{iov_base="[...]", iov_len=16}], 1) = 16 [pid 18521] read(3, <unfinished ...> [pid 8979] <... read resumed> "[...]"..., 135168) = 48 [pid 8979] open("/home/chronos/u-98f63bfacd7086c303788fb107ff099ff85f3202/Downloads/harmless2.rar#urar", O_RDONLY) = -1 ENOENT (No such file or directory) [pid 8979] open("/home/chronos/u-98f63bfacd7086c303788fb107ff099ff85f3202/Downloads/harmless2.rar", O_RDONLY) = 6 [pid 8979] fcntl(6, F_SETFD, FD_CLOEXEC) = 0 [pid 8979] close(6) = 0 [pid 8979] stat("/home/chronos/u-98f63bfacd7086c303788fb107ff099ff85f3202/Downloads/harmless2.rar", {st_mode=S_IFREG|0644, st_size=2505067, ...}) = 0 [pid 8979] open("/home/chronos/u-98f63bfacd7086c303788fb107ff099ff85f3202/Downloads/harmless2.rar", O_RDONLY) = 6 [pid 8979] fcntl(6, F_SETFD, FD_CLOEXEC) = 0 [pid 8979] mkdir("/tmp/.avfs_tmp_YwPqMv", 0700) = 0 [pid 8979] open("/tmp/.avfs_tmp_YwPqMv/atmp000000", O_RDWR|O_CREAT|O_TRUNC, 0644) = 7 [pid 8979] open("/dev/null", O_RDONLY) = 8 [pid 8979] clone(/media/exec/strace: Process 22926 attached <unfinished ...> [pid 22926] set_robust_list(0x7f58a37fe9e0, 24 <unfinished ...> [pid 8979] <... clone resumed> child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f58a37fe9d0) = 22926 [pid 22926] <... set_robust_list resumed> ) = 0 [pid 22926] setsid( <unfinished ...> [pid 8979] close(8 <unfinished ...> [pid 22926] <... setsid resumed> ) = 22926 [pid 8979] <... close resumed> ) = 0 [pid 22926] dup2(8, 0 <unfinished ...> [pid 8979] wait4(22926, <unfinished ...> [pid 22926] <... dup2 resumed> ) = 0 [pid 22926] dup2(7, 1) = 1 [pid 22926] dup2(8, 2) = 2 [pid 22926] execve("/usr/bin/rar", ["rar", "p", "-c-", "-ierr", "/home/chronos/u-98f63bfacd7086c3"..., "test.blend"], 0x7ffc34701740 /* 16 vars */) = -1 ENOENT (No such file or directory) [pid 22926] execve("/usr/sbin/rar", ["rar", "p", "-c-", "-ierr", "/home/chronos/u-98f63bfacd7086c3"..., "test.blend"], 0x7ffc34701740 /* 16 vars */) = -1 ENOENT (No such file or directory) [pid 22926] execve("/sbin/rar", ["rar", "p", "-c-", "-ierr", "/home/chronos/u-98f63bfacd7086c3"..., "test.blend"], 0x7ffc34701740 /* 16 vars */) = -1 ENOENT (No such file or directory) [pid 22926] execve("/bin/rar", ["rar", "p", "-c-", "-ierr", "/home/chronos/u-98f63bfacd7086c3"..., "test.blend"], 0x7ffc34701740 /* 16 vars */) = -1 ENOENT (No such file or directory) [pid 22926] execve("/usr/local/sbin/rar", ["rar", "p", "-c-", "-ierr", "/home/chronos/u-98f63bfacd7086c3"..., "test.blend"], 0x7ffc34701740 /* 16 vars */) = -1 ENOENT (No such file or directory) [pid 22926] execve("/usr/local/bin/rar", ["rar", "p", "-c-", "-ierr", "/home/chronos/u-98f63bfacd7086c3"..., "test.blend"], 0x7ffc34701740 /* 16 vars */) = -1 ENOENT (No such file or directory) [pid 22926] write(5, "07/20 22:29:22 avfs[22926]: Fail"..., 47) = 47 [pid 22926] exit_group(1) = ? [pid 22926] +++ exited with 1 +++ [pid 8979] <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 1}], 0, NULL) = 22926 [pid 8979] write(5, "07/20 22:29:22 avfs[8641]: progr"..., 60) = 60 [pid 8979] open("/dev/null", O_RDONLY) = 8 [pid 8979] clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f58a37fe9d0) = 22927 /media/exec/strace: Process 22927 attached [pid 8979] close(8) = 0 [pid 8979] wait4(22927, <unfinished ...> [pid 22927] set_robust_list(0x7f58a37fe9e0, 24) = 0 [pid 22927] setsid() = 22927 [pid 22927] dup2(8, 0) = 0 [pid 22927] dup2(7, 1) = 1 [pid 22927] dup2(8, 2) = 2 [pid 22927] execve("/usr/bin/unrar", ["unrar", "p", "-c-", "-ierr", "/home/chronos/u-98f63bfacd7086c3"..., "test.blend"], 0x7ffc34701740 /* 16 vars */) = 0 [...] ============================= This bug is subject to a 90 day disclosure deadline. After 90 days elapse or a patch has been made broadly available (whichever is earlier), the bug report will become visible to the public.
,
Jul 20
Jann, thanks for reporting this issue and the details. There are a couple of issues here that we need to fix: 1. uprev unrar. 2. Better sandboxing Files app, which is browser process. We probably need to refine the seccomp policy for this process. +cc: the file_manager owners.
,
Jul 20
,
Jul 20
+benchan@, can you take a look at the seccomp policy to see if we can make it more restrictive? Thanks.
,
Jul 20
,
Jul 21
,
Jul 23
,
Jul 23
The following revision refers to this bug: https://chromium.googlesource.com/chromiumos/overlays/portage-stable/+/bf81438054e8b9011699ba52faa1afe43f104244 commit bf81438054e8b9011699ba52faa1afe43f104244 Author: Ben Chan <benchan@chromium.org> Date: Mon Jul 23 19:59:54 2018 app-arch/unrar: Upgrade to unrar 5.6.5 This CL imports unrar 5.6.5 from upstream Gentoo and modifies KEYWORDS to "*". BUG= chromium:866129 TEST=Tested the following: 1. `emerge-{x86,amd64,arm}-generic unrar` and verify that unrar 5.6.5 is built. 2. Run platform_CrosDisksArchive.rar tests on {x86,amd64,arm}-generic. Change-Id: Ifb6cf14cb9acaa0278a839ca7fb3a744b0904c56 Reviewed-on: https://chromium-review.googlesource.com/1145901 Commit-Ready: Ben Chan <benchan@chromium.org> Tested-by: Ben Chan <benchan@chromium.org> Reviewed-by: Mike Frysinger <vapier@chromium.org> [modify] https://crrev.com/bf81438054e8b9011699ba52faa1afe43f104244/app-arch/unrar/Manifest [add] https://crrev.com/bf81438054e8b9011699ba52faa1afe43f104244/app-arch/unrar/files/unrar-5.5.5-honor-flags.patch [add] https://crrev.com/bf81438054e8b9011699ba52faa1afe43f104244/app-arch/unrar/unrar-5.6.5.ebuild [add] https://crrev.com/bf81438054e8b9011699ba52faa1afe43f104244/app-arch/unrar/files/unrar-5.5.5-build.patch [delete] https://crrev.com/d24f48876a41a47a44277f7335be47b05eac47c2/app-arch/unrar/unrar-4.2.4.ebuild [modify] https://crrev.com/bf81438054e8b9011699ba52faa1afe43f104244/app-arch/unrar/metadata.xml
,
Jul 23
unrar is now upgraded to 5.6.5. I'll have another set of CLs to further restrict the seccomp policy and isolate the namespaces for avfsd.
,
Jul 24
I experimented the following recipe that restricts the avfsd process, and the child rar process under a separate mount namespace:
mount --make-shared -t tmpfs -o nosuid,noexec,nodev,uid="$(id -u avfs)",gid="$(id -u avfs)",mode=0770 tmpfs /run/avfsroot
mkdir -m 0770 /run/avfsroot/media
chown avfs:avfs /run/avfsroot/media
minijail0 -u avfs -g chronos-access -KNlpvrt -S /opt/google/cros-disks/avfsd-seccomp-x86.policy \
-P /var/empty --mount-dev -b / -b /dev/fuse,,1 -b /proc -b /media -b /run -b /run/avfsroot,,1 \
-- /usr/bin/avfsd -o ro,nodev,noexec,nosuid,allow_other,user=chronos,modules=subdir,subdir=/media /run/avfsroot/media
However, given that cros-disks is already inside a minijail (i.e. minijail0 -u cros-disks -g cros-disks -G -c 0x2000c1 --ambient -i -l -n -- /opt/google/cros-disks/disks), setting up the inner minijail for avfsd will require a more relaxed outer minijail for cros-disks, which is not very ideal.
I guess I'd go after the seccomp policy for avfsd and take a closer look there.
,
Jul 24
Re #11: CAP_SYS_MKNOD (for --mount-dev), CAP_SYS_CHROOT (for -P/var/empty) would be needed. We could probably avoid adding CAP_SYS_MKNOD by simply bind-mounting the full /dev and /dev/fuse
,
Jul 25
,
Aug 1
The following revision refers to this bug: https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay/+/c9a249c967cc2af401afd87c2639acb1d64c7c2f commit c9a249c967cc2af401afd87c2639acb1d64c7c2f Author: Ben Chan <benchan@chromium.org> Date: Wed Aug 01 17:01:55 2018 sys-fs/avfs: upgrade to 1.0.5 This CL imports avfs 1.0.5 from upstream Gentoo, with the following local modifications for Chromium OS: - Change KEYWORDS to "*" - Port CL:186361 ("sys-fs/avfs: patch avfs 1.0.1 to handle malformed zip entries") - Port CL:212922 ("sys-fs/avfs: Drop support for dynamic modules.") - Port CL:219891 ("sys-fs/avfs: Add extfs USE flags to control whether extfs files are installed.") - Port CL:272834 ("sys-fs/avfs: Remove bash dependency") - Port CL:867509 ("sys-fs/avfs: patch avfs to handle extra bytes at the beginning of zip file") BUG= chromium:866129 BUG=chromium:867509 TEST=Remote trybot runs. TEST=Run platform_CrosDisksArchive tests. TEST=Test opening ZIP and RAR files from Files.app. Change-Id: I8150af563295b935df7e7689ce271f1988c8282f Reviewed-on: https://chromium-review.googlesource.com/1157443 Commit-Ready: Ben Chan <benchan@chromium.org> Tested-by: Ben Chan <benchan@chromium.org> Reviewed-by: Mike Frysinger <vapier@chromium.org> [modify] https://crrev.com/c9a249c967cc2af401afd87c2639acb1d64c7c2f/sys-fs/avfs/Manifest [rename] https://crrev.com/c9a249c967cc2af401afd87c2639acb1d64c7c2f/sys-fs/avfs/files/avfs-1.0.5-zip-attr-fix.patch [delete] https://crrev.com/61d76183784415e4d3ff1cc9ef908332a87baf05/sys-fs/avfs/avfs-1.0.1-r5.ebuild [modify] https://crrev.com/c9a249c967cc2af401afd87c2639acb1d64c7c2f/sys-fs/avfs/metadata.xml [rename] https://crrev.com/c9a249c967cc2af401afd87c2639acb1d64c7c2f/sys-fs/avfs/files/avfs-1.0.5-disable-dynamic-modules.patch [add] https://crrev.com/c9a249c967cc2af401afd87c2639acb1d64c7c2f/sys-fs/avfs/avfs-1.0.5-r1.ebuild [rename] https://crrev.com/c9a249c967cc2af401afd87c2639acb1d64c7c2f/sys-fs/avfs/files/avfs-1.0.5-zip-handle-extra-bytes.patch [rename] https://crrev.com/c9a249c967cc2af401afd87c2639acb1d64c7c2f/sys-fs/avfs/files/avfs-1.0.5-use-posix-shell.patch [rename] https://crrev.com/c9a249c967cc2af401afd87c2639acb1d64c7c2f/sys-fs/avfs/avfs-1.0.5.ebuild
,
Aug 14
Ben, what's the status here?
,
Aug 21
Can probably mark this one as fixed and open a separate bug for the seccomp policy improvements?
,
Aug 22
+amistry re: the rar stuff.
,
Aug 22
Re #15, #16: the seccomp policy hardening is tracked under crbug.com/866377. In parallel, I'm exploring the approach described in comment #11. As we've updated unrar to 5.6.5 (and avfs to 1.0.5 as well), one of the underlying vulnerabilities used in the exploit chain described in https://bugs.chromium.org/p/project-zero/issues/detail?id=1286 should have been addressed. If that's correct, we can close this bug and focus on 866377 and related bugs. jannh, jorgelo, mnissler: wdyt?
,
Aug 22
Either way is fine with me.
,
Aug 22
if we've cut the chain, closing out this bug is good as it has all the scary security labels attached to it forking out more improvements into sep bugs also sounds good ... just mark them as blockers relative to this so it's easier to look up after the fact
,
Aug 22
I'm a big fan of keeping individual bugs scoped to limited amounts of work, so we should close this.
,
Aug 24
,
Aug 25
,
Oct 5
Pixelbook on beta channel has the fixed unrar version, but Pixelbook on stable channel (at 69.0.3497.95) still has unrar 4.20. The 90-day deadline for this bug ends in 13 days, on the 18th.
,
Oct 5
70 should go to stable on 10/23.
,
Oct 5
+cindyb to weigh in on a potential merge to M69, given that the M70 stable date (10/16? or 23?) is around the bug disclosure deadline on 10/18.
,
Oct 5
+cindyb
,
Oct 5
As per https://chromiumdash.appspot.com/schedule, M70 for CrOS is 10/23.
,
Oct 5
One thing that's probably worth noting is that given how we've been missing our release dates for CrOS, maybe it does make sense to fix 69 on the assumption that the 70 release will slip.
,
Oct 5
Re #28: you're right. I misread the Chrome stable release date as Chrome OS ;) If we were to merge back to M69, how soon the next possible stable push would be?
,
Oct 5
If you commit to shipping the patch on the 23rd (or another specific date within 14 days of October 18th), per https://googleprojectzero.blogspot.com/2015/02/feedback-and-data-driven-updates-to.html, I'll apply the grace extension label to the bug and delay disclosure.
,
Oct 5
While we're waiting for +cindyb to weigh in on M69 merge, here're the cherry-pick CLs for M69: https://chromium-review.googlesource.com/c/chromiumos/overlays/portage-stable/+/1263830 https://chromium-review.googlesource.com/c/chromiumos/overlays/chromiumos-overlay/+/1264632
,
Oct 5
,
Oct 5
The extension would allow us to align with the target release date of 10/23, for sure. The issue is that the Chrome OS release process is complex enough at this point (involving dozens of boards, CTS testing, and the like) that while I'm, say, 95% certain we'll hit 10/23 or a few days after, I don't know that I can guarantee it at 100%. So we're committing to attempt to ship the 70 release starting on 10/23. Geo, how's the 70 release looking?
,
Oct 6
,
Oct 9
Please also cherry-pick https://chromium-review.googlesource.com/c/chromiumos/platform2/+/1180838 The unrar update broke rar file mounting because the updated unrar uses an additional syscall, which triggered the seccomp sandbox.
,
Oct 9
you authored that CL, so shouldn't you be able to cherry pick it back as makes sense ?
,
Oct 15
I'll mark it as having a deadline extension in our bugtracker; if the fix doesn't ship on time, we'll factor that in to future decisions about extensions.
,
Oct 17
,
Dec 1
This bug has been closed for more than 14 weeks. Removing security view restrictions. For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
,
Dec 5
|
|||||||||||||||||||||||
►
Sign in to add a comment |
|||||||||||||||||||||||
Comment 1 by jannh@google.com
, Jul 20