Wiley.Symbian.OS.Internals.Real.time.Kernel.Programming.Dec.2005.eBook-DDU (779891), страница 40
Текст из файла (страница 40)
However, in practice we do not allow this.This is because the exec call is executing kernel code with supervisorprivileges, and can therefore read and write anywhere in the processor’saddress space, which of course includes kernel memory. If the exec calldereferences a pointer given to it by a user thread without checking thatpointer, then we are effectively giving the user thread the freedom toaccess all of the address space too. This defeats platform security andSERVICES PROVIDED TO USER THREADS179makes it more likely that an invalid pointer from the user application willoverwrite a key part of the kernel, crashing the mobile phone.5.2.1.5 The kumem functionsDoes this mean that exec calls can’t access the memory of the userprocess that called them? No, because we provide the special kernelfunctions kumemget(), kumemput() and kumemset() to dereferencethe pointers that are passed from user code.
You should use thesefunctions yourself if you are writing a device driver or an extension thatis passed pointers to user data from user-side code.The kumem functions access memory with special CPU instructionsthat perform the access at user privilege level – for example LDRT/STRTon ARM.
Here is the relevant portion of the kumemget() function, thistime on X86 for a change:_asm mov ax, gs_asm mov ds, ax_asm call CopyInterSegOn entry to the function, GS contains the data segment of thecaller – this is obviously a user-mode data segment in the case of anexec call. We move GS to DS before we call CopyInterSeg(), whichcopies ECX bytes from DS:ESI to ES:EDI. This means that the user’s datasegment is used as the source of the copy, and the memory move thereforerespects the privileges of the caller.5.2.1.6 Slow and fast executive calls comparedI mentioned earlier that the dispatcher checks a bit in the SWI opcode todetermine whether the exec call is a slow or a fast one. In this sectionI’ll discuss these two forms of exec call in more detail and point out thedifferences between them.Slow executive callsSlow exec calls run with interrupts enabled and the kernel unlocked.
Thismeans that they can be preempted at any point in their execution.As we saw in the walk-through, slow exec calls have a mechanismfor automatically performing certain actions when in the dispatcher. Thismechanism relies on particular bits being set in the attribute word of theslow executive table.Using this mechanism, a slow exec call may:• Acquire the system lock fast mutex before calling the kernel handler• Release the system lock after calling the kernel handler• Call a Symbian OS preprocessing handler to look up a Symbian OShandle. In this case, the call always acquires the system lock too.180KERNEL SERVICESA key difference between slow and fast execs is that the user side canpass many more parameters to a slow exec call.
In their standard form,slow execs can have up to four direct 32-bit arguments and can returnone 32-bit value. If this isn’t enough, then the slow exec call can alsocopy as many as eight additional 32-bit values from user space to thecurrent thread’s supervisor stack. If this is done, then we have to use oneof the four direct arguments to point to the additional arguments, so wecan pass a maximum of eleven arguments in total.These extra exec call arguments are a new feature of EKA2 that is notavailable on EKA1. On EKA1, you could pass extra arguments, but onlyby passing a pointer to an arbitrary amount of additional user-mode dataas one of the four standard parameters.
The EKA1 kernel would thenaccess this data directly, which, as I discussed in Section 5.2.1.4, is notsafe. EKA2 allows the extra arguments to be passed in a way that doesnot compromise robustness or security, because the new kernel uses thekumem functions to access the additional data.The mechanism by which the extra parameters are passed is dependenton the CPU architecture. If the processor has sufficient registers, then weuse those that are not already in use. For example, on ARM, we passthe extra arguments in R4-R11; this means that the user-side Exec::functions must save these registers and load the additional argumentsinto them before executing the SWI instruction to enter the kernel. TheExec:: functions must then restore those registers on return from thekernel. The dispatcher pushes R4–R11 onto the supervisor stack and thensets R2 (the third normal argument) to the address of the saved R4.On X86, we use the third argument to pass a pointer to the additionalarguments in user memory.
The dispatcher copies the specified numberof arguments from user memory space to the current thread’s supervisorstack and modifies the third argument to refer to the copied arguments.If the SWI opcode has its system lock bit set, then the dispatcher copiesthe arguments before it acquires the system lock. We do it this way incase an exception occurs during the copying of the additional argumentsbecause the supplied address is invalid. Then, if this does happen, thekernel can terminate the current thread without a problem.Regardless of the CPU architecture, the executive handler alwaysaccesses the additional arguments by using the third normal argument as apointer to them. By the time the executive handler runs, the dispatcher willhave copied the additional arguments to the current thread’s supervisorstack, and changed the third argument to refer to that copy.
This meansthat the executive handler does not need to check that the referencedaddress is a valid user mode address.Fast exec callsAs we saw earlier, slow exec calls run with interrupts enabled. Fast execcalls, on the contrary, run with all interrupts disabled. This is anotherSERVICES PROVIDED TO USER THREADS181difference from EKA1, where they ran with IRQ interrupts disabled andFIQ interrupts enabled. Because of this, EKA2 fast exec calls must be veryshort.
There aren’t many of them, and typically they get or set a single,easily accessible, item of kernel data. For example, there is a fast execcall to get the current thread’s heap pointer.We saw that slow exec calls can pass up to eleven parameters. Fastexec calls, on the other hand, can only pass one 32-bit parameter. Theymay also return a single 32-bit value.5.2.1.7 Executive tablesI have already mentioned that we specify the range of valid fast and slowexecutive calls and their associated handlers using two tables – the fastexecutive table and the slow executive table.
Every nanokernel threadin the system has two pointers, one to each of these tables. The kernelsets up these pointers when the thread is created, which means that theavailable executive calls can be changed on a thread-by-thread basis. AllSymbian OS threads do in fact use the same tables, but this feature makesit possible for threads in an RTOS personality layer to use different tables,if desired. It is worth noting that you would only need to use this featureif you had user-mode personality layer threads.
If your threads only everrun in supervisor mode, then you can call your required personality layerservices directly.The fast executive tableThe fast executive table is composed of a number of 32-bit entries, like so:Word indexDescription0Number of fast executive calls supported.n≥1Address of handler for fast executive call number n.You can see that fast executive call 0 has no entry in the table.This is because it is always assigned to wait on the current thread’srequest semaphore.If a thread makes a fast executive call with a number that is greaterthan or equal to the number of calls specified in the table, then thekernel calls the invalid executive handler, which is specified in the slowexecutive table.The slow executive tableThe slow executive table is composed of three single-word entries followed by an arbitrary number of two-word entries, like so:182Word indexKERNEL SERVICESDescription0Number of slow executive calls supported.1Address of handler for invalid call number.2Address of handler for argument preprocessing.3+2nAttribute flags for slow executive call number n.4+2nAddress of handler for slow executive call number n.If a thread makes a slow executive call with a number that is greaterthan or equal to the number of calls specified in the table, then the kernelcalls the invalid executive handler, which is specified in word 1 of thetable.
Invalid fast exec calls are routed here too, but even in this case thekernel treats the invalid handler as a slow executive call with its attributeflags all zero.I’ve mentioned the attribute flags already in the walk-through and inmy discussions about the differences between slow and fast exec calls.These flags determine any additional actions that the dispatcher performsbefore calling the handler and after returning from it.