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