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