xref: /xnu-11215/iokit/IOKit/IOUserServer.h (revision 4f1223e8)
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 	IOWorkLoop          * fWorkLoop;
177 public:
178 	kern_allocation_name_t fAllocationName;
179 	task_t                 fOwningTask;
180 	os_reason_t            fTaskCrashReason;
181 
182 public:
183 
184 	/*
185 	 * 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
186 	 * a pending dext launch with the same server name.
187 	 *
188 	 * 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.
189 	 */
190 	static  IOUserServer * launchUserServer(OSString * bundleID, const OSSymbol * serverName, OSNumber * serverTag, bool reuseIfExists, IOUserServerCheckInToken ** token, OSData *serverDUI);
191 	static  IOUserClient * withTask(task_t owningTask);
192 	virtual IOReturn       clientClose(void) APPLE_KEXT_OVERRIDE;
193 	virtual bool           finalize(IOOptionBits options) APPLE_KEXT_OVERRIDE;
194 	virtual void           stop(IOService * provider) APPLE_KEXT_OVERRIDE;
195 	virtual void           free() APPLE_KEXT_OVERRIDE;
196 	virtual IOWorkLoop   * getWorkLoop() const APPLE_KEXT_OVERRIDE;
197 
198 	virtual IOReturn       setProperties(OSObject * properties) APPLE_KEXT_OVERRIDE;
199 	virtual IOReturn       externalMethod(uint32_t selector, IOExternalMethodArgumentsOpaque * args) APPLE_KEXT_OVERRIDE;
200 	static IOReturn        externalMethodStart(OSObject * target, void * reference, IOExternalMethodArguments * arguments);
201 	static IOReturn        externalMethodRegisterClass(OSObject * target, void * reference, IOExternalMethodArguments * arguments);
202 
203 	virtual IOExternalTrap * getTargetAndTrapForIndex(IOService ** targetP, UInt32 index) APPLE_KEXT_OVERRIDE;
204 
205 	IOReturn               serviceAttach(IOService * service, IOService * provider);
206 	IOReturn               serviceStop(IOService * service, IOService * provider);
207 	void                   serviceFree(IOService * service);
208 	IOReturn               serviceStarted(IOService * service, IOService * provider, bool result);
209 	static void            serviceWillTerminate(IOService * client, IOService * provider, IOOptionBits options);
210 	static void            serviceDidTerminate(IOService * client, IOService * provider, IOOptionBits options, bool * defer);
211 	static void            serviceDidStop(IOService * client, IOService * provider);
212 	IOReturn               serviceOpen(IOService * provider, IOService * client);
213 	IOReturn               serviceClose(IOService * provider, IOService * client);
214 	IOReturn               serviceJoinPMTree(IOService * service);
215 	IOReturn               serviceSetPowerState(IOService * controllingDriver, IOService * service, IOPMPowerFlags flags, IOPMPowerStateIndex powerState);
216 	IOReturn               serviceNewUserClient(IOService * service, task_t owningTask, void * securityID,
217 	    uint32_t type, OSDictionary * properties, IOUserClient ** handler);
218 	IOReturn               serviceNewUserClient(IOService * service, task_t owningTask, void * securityID,
219 	    uint32_t type, OSDictionary * properties, OSSharedPtr<IOUserClient>& handler);
220 	IOReturn               exit(const char * reason);
221 	IOReturn               kill(const char * reason);
222 
223 	bool                   serviceMatchesCheckInToken(IOUserServerCheckInToken *token);
224 	bool                   checkEntitlements(IOService * provider, IOService * dext);
225 	bool                   checkEntitlements(LIBKERN_CONSUMED OSObject * prop,
226 	    IOService * provider, IOService * dext);
227 	static bool            checkEntitlements(OSDictionary * entitlements, LIBKERN_CONSUMED OSObject * prop,
228 	    IOService * provider, IOService * dext);
229 
230 	void                   setTaskLoadTag(OSKext *kext);
231 	void                   setDriverKitUUID(OSKext *kext);
232 	void                   setDriverKitStatistics(OSKext *kext);
233 	IOReturn               setCheckInToken(IOUserServerCheckInToken *token);
234 	void                   systemPower(bool powerOff, bool hibernate);
235 	void                               systemHalt(int howto);
236 	static void            powerSourceChanged(bool acAttached);
237 	bool                   checkPMReady();
238 
239 	IOReturn                                setPowerState(unsigned long state, IOService * service) APPLE_KEXT_OVERRIDE;
240 	IOReturn                                powerStateWillChangeTo(IOPMPowerFlags flags, unsigned long state, IOService * service) APPLE_KEXT_OVERRIDE;
241 	IOReturn                                powerStateDidChangeTo(IOPMPowerFlags flags, unsigned long state, IOService * service) APPLE_KEXT_OVERRIDE;
242 
243 	IOPStrings *           copyInStringArray(const char * string, uint32_t userSize);
244 	uint32_t               stringArrayIndex(IOPStrings * array, const char * look);
245 	IOReturn               registerClass(OSClassDescription * desc, uint32_t size, OSUserMetaClass ** cls);
246 	IOReturn               registerClass(OSClassDescription * desc, uint32_t size, OSSharedPtr<OSUserMetaClass>& cls);
247 	IOReturn               setRootQueue(IODispatchQueue * queue);
248 
249 	OSObjectUserVars     * varsForObject(OSObject * obj);
250 	LIBKERN_RETURNS_NOT_RETAINED IODispatchQueue      * queueForObject(OSObject * obj, uint64_t msgid);
251 
252 	static ipc_port_t      copySendRightForObject(OSObject * object, natural_t /* ipc_kobject_type_t */ type);
253 	static OSObject      * copyObjectForSendRight(ipc_port_t port, natural_t /* ipc_kobject_type_t */ type);
254 
255 	IOReturn               copyOutObjects(IORPCMessageMach * mach, IORPCMessage * message,
256 	    size_t size, bool consume);
257 	IOReturn               copyInObjects(IORPCMessageMach * mach, IORPCMessage * message,
258 	    size_t size, bool copyObjects, bool consumePorts);
259 
260 	IOReturn               consumeObjects(IORPCMessageMach *mach, IORPCMessage * message, size_t messageSize);
261 
262 	IOReturn               objectInstantiate(OSObject * obj, IORPC rpc, IORPCMessage * message);
263 	IOReturn               kernelDispatch(OSObject * obj, IORPC rpc);
264 	static OSObject      * target(OSAction * action, IORPCMessage * message);
265 
266 	IOReturn               rpc(IORPC rpc);
267 	IOReturn               server(ipc_kmsg_t requestkmsg, IORPCMessage * message, ipc_kmsg_t * preply);
268 	kern_return_t          waitInterruptTrap(void * p1, void * p2, void * p3, void * p4, void * p5, void * p6);
269 	static bool            shouldLeakObjects();
270 	static void            beginLeakingObjects();
271 	bool                   isPlatformDriver();
272 	int                    getCSValidationCategory();
273 };
274 
275 typedef void (*IOUserServerCheckInCancellationHandler)(class IOUserServerCheckInToken*, void*);
276 
277 // OSObject wrapper around IOUserServerCheckInCancellationHandler
278 class _IOUserServerCheckInCancellationHandler : public OSObject {
279 	OSDeclareDefaultStructors(_IOUserServerCheckInCancellationHandler);
280 public:
281 	static _IOUserServerCheckInCancellationHandler *
282 	withHandler(IOUserServerCheckInCancellationHandler handler, void * args);
283 
284 	void call(IOUserServerCheckInToken * token);
285 private:
286 	IOUserServerCheckInCancellationHandler fHandler;
287 	void                                 * fHandlerArgs;
288 };
289 
290 class IOUserServerCheckInToken : public OSObject
291 {
292 	enum State {
293 		kIOUserServerCheckInPending,
294 		kIOUserServerCheckInCanceled,
295 		kIOUserServerCheckInComplete,
296 	};
297 
298 	OSDeclareDefaultStructors(IOUserServerCheckInToken);
299 public:
300 	virtual void free() APPLE_KEXT_OVERRIDE;
301 
302 	/*
303 	 * Cancel all pending dext launches.
304 	 */
305 	static void cancelAll();
306 
307 	/*
308 	 * Set handler to be invoked when launch is cancelled. Returns an wrapper object for the handler to be released by the caller.
309 	 * The handler always runs under the lock for this IOUserServerCheckInToken.
310 	 * The returned object can be used with removeCancellationHandler().
311 	 */
312 	_IOUserServerCheckInCancellationHandler * setCancellationHandler(IOUserServerCheckInCancellationHandler handler, void *handlerArgs);
313 
314 	/*
315 	 * Remove previously set cancellation handler.
316 	 */
317 	void removeCancellationHandler(_IOUserServerCheckInCancellationHandler * handler);
318 
319 	/*
320 	 * Cancel the launch
321 	 */
322 	void cancel();
323 
324 	/*
325 	 * Mark launch as completed.
326 	 */
327 	IOReturn complete();
328 
329 	const OSSymbol * copyServerName() const;
330 	OSNumber * copyServerTag() const;
331 
332 private:
333 	static IOUserServerCheckInToken * findExistingToken(const OSSymbol * serverName);
334 	bool init(const OSSymbol * userServerName, OSNumber * serverTag, OSKext *driverKext, OSData *serverDUI);
335 	bool dextTerminate(void);
336 
337 	friend class IOUserServer;
338 
339 
340 
341 private:
342 	IOUserServerCheckInToken::State          fState;
343 	size_t                                   fPendingCount;
344 	const OSSymbol                         * fServerName;
345 	const OSSymbol                         * fExecutableName;
346 	OSNumber                               * fServerTag;
347 	OSSet                                  * fHandlers;
348 	OSString                               * fKextBundleID;
349 	bool                                     fNeedDextDec;
350 };
351 
352 extern "C" kern_return_t
353 IOUserServerUEXTTrap(OSObject * object, void * p1, void * p2, void * p3, void * p4, void * p5, void * p6);
354 
355 extern "C" void
356 IOUserServerRecordExitReason(task_t task, os_reason_t reason);
357 
358 #endif /* XNU_KERNEL_PRIVATE */
359 #endif /* _IOUSERSERVER_H */
360