Yes, after 2f36db710093, using ecryptfs on top of filesystems that don't support mmap will stop working. I believe that a nice way to do it would be to put the lower kstack to sleep in a ptrace syscall entry/exit stop, let the upper kstack recurse down into the lower one, pause the upper kstack while its stack pointer points into the saved userland registers at the top of the lower kstack's stack, and then use ptrace's userland register manipulation functions on the lower thread to first overwrite the stuff the upper kstack's stack pointer points to and then perhaps even restore the saved userland registers (especially CS and SS) to sane values via ptrace.) DeleteįUSE does support mmap (which is a really nice feature, but also useful for exploitation), and layering ecryptfs on top of FUSE should still work. (Before I realized that the buddy allocator is generic and used for more things than just kstacks, I actually thought about how I would exploit an overflow of a kstack into another one. See the pthread_create page and here for some interesting examples on this.I guess that given a kernel stack pointer leak, your approach of overflowing a kstack into another kstack would also help with exploitation of this issue, since that would eliminate the unreliable heap spray. So the thread stack size can be set either via the set function above, or the ulimit system property.įor the 16k you're referring to, it's not clear on which platform you've seen that and/or if any system limit was set for this. To create a thread, in order to obtain a stack size other than the
![linux thread kernel stack size linux thread kernel stack size](https://imgs.developpaper.com/imgs/3293733242-6d3821c84e6c5132_articlex.png)
Stack size attribute can be explicitly set in the attr argument used RLIMIT_STACK soft resource limit at the time the program started hasĪny value other than "unlimited", then it determines the default Under the NPTL threading implementation, if the On Linux/x86-32, the default stack size for a new thread is 2 In your example, the stack size is set to 8388608 bytes which corresponds to 8MB, as returned by the command ulimit -s The stacksize attribute shall define the minimum stack size (inīytes) allocated for the created threads stack. Int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize) Also, if your application is performance sensitive and deals with a significant amount of data, you should understand how the TLB (the MMU's page table cache) works and how you can restructure your data or your algorithms to maximize your TLB hit rate. In particular, it's responsible for a lot of the "magic" in the system, so I highly recommend learning more about what the MMU does, and about virtual memory in general. The MMU is a key part of the hardware of today's computer systems. Meanwhile, the stack automatically grows (or doesn't) to meet the thread's needs. From its point of view, it just uses the stack as if the memory was there all along. The user space thread sees none of that work. The kernel allocates a page of physical RAM to that virtual memory page and returns back to the user space thread.
![linux thread kernel stack size linux thread kernel stack size](https://3.bp.blogspot.com/-TiRsbBL7HwE/Xbng3AXVcKI/AAAAAAAABE4/9-vpf_PcT0sXU3lacumdRiKK2S22ZSE7ACNcBGAsYHQ/s1600/scs-instrumentation.png)
![linux thread kernel stack size linux thread kernel stack size](https://i.stack.imgur.com/Ajs6r.png)
The CPU core responds to the page fault exception by switching to a privileged execution mode (which has its own stack) and calling the page fault exception handler function inside the kernel.
![linux thread kernel stack size linux thread kernel stack size](https://jon.oberheide.org/images/2010/11/kstack-smash.png)
When your thread runs and tries to access a virtual address on the stack that doesn't have a physical page assigned to it yet, a hardware exception called a "page fault" is triggered by the MMU. This requires very little RAM to hold the page table entries only. The OS allocates 8 MB of virtual memory for your stack by setting up the MMU's page tables for your thread. This is one of the magical powers that your OS gets from using the hardware Memory Management Unit (MMU) in your processor. The good news is that your thread only uses the amount of physical memory that it actually needs. Of course, it's natural to conclude that this can't be right, because that's a ridiculously large amount of memory for every thread to consume for its stack when 99% of the time a couple of KB is probably all they need. Actually, your virtual stack size is 8388608 bytes (8 MB).