1 /* 2 * Copyright (c) 2019 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29 30 #ifndef _IOUSERSERVER_H 31 #define _IOUSERSERVER_H 32 33 #include <IOKit/IORPC.h> 34 35 #define kIOUserServerClassKey "IOUserServer" 36 #define kIOUserServerNameKey "IOUserServerName" 37 #define kIOUserServerTagKey "IOUserServerTag" 38 // the expected cdhash value of the userspace driver executable 39 #define kIOUserServerCDHashKey "IOUserServerCDHash" 40 41 #if DRIVERKIT_PRIVATE 42 43 enum{ 44 kIOKitUserServerClientType = 0x99000003, 45 }; 46 47 enum{ 48 kIOUserServerMethodRegisterClass = 0x0001000, 49 kIOUserServerMethodStart = 0x0001001, 50 kIOUserServerMethodRegister = 0x0001002, 51 }; 52 53 54 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 55 56 #define OSObject_Instantiate_ID 0x0000000100000001ULL 57 58 enum { 59 kOSObjectRPCRemote = 0x00000001, 60 kOSObjectRPCKernel = 0x00000002, 61 }; 62 63 struct OSObject_Instantiate_Msg_Content { 64 IORPCMessage __hdr; 65 OSObjectRef __object; 66 }; 67 68 #pragma pack(push, 4) 69 struct OSObject_Instantiate_Rpl_Content { 70 IORPCMessage __hdr; 71 kern_return_t __result; 72 uint32_t __pad; 73 uint64_t flags; 74 char classname[128]; 75 uint64_t methods[0]; 76 }; 77 #pragma pack(pop) 78 79 #pragma pack(4) 80 struct OSObject_Instantiate_Msg { 81 IORPCMessageMach mach; 82 mach_msg_port_descriptor_t __object__descriptor; 83 OSObject_Instantiate_Msg_Content content; 84 }; 85 struct OSObject_Instantiate_Rpl { 86 IORPCMessageMach mach; 87 OSObject_Instantiate_Rpl_Content content; 88 }; 89 #pragma pack() 90 91 typedef uint64_t IOTrapMessageBuffer[256]; 92 93 #endif /* DRIVERKIT_PRIVATE */ 94 95 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 96 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 97 98 #ifdef XNU_KERNEL_PRIVATE 99 100 #include <IOKit/IOService.h> 101 #include <IOKit/IOUserClient.h> 102 #include <DriverKit/IOUserServer.h> 103 #include <libkern/c++/OSPtr.h> 104 #include <libkern/c++/OSKext.h> 105 #include <libkern/c++/OSBoundedArray.h> 106 #include <libkern/c++/OSBoundedArrayRef.h> 107 #include <kern/ipc_kobject.h> 108 #include <sys/reason.h> 109 class IOUserServer; 110 class OSUserMetaClass; 111 class OSObject; 112 class IODispatchQueue; 113 class IODispatchSource; 114 class IOInterruptDispatchSource; 115 class IOTimerDispatchSource; 116 class IOUserServerCheckInToken; 117 struct IOPStrings; 118 119 struct OSObjectUserVars { 120 IOUserServer * userServer; 121 OSBoundedArrayRef<IODispatchQueue *> queueArray; 122 OSUserMetaClass * userMeta; 123 OSArray * openProviders; 124 IOService * controllingDriver; 125 unsigned long willPowerState; 126 bool willTerminate; 127 bool didTerminate; 128 bool serverDied; 129 bool instantiated; 130 bool started; 131 bool stopped; 132 bool needStop; 133 bool userServerPM; 134 bool willPower; 135 bool powerState; 136 bool resetPowerOnWake; 137 bool deferredRegisterService; 138 uint32_t powerOverride; 139 IOLock * uvarsLock; 140 OSDictionary * originalProperties; 141 OSArray * pmAssertions; 142 OSArray * pmAssertionsSynced; 143 }; 144 145 extern IOLock * gIOUserServerLock; 146 147 typedef struct ipc_kmsg * ipc_kmsg_t; 148 149 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 150 151 namespace IOServicePH 152 { 153 void serverAdd(IOUserServer * server); 154 void serverRemove(IOUserServer * server); 155 void serverAck(IOUserServer * server); 156 bool serverSlept(void); 157 void systemHalt(int howto); 158 bool checkPMReady(void); 159 }; 160 161 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 162 163 class IOUserServer : public IOUserClient2022 164 { 165 OSDeclareDefaultStructorsWithDispatch(IOUserServer); 166 167 IOLock * fLock; 168 IOSimpleLock * fInterruptLock; 169 OSDictionary * fEntitlements; 170 OSDictionary * fClasses; 171 IODispatchQueue * fRootQueue; 172 OSArray * fServices; 173 174 uint8_t fRootNotifier; 175 uint8_t fSystemPowerAck; 176 uint8_t fSystemOff; 177 IOUserServerCheckInToken * fCheckInToken; 178 OSDextStatistics * fStatistics; 179 bool fPlatformDriver; 180 OSString * fTeamIdentifier; 181 unsigned int fCSValidationCategory; 182 IOWorkLoop * fWorkLoop; 183 public: 184 kern_allocation_name_t fAllocationName; 185 task_t fOwningTask; 186 os_reason_t fTaskCrashReason; 187 bool fPageout; 188 bool fSuspended; 189 bool fAOTAllow; 190 bool fSystemOffPhase2Allow; 191 192 public: 193 194 /* 195 * Launch a dext with the specified bundle ID, server name, and server tag. If reuseIfExists is true, this will attempt to find an existing IOUserServer instance or 196 * a pending dext launch with the same server name. 197 * 198 * Returns a IOUserServer instance if one was found, or a token to track the pending dext launch. If both are NULL, then launching the dext failed. 199 */ 200 static IOUserServer * launchUserServer(IOService * provider, OSString * bundleID, const OSSymbol * serverName, OSNumber * serverTag, bool reuseIfExists, IOUserServerCheckInToken ** token, OSData *serverDUI); 201 static IOUserClient * withTask(task_t owningTask); 202 virtual IOReturn clientClose(void) APPLE_KEXT_OVERRIDE; 203 virtual bool finalize(IOOptionBits options) APPLE_KEXT_OVERRIDE; 204 virtual void stop(IOService * provider) APPLE_KEXT_OVERRIDE; 205 virtual void free() APPLE_KEXT_OVERRIDE; 206 virtual IOWorkLoop * getWorkLoop() const APPLE_KEXT_OVERRIDE; 207 208 virtual IOReturn setProperties(OSObject * properties) APPLE_KEXT_OVERRIDE; 209 virtual IOReturn externalMethod(uint32_t selector, IOExternalMethodArgumentsOpaque * args) APPLE_KEXT_OVERRIDE; 210 static IOReturn externalMethodStart(OSObject * target, void * reference, IOExternalMethodArguments * arguments); 211 static IOReturn externalMethodRegisterClass(OSObject * target, void * reference, IOExternalMethodArguments * arguments); 212 213 virtual IOExternalTrap * getTargetAndTrapForIndex(IOService ** targetP, UInt32 index) APPLE_KEXT_OVERRIDE; 214 215 IOReturn serviceAttach(IOService * service, IOService * provider); 216 IOReturn serviceStop(IOService * service, IOService * provider); 217 void serviceFree(IOService * service); 218 IOReturn serviceStarted(IOService * service, IOService * provider, bool result); 219 static void serviceWillTerminate(IOService * client, IOService * provider, IOOptionBits options); 220 static void serviceDidTerminate(IOService * client, IOService * provider, IOOptionBits options, bool * defer); 221 static void serviceDidStop(IOService * client, IOService * provider); 222 IOReturn serviceOpen(IOService * provider, IOService * client); 223 IOReturn serviceClose(IOService * provider, IOService * client); 224 IOReturn serviceJoinPMTree(IOService * service); 225 IOReturn serviceSetPowerState(IOService * controllingDriver, IOService * service, IOPMPowerFlags flags, IOPMPowerStateIndex powerState); 226 IOReturn serviceCreatePMAssertion(IOService * service, uint32_t assertionBits, uint64_t * assertionID, bool synced); 227 IOReturn serviceReleasePMAssertion(IOService * service, uint64_t assertionID); 228 IOReturn serviceNewUserClient(IOService * service, task_t owningTask, void * securityID, 229 uint32_t type, OSDictionary * properties, IOUserClient ** handler); 230 IOReturn serviceNewUserClient(IOService * service, task_t owningTask, void * securityID, 231 uint32_t type, OSDictionary * properties, OSSharedPtr<IOUserClient>& handler); 232 IOReturn exit(const char * reason); 233 IOReturn kill(const char * reason); 234 void serverAck(void); 235 236 bool serviceMatchesCheckInToken(IOUserServerCheckInToken *token); 237 bool checkEntitlements(IOService * provider, IOService * dext); 238 bool checkEntitlements(LIBKERN_CONSUMED OSObject * prop, 239 IOService * provider, IOService * dext); 240 static bool checkEntitlements(OSDictionary * entitlements, LIBKERN_CONSUMED OSObject * prop, 241 IOService * provider, IOService * dext); 242 243 void setTaskLoadTag(OSKext *kext); 244 void setDriverKitUUID(OSKext *kext); 245 void setDriverKitStatistics(OSKext *kext); 246 IOReturn setCheckInToken(IOUserServerCheckInToken *token); 247 void systemPower(uint8_t systemState, bool hibernate); 248 void systemSuspend(void); 249 void systemHalt(int howto); 250 static void powerSourceChanged(bool acAttached); 251 bool checkPMReady(); 252 253 IOReturn setPowerState(unsigned long state, IOService * service) APPLE_KEXT_OVERRIDE; 254 IOReturn powerStateWillChangeTo(IOPMPowerFlags flags, unsigned long state, IOService * service) APPLE_KEXT_OVERRIDE; 255 IOReturn powerStateDidChangeTo(IOPMPowerFlags flags, unsigned long state, IOService * service) APPLE_KEXT_OVERRIDE; 256 257 IOPStrings * copyInStringArray(const char * string, uint32_t userSize); 258 uint32_t stringArrayIndex(IOPStrings * array, const char * look); 259 IOReturn registerClass(OSClassDescription * desc, uint32_t size, OSUserMetaClass ** cls); 260 IOReturn registerClass(OSClassDescription * desc, uint32_t size, OSSharedPtr<OSUserMetaClass>& cls); 261 IOReturn setRootQueue(IODispatchQueue * queue); 262 263 OSObjectUserVars * varsForObject(OSObject * obj); 264 LIBKERN_RETURNS_NOT_RETAINED IODispatchQueue * queueForObject(OSObject * obj, uint64_t msgid); 265 266 static ipc_port_t copySendRightForObject(OSObject * object, ipc_kobject_type_t type); 267 static OSObject * copyObjectForSendRight(ipc_port_t port, ipc_kobject_type_t type); 268 269 IOReturn copyOutObjects(IORPCMessageMach * mach, IORPCMessage * message, 270 size_t size, bool consume); 271 IOReturn copyInObjects(IORPCMessageMach * mach, IORPCMessage * message, 272 size_t size, bool copyObjects, bool consumePorts); 273 274 IOReturn consumeObjects(IORPCMessageMach *mach, IORPCMessage * message, size_t messageSize); 275 276 IOReturn objectInstantiate(OSObject * obj, IORPC rpc, IORPCMessage * message); 277 IOReturn kernelDispatch(OSObject * obj, IORPC rpc); 278 static OSObject * target(OSAction * action, IORPCMessage * message); 279 280 IOReturn rpc(IORPC rpc); 281 IOReturn server(ipc_kmsg_t requestkmsg, IORPCMessage * message, ipc_kmsg_t * preply); 282 kern_return_t waitInterruptTrap(void * p1, void * p2, void * p3, void * p4, void * p5, void * p6); 283 static bool shouldLeakObjects(); 284 static void beginLeakingObjects(); 285 bool isPlatformDriver(); 286 int getCSValidationCategory(); 287 void pageout(); 288 }; 289 290 typedef void (*IOUserServerCheckInCancellationHandler)(class IOUserServerCheckInToken*, void*); 291 292 // OSObject wrapper around IOUserServerCheckInCancellationHandler 293 class _IOUserServerCheckInCancellationHandler : public OSObject { 294 OSDeclareDefaultStructors(_IOUserServerCheckInCancellationHandler); 295 public: 296 static _IOUserServerCheckInCancellationHandler * 297 withHandler(IOUserServerCheckInCancellationHandler handler, void * args); 298 299 void call(IOUserServerCheckInToken * token); 300 private: 301 IOUserServerCheckInCancellationHandler fHandler; 302 void * fHandlerArgs; 303 }; 304 305 class IOUserServerCheckInToken : public OSObject 306 { 307 enum State { 308 kIOUserServerCheckInPending, 309 kIOUserServerCheckInCanceled, 310 kIOUserServerCheckInComplete, 311 }; 312 313 OSDeclareDefaultStructors(IOUserServerCheckInToken); 314 public: 315 virtual void free() APPLE_KEXT_OVERRIDE; 316 317 /* 318 * Cancel all pending dext launches. 319 */ 320 static void cancelAll(); 321 322 /* 323 * Set handler to be invoked when launch is cancelled. Returns an wrapper object for the handler to be released by the caller. 324 * The handler always runs under the lock for this IOUserServerCheckInToken. 325 * The returned object can be used with removeCancellationHandler(). 326 */ 327 _IOUserServerCheckInCancellationHandler * setCancellationHandler(IOUserServerCheckInCancellationHandler handler, void *handlerArgs); 328 329 /* 330 * Remove previously set cancellation handler. 331 */ 332 void removeCancellationHandler(_IOUserServerCheckInCancellationHandler * handler); 333 334 /* 335 * Cancel the launch 336 */ 337 void cancel(); 338 339 /* 340 * Mark launch as completed. 341 */ 342 IOReturn complete(); 343 344 const OSSymbol * copyServerName() const; 345 OSNumber * copyServerTag() const; 346 347 private: 348 static IOUserServerCheckInToken * findExistingToken(const OSSymbol * serverName); 349 bool init(const OSSymbol * userServerName, OSNumber * serverTag, OSKext *driverKext, OSData *serverDUI); 350 bool dextTerminate(void); 351 352 friend class IOUserServer; 353 354 355 356 private: 357 IOUserServerCheckInToken::State fState; 358 const OSSymbol * fServerName; 359 const OSSymbol * fExecutableName; 360 OSNumber * fServerTag; 361 OSSet * fHandlers; 362 OSString * fKextBundleID; 363 bool fNeedDextDec; 364 }; 365 366 extern "C" kern_return_t 367 IOUserServerUEXTTrap(OSObject * object, void * p1, void * p2, void * p3, void * p4, void * p5, void * p6); 368 369 extern "C" void 370 IOUserServerRecordExitReason(task_t task, os_reason_t reason); 371 372 class IOUserUserClient : public IOUserClient 373 { 374 OSDeclareDefaultStructors(IOUserUserClient); 375 public: 376 task_t fTask; 377 OSDictionary * fWorkGroups; 378 OSDictionary * fEventLinks; 379 IOLock * fLock; 380 381 IOReturn setTask(task_t task); 382 IOReturn eventlinkConfigurationTrap(void * p1, void * p2, void * p3, void * p4, void * p5, void * p6); 383 IOReturn workgroupConfigurationTrap(void * p1, void * p2, void * p3, void * p4, void * p5, void * p6); 384 385 virtual bool init( OSDictionary * dictionary ) APPLE_KEXT_OVERRIDE; 386 virtual void free() APPLE_KEXT_OVERRIDE; 387 virtual void stop(IOService * provider) APPLE_KEXT_OVERRIDE; 388 virtual IOReturn clientClose(void) APPLE_KEXT_OVERRIDE; 389 virtual IOReturn setProperties(OSObject * properties) APPLE_KEXT_OVERRIDE; 390 virtual IOReturn externalMethod(uint32_t selector, IOExternalMethodArguments * args, 391 IOExternalMethodDispatch * dispatch, OSObject * target, void * reference) APPLE_KEXT_OVERRIDE; 392 virtual IOReturn clientMemoryForType(UInt32 type, 393 IOOptionBits * options, 394 IOMemoryDescriptor ** memory) APPLE_KEXT_OVERRIDE; 395 virtual IOExternalTrap * getTargetAndTrapForIndex( IOService **targetP, UInt32 index ) APPLE_KEXT_OVERRIDE; 396 }; 397 398 #endif /* XNU_KERNEL_PRIVATE */ 399 #endif /* _IOUSERSERVER_H */ 400