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