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 static bool checkEntitlements(OSDictionary * entitlements, LIBKERN_CONSUMED OSObject * prop, 224 IOService * provider, IOService * dext); 225 226 void setTaskLoadTag(OSKext *kext); 227 void setDriverKitUUID(OSKext *kext); 228 void setDriverKitStatistics(OSKext *kext); 229 void setCheckInToken(IOUserServerCheckInToken *token); 230 void systemPower(bool powerOff); 231 void systemHalt(int howto); 232 static void powerSourceChanged(bool acAttached); 233 234 IOReturn setPowerState(unsigned long state, IOService * service) APPLE_KEXT_OVERRIDE; 235 IOReturn powerStateWillChangeTo(IOPMPowerFlags flags, unsigned long state, IOService * service) APPLE_KEXT_OVERRIDE; 236 IOReturn powerStateDidChangeTo(IOPMPowerFlags flags, unsigned long state, IOService * service) APPLE_KEXT_OVERRIDE; 237 void setPowerManagementFailed(bool failed); 238 239 IOPStrings * copyInStringArray(const char * string, uint32_t userSize); 240 uint32_t stringArrayIndex(IOPStrings * array, const char * look); 241 IOReturn registerClass(OSClassDescription * desc, uint32_t size, OSUserMetaClass ** cls); 242 IOReturn registerClass(OSClassDescription * desc, uint32_t size, OSSharedPtr<OSUserMetaClass>& cls); 243 IOReturn setRootQueue(IODispatchQueue * queue); 244 245 OSObjectUserVars * varsForObject(OSObject * obj); 246 LIBKERN_RETURNS_NOT_RETAINED IODispatchQueue * queueForObject(OSObject * obj, uint64_t msgid); 247 248 static ipc_port_t copySendRightForObject(OSObject * object, natural_t /* ipc_kobject_type_t */ type); 249 static OSObject * copyObjectForSendRight(ipc_port_t port, natural_t /* ipc_kobject_type_t */ type); 250 251 IOReturn copyOutObjects(IORPCMessageMach * mach, IORPCMessage * message, 252 size_t size, bool consume); 253 IOReturn copyInObjects(IORPCMessageMach * mach, IORPCMessage * message, 254 size_t size, bool copyObjects, bool consumePorts); 255 256 IOReturn consumeObjects(IORPCMessage * message, size_t messageSize); 257 258 IOReturn objectInstantiate(OSObject * obj, IORPC rpc, IORPCMessage * message); 259 IOReturn kernelDispatch(OSObject * obj, IORPC rpc); 260 static OSObject * target(OSAction * action, IORPCMessage * message); 261 262 IOReturn rpc(IORPC rpc); 263 IOReturn server(ipc_kmsg_t requestkmsg, ipc_kmsg_t * preply); 264 kern_return_t waitInterruptTrap(void * p1, void * p2, void * p3, void * p4, void * p5, void * p6); 265 static bool shouldLeakObjects(); 266 static void beginLeakingObjects(); 267 bool isPlatformDriver(); 268 int getCSValidationCategory(); 269 }; 270 271 typedef void (*IOUserServerCheckInCancellationHandler)(class IOUserServerCheckInToken*, void*); 272 273 // OSObject wrapper around IOUserServerCheckInCancellationHandler 274 class _IOUserServerCheckInCancellationHandler : public OSObject { 275 OSDeclareDefaultStructors(_IOUserServerCheckInCancellationHandler); 276 public: 277 static _IOUserServerCheckInCancellationHandler * 278 withHandler(IOUserServerCheckInCancellationHandler handler, void * args); 279 280 void call(IOUserServerCheckInToken * token); 281 private: 282 IOUserServerCheckInCancellationHandler fHandler; 283 void * fHandlerArgs; 284 }; 285 286 class IOUserServerCheckInToken : public OSObject 287 { 288 enum State { 289 kIOUserServerCheckInPending, 290 kIOUserServerCheckInCanceled, 291 kIOUserServerCheckInComplete, 292 }; 293 294 OSDeclareDefaultStructors(IOUserServerCheckInToken); 295 public: 296 virtual void free() APPLE_KEXT_OVERRIDE; 297 298 /* 299 * Cancel all pending dext launches. 300 */ 301 static void cancelAll(); 302 303 /* 304 * Set handler to be invoked when launch is cancelled. Returns an wrapper object for the handler to be released by the caller. 305 * The handler always runs under the lock for this IOUserServerCheckInToken. 306 * The returned object can be used with removeCancellationHandler(). 307 */ 308 _IOUserServerCheckInCancellationHandler * setCancellationHandler(IOUserServerCheckInCancellationHandler handler, void *handlerArgs); 309 310 /* 311 * Remove previously set cancellation handler. 312 */ 313 void removeCancellationHandler(_IOUserServerCheckInCancellationHandler * handler); 314 315 /* 316 * Cancel the launch 317 */ 318 void cancel(); 319 320 /* 321 * Mark launch as completed. 322 */ 323 void complete(); 324 325 const OSSymbol * copyServerName() const; 326 OSNumber * copyServerTag() const; 327 328 private: 329 static IOUserServerCheckInToken * findExistingToken(const OSSymbol * serverName); 330 bool init(const OSSymbol * userServerName, OSNumber * serverTag, OSKext *driverKext, OSData *serverDUI); 331 bool dextTerminate(void); 332 333 friend class IOUserServer; 334 335 336 337 private: 338 IOUserServerCheckInToken::State fState; 339 size_t fPendingCount; 340 const OSSymbol * fServerName; 341 OSNumber * fServerTag; 342 OSSet * fHandlers; 343 OSString * fKextBundleID; 344 bool fNeedDextDec; 345 }; 346 347 extern "C" kern_return_t 348 IOUserServerUEXTTrap(OSObject * object, void * p1, void * p2, void * p3, void * p4, void * p5, void * p6); 349 350 extern "C" void 351 IOUserServerRecordExitReason(task_t task, os_reason_t reason); 352 353 #endif /* XNU_KERNEL_PRIVATE */ 354 #endif /* _IOUSERSERVER_H */ 355