| ; Copyright 2017 The Chromium Authors |
| ; Use of this source code is governed by a BSD-style license that can be |
| ; found in the LICENSE file. |
| (version 1) |
| |
| ; Helper function to check if a param is set to true. |
| (define (param-true? str) (string=? (param str) "TRUE")) |
| |
| ; Helper function to determine if a parameter is defined or not. |
| (define (param-defined? str) (string? (param str))) |
| |
| ; Define constants for all of the parameter strings passed in. |
| (define browser-pid "BROWSER_PID") |
| (define bundle-id "BUNDLE_ID") |
| (define helper-bundle-id "HELPER_BUNDLE_ID") |
| (define bundle-path "BUNDLE_PATH") |
| (define component-path "COMPONENT_PATH") |
| (define disable-sandbox-denial-logging "DISABLE_SANDBOX_DENIAL_LOGGING") |
| (define enable-logging "ENABLE_LOGGING") |
| (define executable-path "EXECUTABLE_PATH") |
| (define homedir-as-literal "USER_HOMEDIR_AS_LITERAL") |
| (define log-file-path "LOG_FILE_PATH") |
| (define os-version (string->number (param "OS_VERSION"))) |
| (define darwin-user-cache-dir "DARWIN_USER_CACHE_DIR") |
| (define darwin-user-dir "DARWIN_USER_DIR") |
| (define darwin-user-temp-dir "DARWIN_USER_TEMP_DIR") |
| ; There are two separate flags for syscall filtering to allow it |
| ; to be rolled out to one process type at a time, while still allowing |
| ; local development. |
| (define filter-syscalls "FILTER_SYSCALLS") |
| (define filter-syscalls-debug "FILTER_SYSCALLS_DEBUG") |
| |
| ; Sandboxed processes which use Metal may need to disable the shader cache. |
| (define disable-metal-shader-cache "DISABLE_METAL_SHADER_CACHE") |
| |
| ; --enable-sandbox-logging causes the sandbox to log failures to the syslog. |
| (if (param-true? disable-sandbox-denial-logging) |
| (deny default (with no-log)) |
| (deny default)) |
| |
| (if (param-true? enable-logging) (debug deny)) |
| |
| ; Allow sending signals to self - https://crbug.com/20370 |
| (allow signal (target self)) |
| |
| ; TODO(rsesek): Lock down `(deny process-info*)`. |
| (allow process-info-pidinfo (target self)) |
| |
| ; Consumes a subpath and appends it to the user's homedir path. |
| (define (user-homedir-path subpath) |
| (string-append (param homedir-as-literal) subpath)) |
| |
| ; A function that specific profiles (i.e. renderer) can call to allow |
| ; font rendering. |
| (define (allow-font-access) |
| (begin |
| (allow file-read-data |
| (subpath "/Library/Fonts") |
| (subpath "/System/Library/Fonts") |
| (subpath (user-homedir-path "/Library/Fonts")) |
| ) |
| (allow mach-lookup |
| ; https://crbug.com/756145, https://crbug.com/786615 |
| (global-name "com.apple.FontObjectsServer") |
| (global-name "com.apple.fonts") |
| ) |
| ; To allow accessing downloaded and other hidden fonts in |
| ; /System/Library/Asssets/com_apple_MobileAsset_Font*. |
| ; (https://crbug.com/662686) |
| (allow file-read* (extension "com.apple.app-sandbox.read")))) |
| |
| ; A function that profiles can call to allow forcibly disabling the Metal shader |
| ; cache in lieu of poking necessary holes in the sandbox for it. |
| ; See https://crbug.com/1159113 |
| (define (maybe-disable-metal-shader-cache) |
| (if (param-true? disable-metal-shader-cache) |
| (let ((metal-cache-dir (subpath (string-append (param darwin-user-cache-dir) |
| "/com.apple.metal")))) |
| (deny file-read* metal-cache-dir) |
| (deny file-write* metal-cache-dir) |
| #t) |
| #f)) |
| |
| ; A function profiles can call to enable the requisite file access needed for |
| ; Metal shader compilation to work with the shader cache. |
| ; |
| ; Metal shader compilation may be offloaded to a helper process that needs |
| ; access to the user cache directory in order to cache its work to disk. |
| ; If this sandbox is applied to an executable that is not within an app bundle, |
| ; such as in a unit test, the helper-bundle-id parameter will not be set and |
| ; issuing sandbox extensions to the Metal cache directories will not be allowed. |
| ; See https://crbug.com/1453813 |
| (define (maybe-allow-metal-shader-cache-access) |
| (begin |
| (if (param helper-bundle-id) |
| (let ((helper-bundle-cache-dir |
| (string-append (param darwin-user-cache-dir) |
| "/" (param helper-bundle-id)))) |
| (allow file-issue-extension |
| (require-all |
| (extension-class "com.apple.app-sandbox.read-write") |
| (require-any |
| (subpath (string-append helper-bundle-cache-dir |
| "/com.apple.metalfe")) |
| (subpath (string-append helper-bundle-cache-dir |
| "/com.apple.gpuarchiver"))))))))) |
| |
| ; Reads of signed Mach-O blobs created by the CVMS server. |
| ; https://crbug.com/850021 |
| (define (allow-cvms-blobs) |
| (if (>= os-version 1014) |
| (begin |
| (allow file-read* file-write-unlink |
| (prefix "/private/tmp/cvmsCodeSignObj")) |
| (allow file-read* |
| (extension "com.apple.cvms.kernel") |
| (prefix "/private/var/db/CVMS/cvmsCodeSignObj")) |
| ))) |
| |
| ; Allow logging for all processes. |
| (allow file-write* |
| (require-all |
| (path (param log-file-path)) |
| (vnode-type REGULAR-FILE))) |
| |
| ; Allow component builds to work. |
| (if (param-defined? component-path) |
| (allow file-read* (subpath (param component-path)))) |
| |
| (allow process-exec (path (param executable-path))) |
| (allow file-read* (path (param executable-path))) |
| |
| ; The browser exposes Mach services at "bundle-id.service-name.browser-pid". |
| ; This macro is a helper for doing the string concatenation. |
| (define (browser-service-name service-name) |
| (global-name (string-append (param bundle-id) |
| "." service-name "." |
| (param browser-pid)))) |
| |
| (allow mach-lookup |
| (browser-service-name "MachPortRendezvousServer") |
| ) |
| |
| ; Allow realpath() to work. |
| (allow file-read-metadata (subpath "/")) |
| |
| ; All processes can read the bundle contents. |
| (allow file-read* (subpath (param bundle-path))) |
| |
| ; A sandbox bug on macOS 11 and 12 causes the sandbox to see any paths within |
| ; the data volume (/System/Volumes/Data) outside of system firm link locations |
| ; (listed in /usr/share/firmlinks) as though they were not on the data volume, |
| ; causing it to deny access to user paths containing the data volume mount point |
| ; as a prefix. This is filed as https://openradar.appspot.com/FB9738355 and |
| ; tracked at https://crbug.com/1266490. Although macOS 10.15 also has the root |
| ; volume split, this bug does not appear to affect that OS version. |
| ; |
| ; When the bundle path appears in the data volume, this causes the sandbox to |
| ; deny access to the bundle. |
| ; |
| ; This is not a problem in normal use, as typical bundle paths, while on the |
| ; data volume, will be in system firm link locations such as /Applications or |
| ; /Users. As a workaround for other cases where the bundle may be present on the |
| ; data volume but not in a system firm link location, configure the sandbox with |
| ; an alternate bundle path so that it permits access to the bundle. |
| (define (string-prefix? str prefix) |
| (let ((l (string-length prefix))) |
| (if (< (string-length str) l) |
| #f |
| (equal? (substring str 0 l) prefix) |
| ) |
| ) |
| ) |
| (define data-volume-root "/System/Volumes/Data/") |
| (when (string-prefix? (param bundle-path) data-volume-root) |
| (define (strip-leading-chars str count) |
| (substring str count (string-length str)) |
| ) |
| (allow file-read* |
| (subpath (strip-leading-chars (param bundle-path) |
| (- (string-length data-volume-root) 1)))) |
| ) |
| |
| ; Allow reads of system libraries and frameworks. |
| (allow file-read* |
| (subpath "/System/Library/CoreServices/CoreTypes.bundle") |
| (subpath "/System/Library/CoreServices/SystemVersion.bundle") |
| (subpath "/System/Library/Frameworks") |
| (subpath "/System/Library/Preferences/Logging") |
| (subpath "/System/Library/PrivateFrameworks") |
| (subpath "/usr/lib") |
| ) |
| |
| ; Reads from /etc. |
| ; This is read by CFPrefs calling getpwuid in a loop. libinfo then fails to |
| ; contact any of the opendirectoryd mach services, and falls back to |
| ; the /etc/passwd file for the user info. The access is OK because |
| ; no actual password hashes are in /etc/passwd anymore. |
| (allow file-read-data (path "/private/etc/passwd")) |
| |
| ; Access to /dev. |
| (allow file-ioctl file-read-data file-write-data |
| (require-all |
| (path "/dev/dtracehelper") |
| (vnode-type CHARACTER-DEVICE))) |
| |
| (allow file-read-data |
| (path "/dev/null") |
| (path "/dev/random") |
| (path "/dev/urandom") |
| ) |
| |
| (allow file-read* (subpath "/private/var/db/timezone")) |
| (allow file-read-data (subpath "/usr/share/zoneinfo.default")) |
| |
| ; Reads from /Library. |
| (allow file-read-data |
| (path "/Library/Managed Preferences/.GlobalPreferences.plist") |
| (path "/Library/Preferences/.GlobalPreferences.plist") |
| (path (string-append "/Library/Managed Preferences/" (param bundle-id) ".plist")) |
| (path (string-append "/Library/Preferences/" (param bundle-id) ".plist")) |
| (regex #"/Library/Managed Preferences/.*/\.GlobalPreferences\.plist") |
| (regex (string-append #"/Library/Managed Preferences/.*/" (regex-quote (param bundle-id)) #"\.plist")) |
| ) |
| |
| ; Reads from /System. |
| (allow file-read-data |
| (path "/System/Library/CoreServices/SystemVersion.plist") |
| (path "/System/Library/CoreServices/SystemVersionCompat.plist") ; https://crbug.com/1108832 |
| (path "/System/Library/CoreServices/checkfixlist") |
| ) |
| |
| ; From /System/Library/Sandbox/Profiles/dyld-support.sb on macOS 13. |
| (if (>= os-version 1300) |
| (allow file-read* file-map-executable |
| (subpath "/System/Cryptexes/App") |
| (subpath "/System/Cryptexes/OS") |
| (subpath "/System/Volumes/Preboot/Cryptexes/App/System") |
| (subpath "/System/Volumes/Preboot/Cryptexes/OS") |
| ) |
| ) |
| |
| ; Reads from /usr. |
| (allow file-read-data |
| (subpath "/usr/share/icu") |
| (subpath "/usr/share/locale") |
| ) |
| |
| ; Access to the home directory. |
| (allow file-read-data |
| (path (string-append (user-homedir-path "/Library/Preferences/") (param bundle-id) ".plist")) |
| (path (user-homedir-path "/Library/Preferences/.GlobalPreferences.plist")) |
| (path (user-homedir-path "/Library/Preferences/.GlobalPreferences_m.plist")) |
| (prefix (user-homedir-path "/Library/Preferences/ByHost/.GlobalPreferences")) |
| (path (user-homedir-path "/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist")) |
| ) |
| |
| ; Mach IPC needed by all Chromium Helper instances. |
| (allow mach-lookup |
| (global-name "com.apple.logd") ; https://crbug.com/792229 |
| (global-name "com.apple.system.logger") |
| (global-name "com.apple.system.opendirectoryd.libinfo") ; https://crbug.com/792228 |
| ) |
| |
| ; sysctls permitted. |
| (allow sysctl-read |
| (sysctl-name "hw.activecpu") |
| (sysctl-name "hw.busfrequency_compat") |
| (sysctl-name "hw.byteorder") |
| (sysctl-name "hw.cachelinesize_compat") |
| (sysctl-name "hw.cpufrequency_compat") |
| (sysctl-name "hw.cputype") |
| (sysctl-name "hw.logicalcpu_max") |
| (sysctl-name "hw.machine") |
| (sysctl-name "hw.ncpu") |
| (sysctl-name "hw.nperflevels") |
| (sysctl-name "hw.optional.arm.FEAT_SHA512") |
| (sysctl-name "hw.optional.armv8_2_sha512") |
| (sysctl-name "hw.pagesize_compat") |
| (sysctl-name "hw.physicalcpu_max") |
| (sysctl-name "hw.tbfrequency_compat") |
| (sysctl-name "hw.vectorunit") |
| (sysctl-name "kern.hostname") |
| (sysctl-name "kern.maxfilesperproc") |
| (sysctl-name "kern.osproductversion") |
| (sysctl-name "kern.osrelease") |
| (sysctl-name "kern.ostype") |
| (sysctl-name "kern.osvariant_status") |
| (sysctl-name "kern.osversion") |
| (sysctl-name "kern.secure_kernel") |
| (sysctl-name "kern.usrstack64") |
| (sysctl-name "kern.version") |
| (sysctl-name "sysctl.proc_cputype") |
| (sysctl-name-prefix "hw.perflevel") |
| ) |
| |
| (allow network-outbound |
| (literal "/private/var/run/asl_input") |
| (literal "/private/var/run/syslog") |
| ) |
| |
| ; This is available in 10.15+, and rolled out as a Finch experiment. |
| (if (param-true? filter-syscalls) |
| (when (defined? 'syscall-unix) |
| (allow syscall-unix |
| (syscall-number SYS___disable_threadsignal) |
| (syscall-number SYS___mac_syscall) |
| (syscall-number SYS___pthread_kill) |
| (syscall-number SYS___pthread_markcancel) |
| (syscall-number SYS___pthread_sigmask) |
| (syscall-number SYS___semwait_signal) |
| (syscall-number SYS___semwait_signal_nocancel) |
| (syscall-number SYS_access) |
| (syscall-number SYS_bsdthread_create) |
| (syscall-number SYS_bsdthread_ctl) |
| (syscall-number SYS_bsdthread_register) |
| (syscall-number SYS_bsdthread_terminate) |
| (syscall-number SYS_close) |
| (syscall-number SYS_close_nocancel) |
| (syscall-number SYS_csops_audittoken) |
| (syscall-number SYS_exit) |
| (syscall-number SYS_fcntl) |
| (syscall-number SYS_fileport_makefd) |
| (syscall-number SYS_fileport_makeport) |
| (syscall-number SYS_fstat64) |
| (syscall-number SYS_fstatat64) |
| (syscall-number SYS_fstatfs64) |
| (syscall-number SYS_getattrlist) |
| (syscall-number SYS_getattrlistbulk) |
| (syscall-number SYS_getaudit_addr) |
| (syscall-number SYS_getdirentries64) |
| (syscall-number SYS_geteuid) |
| (syscall-number SYS_getgid) |
| (syscall-number SYS_gethostuuid) |
| (syscall-number SYS_getpid) |
| (syscall-number SYS_getppid) |
| (syscall-number SYS_getpriority) |
| (syscall-number SYS_getrlimit) |
| (syscall-number SYS_gettimeofday) |
| (syscall-number SYS_getuid) |
| (syscall-number SYS_ioctl) |
| (syscall-number SYS_issetugid) |
| (syscall-number SYS_kdebug_trace64) |
| (syscall-number SYS_kevent64) |
| (syscall-number SYS_kevent_id) |
| (syscall-number SYS_kevent_qos) |
| (syscall-number SYS_kqueue) |
| (syscall-number SYS_lstat64) |
| (syscall-number SYS_madvise) |
| (syscall-number SYS_mmap) |
| (syscall-number SYS_mprotect) |
| (syscall-number SYS_munmap) |
| (syscall-number SYS_open) |
| (syscall-number SYS_open_dprotected_np) |
| (syscall-number SYS_open_nocancel) |
| (syscall-number SYS_pread) |
| (syscall-number SYS_proc_info) |
| (syscall-number SYS_psynch_mutexdrop) |
| (syscall-number SYS_psynch_mutexwait) |
| (syscall-number SYS_psynch_rw_downgrade) |
| (syscall-number SYS_psynch_rw_longrdlock) |
| (syscall-number SYS_psynch_rw_rdlock) |
| (syscall-number SYS_psynch_rw_unlock) |
| (syscall-number SYS_psynch_rw_unlock2) |
| (syscall-number SYS_psynch_rw_upgrade) |
| (syscall-number SYS_psynch_rw_wrlock) |
| (syscall-number SYS_psynch_rw_yieldwrlock) |
| (syscall-number SYS_read) |
| (syscall-number SYS_read_nocancel) |
| (syscall-number SYS_readlink) |
| (syscall-number SYS_shm_open) |
| (syscall-number SYS_sigaction) |
| (syscall-number SYS_sigprocmask) |
| (syscall-number SYS_sigreturn) |
| (syscall-number SYS_stat64) |
| (syscall-number SYS_statfs64) |
| (syscall-number SYS_sysctl) |
| (syscall-number SYS_sysctlbyname) |
| (syscall-number SYS_thread_selfid) |
| (syscall-number SYS_ulock_wait) |
| (syscall-number SYS_ulock_wake) |
| (syscall-number SYS_workq_kernreturn) |
| (syscall-number SYS_workq_open) |
| ))) |
| |
| ; Explicit denials. These are already covered by the blanket `(deny default)`, |
| ; but benefit from explanation as to why they're denied. |
| (deny mach-lookup |
| ; CFPreferences falls back to in-process access to preference plists, known as |
| ; direct mode, when cfprefsd is inaccessible. This in-process access ensures |
| ; that our sandbox policy limits which preference domains can be accessed via |
| ; CFPreferences or NSUserDefaults. |
| (global-name "com.apple.cfprefsd.daemon") |
| ) |