On 2/25/2020 10:26 AM, Xiang Xiao wrote:
On Tue, Feb 25, 2020 at 11:59 PM Gregory Nutt <spudan...@gmail.com> wrote:
Hi,
i meant that, if userspace wants to read some kernel memory, it can pass
the kernel pointer to eg. write system call as the buffer argument,
and then read the contents of the file.
I guess I still don't understand.  Access is still via file descriptor.
You could certainly clobber kernel memory with a read in that way.  But
it is not clear how you could read the kernel memory into user space.
Here is an example:
Program open malicious elf and call read with a pointer to kernel
stack, then kernel may run code from elf after kernel finish and
return.
It is not clear to me how you could do that.  The stack is not
accessible to the calling thread while the system call is running, but I
suppose it could be accessed by another thread:

1. Thread A calls sem wait
2. Thread B modifies Thread A return stack so that sem_wait returns to
user code, then posts the semaphoe
3. When semaphore wakes up, the return would execute in supervisor mode.

Unlike Linux (and most higher end OS's), NuttX does not use a separate
kernel stack.  In Linux, each task has two stacks, a user space stack
and a kernel space stack.  In the system call handler, it switches ti
the kernel stack; on the system call return, it switches back to the
user stack.  That allows you to protect the stack from any user access
while in kernelmode and would prohibit this kind of thing.

Since all arch need save the function return address into stack
eventually, if userspace pass a pointer inside the stack and request
kernel read the file provided by userspace to this pointer, then
kernel may get the wrong return address and run the malicious code
with the highest privilege. The keypoint isn't whether we use
two(user/kernel) stack or single stack, but the kernel may corrupt the
return address saved in the stack and then jump to the attacked code
before low the privilege.

yes, I think you could do that in the current environment, but I don't think it would be possible to do that with two stacks -- well, at least if would not be easy.  The kernel logic invoked by the syscall code does not "return" using any stack data.  It executes a second system call without returning (SYS_syscall_return).  The second system call performs the return to user space.  There might be some way to hack into that, but just ovewriting the return address on the kernel stack won't do it.


Reply via email to