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 <sys/reason.h> 108 class IOUserServer; 109 class OSUserMetaClass; 110 class OSObject; 111 class IODispatchQueue; 112 class IODispatchSource; 113 class IOInterruptDispatchSource; 114 class IOTimerDispatchSource; 115 class IOUserServerCheckInToken; 116 struct IOPStrings; 117 118 struct OSObjectUserVars { 119 IOUserServer * userServer; 120 OSBoundedArrayRef<IODispatchQueue *> queueArray; 121 OSUserMetaClass * userMeta; 122 OSArray * openProviders; 123 IOService * controllingDriver; 124 unsigned long willPowerState; 125 bool willTerminate; 126 bool didTerminate; 127 bool serverDied; 128 bool started; 129 bool stopped; 130 bool userServerPM; 131 bool willPower; 132 bool powerState; 133 bool resetPowerOnWake; 134 bool deferredRegisterService; 135 uint32_t powerOverride; 136 IOLock * uvarsLock; 137 }; 138 139 extern IOLock * gIOUserServerLock; 140 141 typedef struct ipc_kmsg * ipc_kmsg_t; 142 143 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 144 145 namespace IOServicePH 146 { 147 void serverAdd(IOUserServer * server); 148 void serverRemove(IOUserServer * server); 149 void serverAck(IOUserServer * server); 150 bool serverSlept(void); 151 void systemHalt(int howto); 152 bool checkPMReady(void); 153 }; 154 155 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 156 157 class IOUserServer : public IOUserClient2022 158 { 159 OSDeclareDefaultStructorsWithDispatch(IOUserServer); 160 161 IOLock * fLock; 162 IOSimpleLock * fInterruptLock; 163 OSDictionary * fEntitlements; 164 OSDictionary * fClasses; 165 IODispatchQueue * fRootQueue; 166 OSArray * fServices; 167 168 uint8_t fRootNotifier; 169 uint8_t fSystemPowerAck; 170 uint8_t fSystemOff; 171 IOUserServerCheckInToken * fCheckInToken; 172 OSDextStatistics * fStatistics; 173 bool fPlatformDriver; 174 OSString * fTeamIdentifier; 175 unsigned int fCSValidationCategory; 176 IOWorkLoop * fWorkLoop; 177 public: 178 kern_allocation_name_t fAllocationName; 179 task_t fOwningTask; 180 os_reason_t fTaskCrashReason; 181 182 public: 183 184 /* 185 * 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 186 * a pending dext launch with the same server name. 187 * 188 * 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. 189 */ 190 static IOUserServer * launchUserServer(OSString * bundleID, const OSSymbol * serverName, OSNumber * serverTag, bool reuseIfExists, IOUserServerCheckInToken ** token, OSData *serverDUI); 191 static IOUserClient * withTask(task_t owningTask); 192 virtual IOReturn clientClose(void) APPLE_KEXT_OVERRIDE; 193 virtual bool finalize(IOOptionBits options) APPLE_KEXT_OVERRIDE; 194 virtual void stop(IOService * provider) APPLE_KEXT_OVERRIDE; 195 virtual void free() APPLE_KEXT_OVERRIDE; 196 virtual IOWorkLoop * getWorkLoop() const APPLE_KEXT_OVERRIDE; 197 198 virtual IOReturn setProperties(OSObject * properties) APPLE_KEXT_OVERRIDE; 199 virtual IOReturn externalMethod(uint32_t selector, IOExternalMethodArgumentsOpaque * args) APPLE_KEXT_OVERRIDE; 200 static IOReturn externalMethodStart(OSObject * target, void * reference, IOExternalMethodArguments * arguments); 201 static IOReturn externalMethodRegisterClass(OSObject * target, void * reference, IOExternalMethodArguments * arguments); 202 203 virtual IOExternalTrap * getTargetAndTrapForIndex(IOService ** targetP, UInt32 index) APPLE_KEXT_OVERRIDE; 204 205 IOReturn serviceAttach(IOService * service, IOService * provider); 206 IOReturn serviceStop(IOService * service, IOService * provider); 207 void serviceFree(IOService * service); 208 IOReturn serviceStarted(IOService * service, IOService * provider, bool result); 209 static void serviceWillTerminate(IOService * client, IOService * provider, IOOptionBits options); 210 static void serviceDidTerminate(IOService * client, IOService * provider, IOOptionBits options, bool * defer); 211 static void serviceDidStop(IOService * client, IOService * provider); 212 IOReturn serviceOpen(IOService * provider, IOService * client); 213 IOReturn serviceClose(IOService * provider, IOService * client); 214 IOReturn serviceJoinPMTree(IOService * service); 215 IOReturn serviceSetPowerState(IOService * controllingDriver, IOService * service, IOPMPowerFlags flags, IOPMPowerStateIndex powerState); 216 IOReturn serviceNewUserClient(IOService * service, task_t owningTask, void * securityID, 217 uint32_t type, OSDictionary * properties, IOUserClient ** handler); 218 IOReturn serviceNewUserClient(IOService * service, task_t owningTask, void * securityID, 219 uint32_t type, OSDictionary * properties, OSSharedPtr<IOUserClient>& handler); 220 IOReturn exit(const char * reason); 221 IOReturn kill(const char * reason); 222 223 bool serviceMatchesCheckInToken(IOUserServerCheckInToken *token); 224 bool checkEntitlements(IOService * provider, IOService * dext); 225 bool checkEntitlements(LIBKERN_CONSUMED OSObject * prop, 226 IOService * provider, IOService * dext); 227 static bool checkEntitlements(OSDictionary * entitlements, LIBKERN_CONSUMED OSObject * prop, 228 IOService * provider, IOService * dext); 229 230 void setTaskLoadTag(OSKext *kext); 231 void setDriverKitUUID(OSKext *kext); 232 void setDriverKitStatistics(OSKext *kext); 233 IOReturn setCheckInToken(IOUserServerCheckInToken *token); 234 void systemPower(bool powerOff, bool hibernate); 235 void systemHalt(int howto); 236 static void powerSourceChanged(bool acAttached); 237 bool checkPMReady(); 238 239 IOReturn setPowerState(unsigned long state, IOService * service) APPLE_KEXT_OVERRIDE; 240 IOReturn powerStateWillChangeTo(IOPMPowerFlags flags, unsigned long state, IOService * service) APPLE_KEXT_OVERRIDE; 241 IOReturn powerStateDidChangeTo(IOPMPowerFlags flags, unsigned long state, IOService * service) APPLE_KEXT_OVERRIDE; 242 243 IOPStrings * copyInStringArray(const char * string, uint32_t userSize); 244 uint32_t stringArrayIndex(IOPStrings * array, const char * look); 245 IOReturn registerClass(OSClassDescription * desc, uint32_t size, OSUserMetaClass ** cls); 246 IOReturn registerClass(OSClassDescription * desc, uint32_t size, OSSharedPtr<OSUserMetaClass>& cls); 247 IOReturn setRootQueue(IODispatchQueue * queue); 248 249 OSObjectUserVars * varsForObject(OSObject * obj); 250 LIBKERN_RETURNS_NOT_RETAINED IODispatchQueue * queueForObject(OSObject * obj, uint64_t msgid); 251 252 static ipc_port_t copySendRightForObject(OSObject * object, natural_t /* ipc_kobject_type_t */ type); 253 static OSObject * copyObjectForSendRight(ipc_port_t port, natural_t /* ipc_kobject_type_t */ type); 254 255 IOReturn copyOutObjects(IORPCMessageMach * mach, IORPCMessage * message, 256 size_t size, bool consume); 257 IOReturn copyInObjects(IORPCMessageMach * mach, IORPCMessage * message, 258 size_t size, bool copyObjects, bool consumePorts); 259 260 IOReturn consumeObjects(IORPCMessageMach *mach, IORPCMessage * message, size_t messageSize); 261 262 IOReturn objectInstantiate(OSObject * obj, IORPC rpc, IORPCMessage * message); 263 IOReturn kernelDispatch(OSObject * obj, IORPC rpc); 264 static OSObject * target(OSAction * action, IORPCMessage * message); 265 266 IOReturn rpc(IORPC rpc); 267 IOReturn server(ipc_kmsg_t requestkmsg, IORPCMessage * message, ipc_kmsg_t * preply); 268 kern_return_t waitInterruptTrap(void * p1, void * p2, void * p3, void * p4, void * p5, void * p6); 269 static bool shouldLeakObjects(); 270 static void beginLeakingObjects(); 271 bool isPlatformDriver(); 272 int getCSValidationCategory(); 273 }; 274 275 typedef void (*IOUserServerCheckInCancellationHandler)(class IOUserServerCheckInToken*, void*); 276 277 // OSObject wrapper around IOUserServerCheckInCancellationHandler 278 class _IOUserServerCheckInCancellationHandler : public OSObject { 279 OSDeclareDefaultStructors(_IOUserServerCheckInCancellationHandler); 280 public: 281 static _IOUserServerCheckInCancellationHandler * 282 withHandler(IOUserServerCheckInCancellationHandler handler, void * args); 283 284 void call(IOUserServerCheckInToken * token); 285 private: 286 IOUserServerCheckInCancellationHandler fHandler; 287 void * fHandlerArgs; 288 }; 289 290 class IOUserServerCheckInToken : public OSObject 291 { 292 enum State { 293 kIOUserServerCheckInPending, 294 kIOUserServerCheckInCanceled, 295 kIOUserServerCheckInComplete, 296 }; 297 298 OSDeclareDefaultStructors(IOUserServerCheckInToken); 299 public: 300 virtual void free() APPLE_KEXT_OVERRIDE; 301 302 /* 303 * Cancel all pending dext launches. 304 */ 305 static void cancelAll(); 306 307 /* 308 * Set handler to be invoked when launch is cancelled. Returns an wrapper object for the handler to be released by the caller. 309 * The handler always runs under the lock for this IOUserServerCheckInToken. 310 * The returned object can be used with removeCancellationHandler(). 311 */ 312 _IOUserServerCheckInCancellationHandler * setCancellationHandler(IOUserServerCheckInCancellationHandler handler, void *handlerArgs); 313 314 /* 315 * Remove previously set cancellation handler. 316 */ 317 void removeCancellationHandler(_IOUserServerCheckInCancellationHandler * handler); 318 319 /* 320 * Cancel the launch 321 */ 322 void cancel(); 323 324 /* 325 * Mark launch as completed. 326 */ 327 IOReturn complete(); 328 329 const OSSymbol * copyServerName() const; 330 OSNumber * copyServerTag() const; 331 332 private: 333 static IOUserServerCheckInToken * findExistingToken(const OSSymbol * serverName); 334 bool init(const OSSymbol * userServerName, OSNumber * serverTag, OSKext *driverKext, OSData *serverDUI); 335 bool dextTerminate(void); 336 337 friend class IOUserServer; 338 339 340 341 private: 342 IOUserServerCheckInToken::State fState; 343 size_t fPendingCount; 344 const OSSymbol * fServerName; 345 const OSSymbol * fExecutableName; 346 OSNumber * fServerTag; 347 OSSet * fHandlers; 348 OSString * fKextBundleID; 349 bool fNeedDextDec; 350 }; 351 352 extern "C" kern_return_t 353 IOUserServerUEXTTrap(OSObject * object, void * p1, void * p2, void * p3, void * p4, void * p5, void * p6); 354 355 extern "C" void 356 IOUserServerRecordExitReason(task_t task, os_reason_t reason); 357 358 #endif /* XNU_KERNEL_PRIVATE */ 359 #endif /* _IOUSERSERVER_H */ 360