;;; Copyright (c) 2017 Apple Inc. All Rights reserved.
;;;
;;; WARNING: The sandbox rules in this file currently constitute
;;; Apple System Private Interface and are subject to change at any time and
;;; without notice.
;;;
;;; build with:
;;; sbutil compile -D HOME=${HOME} -D TMPDIR=${TMPDIR} -D DARWIN_CACHE_DIR=${HOME}/Library/Caches com.apple.fileproviderd.sb
(version 1)
(deny default)
(deny file-map-executable iokit-get-properties process-info* nvram*)
(deny dynamic-code-generation)
(import "system.sb")
(import "com.apple.corefoundation.sb")
(corefoundation)
;;; Homedir-relative path filters
(define (home-regex home-relative-regex)
  (regex (string-append "^" (regex-quote (param "HOME")) home-relative-regex)))
(define (home-subpath home-relative-subpath)
  (subpath (string-append (param "HOME") home-relative-subpath)))
(define (home-prefix home-relative-prefix)
  (prefix (string-append (param "HOME") home-relative-prefix)))
(define (home-literal home-relative-literal)
  (literal (string-append (param "HOME") home-relative-literal)))
(allow process-info* (target self))
;; UUID pattern matching stolen from AppSandbox/application.sb
;;; <rdar:
;;; UUID of the form: XXXXXXXX-XXXX-XXXX--XXXX-XXXXXXXXXXXX
;;; That's 8X-4X-4X-4X-12X; where X = "[0-9A-F]", length(X) = 8
;;; Return a regex string which matches capital hex digit patterns
;;; pattern descriptor is an list of integers where the element specifies the repeat
;;; count of the hex digit; 0 means insert a dash
;;; You can paste these functions into: https:
(define (HEX-pattern-match-generator pattern-descriptor)
    (letrec ((pattern-string ""))
        (for-each (lambda (repeat-count)
            (if (zero? repeat-count)
                (set! pattern-string (string-append pattern-string "-"))
                (let appender ((count repeat-count))
                    (if (> count 0)
                        (begin
                            (set! pattern-string (string-append pattern-string "[0-9A-F]"))
                            (appender (- count 1)))))))
        pattern-descriptor)
    pattern-string)
)
;; return a regex pattern matching string for 8-4-4-4-12 UUIDs:
(define (uuid-HEX-pattern-match-string)
(HEX-pattern-match-generator '(8 0 4 0 4 0 4 0 12)))
;; global to hold the computed UUID matching pattern.
(define *uuid-pattern* "")
(define (uuid-regex-string)
       (if (zero? (string-length *uuid-pattern*))
              (set! *uuid-pattern* (uuid-HEX-pattern-match-string)))
       *uuid-pattern*
)
;; root when running in enterprise persona context
(define (enterprise-context-root)
       (regex (string-append "^/Volumes/" (uuid-regex-string) "(/|$)"))
)
(define (enterprise-context-tmp)
       (regex (string-append "^/Volumes/" (uuid-regex-string) #"/tmp/com.apple.fileproviderd(/|$)"))
)
(define (enterprise-context-library)
       (regex (string-append "^/Volumes/" (uuid-regex-string) #"/Library/Application Support/FileProvider(/|$)"))
)
;; For resolving symlinks, realpath(3), and equivalents.
(allow file-read-metadata)
;; For validating the entitlements of clients.
(allow process-info-codesignature)
;; for killing runaway extensions. Remove if we move macOS to runningboard
 (allow signal (target others))
;; Read/write access to a temporary directory.
(allow file-read* file-write*
       (enterprise-context-tmp)
       (subpath (param "TMPDIR"))
       (subpath (param "DARWIN_CACHE_DIR"))
       (subpath (param "DARWIN_TEMP_DIR"))
       (extension "com.apple.app-sandbox.read-write")
       (extension "com.apple.app-sandbox.read")
       (mount-relative-regex #"^/\.DocumentRevisions-V100($|/)")
)
;; Allow read-only access to $HOME/Library/Trial
(allow file-read*
    (home-subpath "/Library/Trial"))
;; MDM disallow of extensions
(allow file-read*
    (subpath "/private/var/db/ConfigurationProfiles/Settings/com.apple.managed.PlugInKit.plist"))
(allow file-read*
;; CP_ManagedAppsIsAppManagedAtURL to determine MDM status of apps
        (subpath "/var/db/ConfigurationProfiles/Settings")
)
(allow file-read*
       (extension "com.apple.app-sandbox.read")
)
;; issue extensions for alternate file contents in iWork container
(let ((extension-path-filter
    (require-any
       (home-regex (string-append "/Containers/Data/[^/]+/[^/]+/Library/Application Support/Collaboration/com.apple.iWork/"))
       (subpath (param "TMPDIR")))))
  (allow file-issue-extension
    (require-all
      (extension-class "com.apple.app-sandbox.read-write")
       extension-path-filter)))
(allow mach-lookup
    (global-name "com.apple.DesktopServicesHelper")
    (global-name "com.apple.CoreServices.coreservicesd")
    (global-name "com.apple.ProgressReporting")
    (global-name "com.apple.FileCoordination")
    (global-name "com.apple.cache_delete")
    (global-name "com.apple.spaceattributiond")
    (global-name "com.apple.distributed_notifications@Uv3")
    (global-name "com.apple.lsd.mapdb")
    (global-name "com.apple.lsd.modifydb")
    (global-name "com.apple.lsd.xpc")
    (global-name "com.apple.pluginkit.pkd")
    (global-name "com.apple.runningboard")
    (global-name "com.apple.revisiond")
    (global-name "com.apple.lsd.advertisingidentifiers")
    (global-name "com.apple.CoreAuthentication.agent")
    ;; we're soft-linking CoreSpotlight, otherwise we'd get these automatically
    (global-name "com.apple.spotlight.IndexAgent")
    (global-name "com.apple.spotlight.IndexDelegateAgent")
    (global-name "com.apple.spotlight.SearchAgent")
    (global-name "com.apple.metadata.mds")
    (global-name "com.apple.FSEvents")
    (global-name "com.apple.coreservices.quarantine-resolver")
    (global-name "com.apple.coresymbolicationd")
    (global-name "com.apple.apsd") ;; PKPushRegistry
    (global-name "com.apple.SystemConfiguration.configd") ;; PKPushRegistry
    (global-name "com.apple.windowserver.active") ;; PKPushRegistry
    (global-name "com.apple.scopedbookmarksagent.xpc")
    (global-name "com.apple.UNCUserNotification")
    (global-name "com.apple.coreservices.launchservicesd")
    (global-name "com.apple.iconservices")
    (global-name "com.apple.analyticsd")
    (global-name "com.apple.sandboxd")
    (global-name "com.apple.cloudd")
    (global-name "com.apple.mobile.keybagd.xpc")
    (global-name "com.apple.dock.fullscreen")
    (global-name "com.apple.CoreDisplay.master")
    (global-name "com.apple.fonts")
    (global-name "com.apple.containermanagerd")
    (global-name "com.apple.mdmclient.agent.unrestricted") ;; CP_ManagedAppsIsAppManagedAtURL
    (global-name "com.apple.mobile.keybagd.UserManager.xpc")
    (global-name "com.apple.mobile.usermanagerd.xpc")
    (global-name "com.apple.rtcreportingd")
    (global-name "com.apple.cache_delete.public")
    (global-name "com.apple.symptom_diagnostics")
    (global-name "com.apple.DiskArbitration.diskarbitrationd")
    (global-name "com.apple.quicklook.ThumbnailsAgent") ;; QuickLook for thumbnails
    (global-name "com.apple.TapToRadarKit.service") ;; TTR
    (global-name "com.apple.OTATaskingAgent")
    (global-name "com.apple.duetactivityscheduler")
    (global-name "com.apple.system.opendirectoryd.api") ;; MDM disallow of extensions
    (global-name "com.apple.securityd.xpc") ;; Keychain access for Ebihil signature
    (global-name "com.apple.tccd.system")
    (global-name "com.apple.tccd")
    (global-name "com.apple.CoreAuthentication.agent.libxpc")
)
(allow process-info-dirtycontrol
    (target self))
;; for logging client names
(allow process-info-pidinfo)
(allow user-preference*
    (preference-domain "com.apple.fileproviderd")
    (preference-domain "com.apple.iclouddrive.features"))
;; Alias for .GlobalPreferences
(allow user-preference-read (preference-domain "kCFPreferencesAnyApplication"))
(allow sysctl-write
;; used by fpfs_enable_vnode_rapid_aging
    (sysctl-name "kern.rage_vnode"))
(allow file-read* file-write*
    ;; We need to be able to create items in the home folder
    (home-subpath "/")
    (enterprise-context-root)
)
(define home-path-blacklist
    (require-any
        ;; Blacklist dot files
        (home-regex #"/\..*")
        ;; Blacklist usual system folders
        ;; rdar:
        ;(home-subpath "/Applications/")
        ;(home-subpath "/Downloads/")
        ;(home-subpath "/Library/")
        ;(home-subpath "/Movies/")
        ;(home-subpath "/Pictures/")
        ;(home-subpath "/Public/")
        ;(home-subpath "/local/")
    )
)
(deny file-read* file-write*
    home-path-blacklist
)
(define (multivolume-store-paths)
    (require-any
        (mount-relative-regex #"^/\.CloudStorage($|/)")
        (mount-relative-regex #"^/\.TemporaryItems($|/)")
    )
)
;; this comes /after/ home-path-blacklist so that the "Blacklist dot files" doesn't take precedence
(allow file-read* file-write*
    (multivolume-store-paths)
)
;; For managing Ebihil root exposure symlinks
(allow file-read* file-write*
    (mount-relative-literal "/")
    ;; Applies to all symlinks in volume root, but not in subdirs
    (require-all
        (vnode-type SYMLINK)
        (mount-relative-regex #"^/[^/]+$")
    )
)
(allow file-read* file-write*
 (home-subpath "/Library/FileProvider")
    (home-subpath "/Library/CloudStorage")
    (home-subpath "/Library/Application Support/FileProvider")
    (home-subpath "/Library/Mobile Documents")
    (home-subpath "/Desktop")
    (home-subpath "/Documents")
    (home-subpath "/.DS_Nested_Desktop_Documents")
    (enterprise-context-library)
)
(allow file-issue-extension
    (require-all
        (extension-class "com.apple.app-sandbox.read-write")
        (require-any
            (home-subpath "/Library/CloudStorage")
            (home-subpath "/Library/Application Support/FileProvider")
            (home-subpath "/Library/Mobile Documents")
            (home-subpath "/")
        )
    )
;; Re-issue file extension from our security app-scoped bookmark to the root of
;; the provider.
    (require-all
        (extension-class "com.apple.app-sandbox.read-write")
        (extension-class "com.apple.app-sandbox.read-write")
    )
    (multivolume-store-paths)
)
(allow file-issue-extension
    (require-all
        (extension-class "com.apple.app-sandbox.read")
        (require-any
            (home-subpath "/Library/CloudStorage")
            (home-subpath "/Library/Application Support/FileProvider")
            (home-subpath "/Library/Mobile Documents")
            (home-subpath "/")
            (mount-relative-regex #"^/\.DocumentRevisions-V100($|/)")
)))
(deny file-issue-extension
    (require-all
        (extension-class "com.apple.app-sandbox.read-write")
        (require-any
            home-path-blacklist
        ))
)
(deny file-issue-extension
    (require-all
        (extension-class "com.apple.app-sandbox.read")
        (require-any
            home-path-blacklist
        ))
)
;; observing ~/Library/FileProvider/CloudStorage also tries to read all parents
(allow file-read-data
    (home-literal "/Library")
    (literal (param "HOME"))
    (literal "/Users")
    (literal "/Volumes")
    (mount-relative-literal "/")
)
(allow system-fsctl
    (fsctl-command
        APFSIOC_GET_DIR_STATS_EXT
        APFSIOC_GET_PURGEABLE_FILE_FLAGS
        APFSIOC_MAINTAIN_DIR_STATS
        APFSIOC_MAKE_OBJECT_DATALESS
        APFSIOC_MARK_PURGEABLE
        APFSIOC_SHARE_RANGE
        APFSIOC_SYNC_ROOT_GET_FLAG
        APFSIOC_SYNC_ROOT_SET_FLAG
        FSIOC_CAS_BSDFLAGS
        HFSIOC_TRANSFER_DOCUMENT_ID ;; used in fpfs_transfer_document_id
        APFSIOC_MARK_PURGEABLE_EXT
        APFSIOC_REVOKE_CHILDREN
        APFSIOC_PURGE_SINGLE_FILE
        APFSIOC_DOC_ID_TO_FILE_ID
        APFSIOC_PURGEABLE_GET_FILE_INFO
        APFSIOC_PURGEABLE_GET_DETAILED_STATS
        APFSIOC_GET_SPEC_TELEM
        APFSIOC_OBJECT_UNSET_DATALESS
        APFSIOC_PURGEABLE_LABEL_PURGEABLE
    )
)
;; Package detection
(if (defined? 'system-package-check)
    (allow system-package-check)
)
;; _CSCreateSeed, used for some obscure LSPrefs purposes
(allow ipc-posix-shm-write-create
    (ipc-posix-name-regex #"^/tmp/com.apple.csseed.[0-9]+$"))
(allow ipc-posix-shm-write-data
    (ipc-posix-name-regex #"^/tmp/com.apple.csseed.[0-9]+$"))
(allow ipc-posix-shm-read-data
    (ipc-posix-name-regex #"^/tmp/com.apple.csseed.[0-9]+$"))
;; secure LS preferences
(allow file-read-data
    (home-literal "/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist"))
;; reading the CoreStorage encrypted status
(with-filter (iokit-registry-entry-class "CoreStorageLogical")
    (allow iokit-get-properties))
;; Radar-Id: rdar:
(with-filter (iokit-registry-entry-class "AppleAPFSUserClient")
    (allow iokit-get-properties))
;; Radar-Id: rdar:
(allow iokit-open (iokit-user-client-class "AppleAPFSUserClient"))
;; read volume role for multi-volume support w/ FPFS
(with-filter (iokit-registry-entry-class "AppleAPFSVolume")
    (allow iokit-get-properties))
(with-filter (iokit-registry-entry-class "AppleAPFSVolumeBSDClient")
    (allow iokit-get-properties))
;; read device serial number through MobileGestalt
(with-filter (iokit-registry-entry-class "IOPlatformExpertDevice")
    (allow iokit-get-properties
           (iokit-property "IOPlatformSerialNumber")
    )
)
(allow file-read*
    (subpath "/Library/Application Support/CrashReporter")
)
;; rdar:
(allow file-map-executable
    (literal "/System/Library/CoreServices/ManagedClient.app/Contents/PlugIns/MCXToolsInterface.bundle/Contents/MacOS/MCXToolsInterface")
)
(allow lsopen)
;; allow DSHelper to show the root authentication alert for us (rdar:
(allow authorization-right-obtain
       (right-name "com.apple.desktopservices"))
