| # Copyright 2020 The ChromiumOS Authors | |
| # Use of this source code is governed by a BSD-style license that can be | |
| # found in the LICENSE file. | |
| description "Run /system/bin/adbd (bridge)" | |
| author "chromium-os-dev@chromium.org" | |
| # Note: Lifecycle of this job is managed by Chrome. | |
| # Stop this job when stopping ui job via arcvm-post-vm-start-services. | |
| # If Chrome crashes, Chrome stops arcvm-post-vm-start-services before | |
| # starting the mini-VM. | |
| stop on stopping arcvm-post-vm-start-services | |
| # There is no point to have this service when the VM it talks to has | |
| # been killed in oom case, so the value should be higher than the VM | |
| # instance. | |
| oom score -100 | |
| # The service will allocate some buffers. | |
| limit as 150000000 150000000 | |
| env PIDFILE=/run/arc/adbd.pid | |
| env RUNTIME_DIR=/run/arc/adbd | |
| env CONFIG=/etc/arc/adbd.json | |
| env HAS_DBC_SUPPORT=0 | |
| # The following environment variables are passed from Chrome. | |
| import SERIALNUMBER | |
| import ARCVM_CID | |
| pre-start script | |
| logger -t "${UPSTART_JOB}" "Pre-start arcvm-adbd" | |
| # Validity check against dev mode. | |
| if ! crossystem "cros_debug?1"; then | |
| logger -t "${UPSTART_JOB}" "Don't start arcvm-adbd in verified mode." | |
| stop | |
| exit 0 | |
| fi | |
| # Validity check against serial number is derived from Android CTS. | |
| if ! echo "${SERIALNUMBER}" | grep -q -E '^[0-9A-Za-z]{6,20}$'; then | |
| logger -t "${UPSTART_JOB}" "ERROR: Serial number is invalid." | |
| stop | |
| exit 0 | |
| fi | |
| # Validity check cid of VM that is defined as unsigned integer. | |
| # In arc-adbd service the CID is for guest VM so it should start | |
| # from 3. (Refer to the man page of vsock) | |
| if ! echo "${ARCVM_CID}" | grep -q -E '^(([3-9])|([1-9][0-9]+))$'; then | |
| logger -t "${UPSTART_JOB}" "ERROR: CID of ARCVM is invalid." | |
| stop | |
| exit 0 | |
| fi | |
| # Clean up a stale pid file if exists. | |
| if ! rm -f "${PIDFILE}"; then | |
| logger -t "${UPSTART_JOB}" "ERROR: Failed to remove ${PIDFILE}" | |
| stop | |
| exit 0 | |
| fi | |
| # Check for DbC and run DbC-specific configuration. | |
| if [ $(grep -ic '"adbOverDbcSupport":[^"]*true' ${CONFIG}) -ge 1 ]; then | |
| logger -t "${UPSTART_JOB}" "DbC support indicated in adbd.json." | |
| HAS_DBC_SUPPORT=1 | |
| else | |
| logger -t "${UPSTART_JOB}" "DbC support not indicated in adbd.json. \ | |
| Assuming gadget mode." | |
| HAS_DBC_SUPPORT=0 | |
| fi | |
| if [ "$HAS_DBC_SUPPORT" -eq 1 ]; then | |
| # Fetch USB-C PCI bus id from adb config file. | |
| DEVICE_ID=$(grep -o '"pciBusDeviceId": "[^"]*' ${CONFIG} | grep -o '[^"]*$') | |
| # Write Google Vendor ID to DbC device if no yet set. | |
| GOOGLE_VENDOR_ID="18d1" | |
| DBC_VENDOR_ID="$(cat /sys/bus/pci/devices/$DEVICE_ID/dbc_idVendor)" | |
| if [ ${DBC_VENDOR_ID} != ${GOOGLE_VENDOR_ID} ]; then | |
| # First disable DbC, and then change the vendor id. | |
| echo disable > /sys/bus/pci/devices/$DEVICE_ID/dbc | |
| echo "0x$GOOGLE_VENDOR_ID" > /sys/bus/pci/devices/$DEVICE_ID/dbc_idVendor | |
| fi | |
| # Enable DbC if needed. | |
| if [ $(cat /sys/bus/pci/devices/$DEVICE_ID/dbc) = "disabled" ]; then | |
| logger -t "${UPSTART_JOB}" "About to enable dbc on ${DEVICE_ID}." | |
| echo enable > /sys/bus/pci/devices/$DEVICE_ID/dbc | |
| fi | |
| fi | |
| end script | |
| script | |
| # Start constructing minijail0 args... | |
| args="minijail0" | |
| # Use a minimalistic mount namespace. | |
| args="${args} --profile minimalistic-mountns" | |
| # Enter a new mount namespace. | |
| args="${args} -v" | |
| # Enter a new PID namespace. | |
| args="${args} -p" | |
| # Skip remounting as private. | |
| args="${args} -K" | |
| # Enter a new IPC namespace. | |
| args="${args} -l" | |
| # Create PID file at $PIDFILE. | |
| args="${args} -f $PIDFILE" | |
| # Set up mount points. | |
| args="${args} -k \ | |
| tmpfs,/sys,tmpfs,MS_NOSUID|MS_NODEV|MS_NOEXEC,mode=755,size=10M" | |
| args="${args} -b /sys,/sys" | |
| # DbC-specific configuration. | |
| if [ $(grep -ic '"adbOverDbcSupport":[^"]*true' ${CONFIG}) -ge 1 ]; then | |
| # For DbC, need write permissions for usb role. | |
| for f in $(find /sys/class/usb_role -type l -exec readlink -f {} +); do | |
| args="${args} -b $f/role,,1"; | |
| done; | |
| # For accessing DbC device node. | |
| args="${args} -b /dev/dbc,/dev/dbc" | |
| # For udev monitor. | |
| args="${args} -k \ | |
| tmpfs,/run,tmpfs,MS_NOSUID|MS_NODEV|MS_NOEXEC,mode=755,size=10M" | |
| args="${args} -b /run/udev,/run/udev" | |
| fi | |
| # Set up seccomp-bpf. | |
| args="${args} -S /usr/share/policy/arcvm-adbd-seccomp.policy" | |
| # Allow only CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH, | |
| # CAP_SYS_MODULE, CAP_SYS_ADMIN. | |
| args="${args} -n -c 210007 --ambient" | |
| # Finally, specify the command line arguments. | |
| args="${args} -- /usr/sbin/arc-adbd \ | |
| --serialnumber=${SERIALNUMBER} \ | |
| --arcvm_cid=${ARCVM_CID}" | |
| logger -t "${UPSTART_JOB}" "Executing: ${args}" | |
| exec ${args} | |
| end script | |
| post-stop script | |
| { | |
| echo "Post-stop arcvm-adbd" | |
| set +e -x | |
| # Perform best-effort unmounting of the bulk endpoints. | |
| umount --lazy "${RUNTIME_DIR}"/ep1 | |
| umount --lazy "${RUNTIME_DIR}"/ep2 | |
| exec rm -f "${RUNTIME_DIR}/"* | |
| } 2>&1 | logger -t "${UPSTART_JOB}" | |
| end script |