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 kIOUserClassKey "IOUserClass" 36 #define kIOUserServerClassKey "IOUserServer" 37 #define kIOUserServerNameKey "IOUserServerName" 38 #define kIOUserServerTagKey "IOUserServerTag" 39 // the expected cdhash value of the userspace driver executable 40 #define kIOUserServerCDHashKey "IOUserServerCDHash" 41 42 #if DRIVERKIT_PRIVATE 43 44 enum{ 45 kIOKitUserServerClientType = 0x99000003, 46 }; 47 48 enum{ 49 kIOUserServerMethodRegisterClass = 0x0001000, 50 kIOUserServerMethodStart = 0x0001001, 51 kIOUserServerMethodRegister = 0x0001002, 52 }; 53 54 55 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 56 57 #define OSObject_Instantiate_ID 0x0000000100000001ULL 58 59 enum { 60 kOSObjectRPCRemote = 0x00000001, 61 kOSObjectRPCKernel = 0x00000002, 62 }; 63 64 struct OSObject_Instantiate_Msg_Content { 65 IORPCMessage __hdr; 66 OSObjectRef __object; 67 }; 68 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 78 #pragma pack(4) 79 struct OSObject_Instantiate_Msg { 80 IORPCMessageMach mach; 81 mach_msg_port_descriptor_t __object__descriptor; 82 OSObject_Instantiate_Msg_Content content; 83 }; 84 struct OSObject_Instantiate_Rpl { 85 IORPCMessageMach mach; 86 OSObject_Instantiate_Rpl_Content content; 87 }; 88 #pragma pack() 89 90 typedef uint64_t IOTrapMessageBuffer[256]; 91 92 #endif /* DRIVERKIT_PRIVATE */ 93 94 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 95 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 96 97 #ifdef XNU_KERNEL_PRIVATE 98 99 #include <IOKit/IOService.h> 100 #include <IOKit/IOUserClient.h> 101 #include <DriverKit/IOUserServer.h> 102 #include <libkern/c++/OSPtr.h> 103 #include <libkern/c++/OSKext.h> 104 105 class IOUserServer; 106 class OSUserMetaClass; 107 class OSObject; 108 class IODispatchQueue; 109 class IODispatchSource; 110 class IOInterruptDispatchSource; 111 class IOTimerDispatchSource; 112 class IOUserServerCheckInToken; 113 struct IOPStrings; 114 115 struct OSObjectUserVars { 116 IOUserServer * userServer; 117 IODispatchQueue ** queueArray; 118 OSUserMetaClass * userMeta; 119 OSArray * openProviders; 120 IOService * controllingDriver; 121 unsigned long willPowerState; 122 bool willTerminate; 123 bool didTerminate; 124 bool serverDied; 125 bool started; 126 bool stopped; 127 bool userServerPM; 128 bool willPower; 129 bool powerState; 130 uint32_t powerOverride; 131 IOLock * uvarsLock; 132 }; 133 134 extern IOLock * gIOUserServerLock; 135 136 typedef struct ipc_kmsg * ipc_kmsg_t; 137 138 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 139 140 namespace IOServicePH 141 { 142 void serverAdd(IOUserServer * server); 143 void serverRemove(IOUserServer * server); 144 void serverAck(IOUserServer * server); 145 bool serverSlept(void); 146 void systemHalt(int howto); 147 }; 148 149 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 150 151 class IOUserServer : public IOUserClient 152 { 153 OSDeclareDefaultStructorsWithDispatch(IOUserServer); 154 155 IOLock * fLock; 156 IOSimpleLock * fInterruptLock; 157 task_t fOwningTask; 158 OSDictionary * fEntitlements; 159 OSDictionary * fClasses; 160 IODispatchQueue * fRootQueue; 161 OSArray * fServices; 162 163 uint8_t fRootNotifier; 164 uint8_t fSystemPowerAck; 165 uint8_t fSystemOff; 166 IOUserServerCheckInToken * fCheckInToken; 167 public: 168 kern_allocation_name_t fAllocationName; 169 170 public: 171 172 /* 173 * 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 174 * a pending dext launch with the same server name. 175 * 176 * 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. 177 */ 178 static IOUserServer * launchUserServer(OSString * bundleID, const OSSymbol * serverName, OSNumber * serverTag, bool reuseIfExists, IOUserServerCheckInToken ** token); 179 static IOUserClient * withTask(task_t owningTask); 180 virtual IOReturn clientClose(void) APPLE_KEXT_OVERRIDE; 181 virtual bool finalize(IOOptionBits options) APPLE_KEXT_OVERRIDE; 182 virtual void stop(IOService * provider) APPLE_KEXT_OVERRIDE; 183 virtual void free() APPLE_KEXT_OVERRIDE; 184 185 virtual IOReturn setProperties(OSObject * properties) APPLE_KEXT_OVERRIDE; 186 virtual IOReturn externalMethod(uint32_t selector, IOExternalMethodArguments * args, 187 IOExternalMethodDispatch * dispatch, 188 OSObject * target, void * reference) APPLE_KEXT_OVERRIDE; 189 190 virtual IOExternalTrap * getTargetAndTrapForIndex(IOService ** targetP, UInt32 index) APPLE_KEXT_OVERRIDE; 191 192 IOReturn serviceAttach(IOService * service, IOService * provider); 193 IOReturn serviceStop(IOService * service, IOService * provider); 194 void serviceFree(IOService * service); 195 IOReturn serviceStarted(IOService * service, IOService * provider, bool result); 196 static void serviceWillTerminate(IOService * client, IOService * provider, IOOptionBits options); 197 static void serviceDidTerminate(IOService * client, IOService * provider, IOOptionBits options, bool * defer); 198 static void serviceDidStop(IOService * client, IOService * provider); 199 IOReturn serviceOpen(IOService * provider, IOService * client); 200 IOReturn serviceClose(IOService * provider, IOService * client); 201 IOReturn serviceSetPowerState(IOService * controllingDriver, IOService * service, IOPMPowerFlags flags, IOPMPowerStateIndex powerState); 202 IOReturn serviceNewUserClient(IOService * service, task_t owningTask, void * securityID, 203 uint32_t type, OSDictionary * properties, IOUserClient ** handler); 204 IOReturn serviceNewUserClient(IOService * service, task_t owningTask, void * securityID, 205 uint32_t type, OSDictionary * properties, OSSharedPtr<IOUserClient>& handler); 206 IOReturn exit(const char * reason); 207 208 bool serviceMatchesCheckInToken(IOUserServerCheckInToken *token); 209 bool checkEntitlements(IOService * provider, IOService * dext); 210 bool checkEntitlements(OSDictionary * entitlements, LIBKERN_CONSUMED OSObject * prop, 211 IOService * provider, IOService * dext); 212 213 void setTaskLoadTag(OSKext *kext); 214 void setDriverKitUUID(OSKext *kext); 215 void setCheckInToken(IOUserServerCheckInToken *token); 216 void systemPower(bool powerOff); 217 void systemHalt(int howto); 218 static void powerSourceChanged(bool acAttached); 219 220 IOReturn setPowerState(unsigned long state, IOService * service) APPLE_KEXT_OVERRIDE; 221 IOReturn powerStateWillChangeTo(IOPMPowerFlags flags, unsigned long state, IOService * service) APPLE_KEXT_OVERRIDE; 222 IOReturn powerStateDidChangeTo(IOPMPowerFlags flags, unsigned long state, IOService * service) APPLE_KEXT_OVERRIDE; 223 224 IOPStrings * copyInStringArray(const char * string, uint32_t userSize); 225 uint32_t stringArrayIndex(IOPStrings * array, const char * look); 226 IOReturn registerClass(OSClassDescription * desc, uint32_t size, OSUserMetaClass ** cls); 227 IOReturn registerClass(OSClassDescription * desc, uint32_t size, OSSharedPtr<OSUserMetaClass>& cls); 228 IOReturn setRootQueue(IODispatchQueue * queue); 229 230 OSObjectUserVars * varsForObject(OSObject * obj); 231 LIBKERN_RETURNS_NOT_RETAINED IODispatchQueue * queueForObject(OSObject * obj, uint64_t msgid); 232 233 static ipc_port_t copySendRightForObject(OSObject * object, natural_t /* ipc_kobject_type_t */ type); 234 static OSObject * copyObjectForSendRight(ipc_port_t port, natural_t /* ipc_kobject_type_t */ type); 235 236 IOReturn copyOutObjects(IORPCMessageMach * mach, IORPCMessage * message, 237 size_t size, bool consume); 238 IOReturn copyInObjects(IORPCMessageMach * mach, IORPCMessage * message, 239 size_t size, bool copyObjects, bool consumePorts); 240 241 IOReturn consumeObjects(IORPCMessage * message, size_t messageSize); 242 243 IOReturn objectInstantiate(OSObject * obj, IORPC rpc, IORPCMessage * message); 244 IOReturn kernelDispatch(OSObject * obj, IORPC rpc); 245 static OSObject * target(OSAction * action, IORPCMessage * message); 246 247 IOReturn rpc(IORPC rpc); 248 IOReturn server(ipc_kmsg_t requestkmsg, ipc_kmsg_t * preply); 249 kern_return_t waitInterruptTrap(void * p1, void * p2, void * p3, void * p4, void * p5, void * p6); 250 }; 251 252 typedef void (*IOUserServerCheckInCancellationHandler)(class IOUserServerCheckInToken*, void*); 253 254 // OSObject wrapper around IOUserServerCheckInCancellationHandler 255 class _IOUserServerCheckInCancellationHandler : public OSObject { 256 OSDeclareDefaultStructors(_IOUserServerCheckInCancellationHandler); 257 public: 258 static _IOUserServerCheckInCancellationHandler * 259 withHandler(IOUserServerCheckInCancellationHandler handler, void * args); 260 261 void call(IOUserServerCheckInToken * token); 262 private: 263 IOUserServerCheckInCancellationHandler fHandler; 264 void * fHandlerArgs; 265 }; 266 267 class IOUserServerCheckInToken : public OSObject 268 { 269 enum State { 270 kIOUserServerCheckInPending, 271 kIOUserServerCheckInCanceled, 272 kIOUserServerCheckInComplete, 273 }; 274 275 OSDeclareDefaultStructors(IOUserServerCheckInToken); 276 public: 277 virtual void free() APPLE_KEXT_OVERRIDE; 278 279 /* 280 * Cancel all pending dext launches. 281 */ 282 static void cancelAll(); 283 284 /* 285 * Set handler to be invoked when launch is cancelled. Returns an wrapper object for the handler to be released by the caller. 286 * The handler always runs under the lock for this IOUserServerCheckInToken. 287 * The returned object can be used with removeCancellationHandler(). 288 */ 289 _IOUserServerCheckInCancellationHandler * setCancellationHandler(IOUserServerCheckInCancellationHandler handler, void *handlerArgs); 290 291 /* 292 * Remove previously set cancellation handler. 293 */ 294 void removeCancellationHandler(_IOUserServerCheckInCancellationHandler * handler); 295 296 /* 297 * Cancel the launch 298 */ 299 void cancel(); 300 301 /* 302 * Mark launch as completed. 303 */ 304 void complete(); 305 306 const OSSymbol * copyServerName() const; 307 OSNumber * copyServerTag() const; 308 309 private: 310 static IOUserServerCheckInToken * findExistingToken(const OSSymbol * serverName); 311 bool init(const OSSymbol * userServerName, OSNumber * serverTag); 312 313 friend class IOUserServer; 314 315 316 317 private: 318 IOUserServerCheckInToken::State fState; 319 size_t fPendingCount; 320 const OSSymbol * fServerName; 321 OSNumber * fServerTag; 322 OSSet * fHandlers; 323 }; 324 325 extern "C" kern_return_t 326 IOUserServerUEXTTrap(OSObject * object, void * p1, void * p2, void * p3, void * p4, void * p5, void * p6); 327 328 #endif /* XNU_KERNEL_PRIVATE */ 329 #endif /* _IOUSERSERVER_H */ 330