xref: /xnu-11215.41.3/iokit/IOKit/IOUserServer.h (revision 33de042d024d46de5ff4e89f2471de6608e37fa4)
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 bool checkPMReady(void);
153 };
154 
155 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
156 
157 class IOUserServer : public IOUserClient2022
158 {
159 	OSDeclareDefaultStructorsWithDispatch(IOUserServer);
160 
161 	IOLock       *        fLock;
162 	IOSimpleLock *        fInterruptLock;
163 	OSDictionary  *       fEntitlements;
164 	OSDictionary  *       fClasses;
165 	IODispatchQueue     * fRootQueue;
166 	OSArray             * fServices;
167 
168 	uint8_t               fRootNotifier;
169 	uint8_t               fSystemPowerAck;
170 	uint8_t               fSystemOff;
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 	IOReturn               setCheckInToken(IOUserServerCheckInToken *token);
232 	void                   systemPower(bool powerOff, bool hibernate);
233 	void                               systemHalt(int howto);
234 	static void            powerSourceChanged(bool acAttached);
235 	bool                   checkPMReady();
236 
237 	IOReturn                                setPowerState(unsigned long state, IOService * service) APPLE_KEXT_OVERRIDE;
238 	IOReturn                                powerStateWillChangeTo(IOPMPowerFlags flags, unsigned long state, IOService * service) APPLE_KEXT_OVERRIDE;
239 	IOReturn                                powerStateDidChangeTo(IOPMPowerFlags flags, unsigned long state, IOService * service) APPLE_KEXT_OVERRIDE;
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(IORPCMessageMach *mach, 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, IORPCMessage * message, 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 	IOReturn 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