| #!/bin/sh |
| # Copyright 2016 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| # Run mount-passthrough with minijail0. |
| |
| set -e |
| |
| ROOTFSIMAGE=/usr/share/mount-passthrough/rootfs.squashfs |
| SOURCE_IN_CONTAINER=/mnt/source |
| DEST_IN_CONTAINER=/mnt/dest |
| |
| main() { |
| if [ $# -ne 4 ]; then |
| echo "Usage: $0 source dest container_root umask" |
| exit 1 |
| fi |
| |
| local source="$1" |
| local dest="$2" |
| local container_root="$3" |
| local umask="$4" |
| |
| # Set large enough open file limit since this process handles many open files. |
| ulimit -n 8192 |
| |
| # Start constructing minijail0 args... |
| set -- |
| |
| # Enter a new UTS namespace. |
| set -- "$@" --uts |
| |
| # Enter a new VFS namespace and remount /proc read-only. |
| set -- "$@" -v -r |
| |
| # Enter a new network namespace. |
| set -- "$@" -e |
| |
| # Enter a new PID namespace and run the process as init (pid=1). |
| set -- "$@" -p -I |
| |
| # Enter a new IPC namespace. |
| set -- "$@" -l |
| |
| # Forbid all caps except for CAP_SYS_ADMIN needed to mount fuse filesystem. |
| set -- "$@" -c 0x200000 |
| |
| # Run as chronos/chronos. |
| set -- "$@" -u chronos -g chronos -G |
| |
| # pivot_root to $container_root. |
| set -- "$@" -P "${container_root}" |
| |
| # Allow sharing mounts between CrOS and Android. |
| # WARNING: BE CAREFUL not to unexpectedly expose shared mounts in following |
| # bind mounts! Always remount them with MS_REC|MS_PRIVATE unless you want to |
| # share those mounts explicitly. |
| set -- "$@" -K |
| |
| # Do read-only bind mounts. |
| # This code assumes no new mount point appears under those directories |
| # during setup of minijail. Otherwise they can be bind-mounted read-write to |
| # the container. |
| # We need this assumption because MS_REMOUNT and MS_REC can not be used |
| # together. |
| for i in bin etc lib sbin usr; do |
| set -- "$@" -k "/${i},/${i},none,0x1000" # bind |
| set -- "$@" -k "/${i},/${i},none,0x1027" # bind,remount,nodev,nosuid,ro |
| done |
| |
| # Mount /proc. |
| set -- "$@" -b "/proc,/proc,1" |
| |
| # Mark PRIVATE recursively under (pivot) root, in order not to expose shared |
| # mount points accidentally. |
| set -- "$@" -k "none,/,none,0x44000" # private,rec |
| |
| # Mount source/dest directories. |
| # Note that those directories might be shared mountpoints and we allow them. |
| # 0x5000 = bind,rec |
| set -- "$@" -k "${source},${SOURCE_IN_CONTAINER},none,0x5000" |
| # 0x84000 = slave,rec |
| set -- "$@" -k "${source},${SOURCE_IN_CONTAINER},none,0x84000" |
| # 0x102e = bind,remount,noexec,nodev,nosuid |
| set -- "$@" -k "${source},${SOURCE_IN_CONTAINER},none,0x102e" |
| |
| # 0x1000 = bind |
| set -- "$@" -k "${dest},${DEST_IN_CONTAINER},none,0x1000" |
| # 0x102e = bind,remount,noexec,nodev,nosuid |
| set -- "$@" -k "${dest},${DEST_IN_CONTAINER},none,0x102e" |
| |
| # Finally, specify command line arguments. |
| set -- "$@" -- /usr/bin/mount-passthrough |
| set -- "$@" "${SOURCE_IN_CONTAINER}" "${DEST_IN_CONTAINER}" "${umask}" |
| |
| exec minijail0 "$@" |
| } |
| |
| main "$@" |