5 ms·
I'm quite impressed with Windows 10's userland heap randomization. I never do any work on Linux, and especially not in the kernel. But maybe the authors can tak
by SCHiM 6y ago
I'm quite impressed with Windows 10's userland heap randomization. I never do any work on Linux, and especially not in the kernel. But maybe the authors can take some inspiration from the work there?
https://www.blackhat.com/docs/us-16/materials/us-16-Yason-Windows-10-Segment-Heap-Internals-wp.pdf https://www.blackhat.com/docs/us-16/materials/us-16-Yason-Wi...
https://www.blackhat.com/docs/us-16/materials/us-16-Yason-Windows-10-Segment-Heap-Internals.pdf https://www.blackhat.com/docs/us-16/materials/us-16-Yason-Wi...
It's still not perfect, given the predictable nature of block coalescence. But it's quite a departure from the old manager.
- saagarjha 6y agoThe Windows heap seems to have fairly straightforward security features; there doesn't seem to be a lot of randomization other than the heap base. Did I miss something in those two documents?
- SCHiM 6y agoAfter 18 allocations on the backend allocator LFH will kick in. The LFH will randomize returned chunks of the same size, doesn't matter if they were freed in the meantime or not. That makes it hard to exploit, you need to groom the heap before LFH kicks in because afterwards the unpredictability becomes too large. If you change the size of your request you will go either to another bucket or the backend allocator. So that makes type confusions slightly harder if you don't control variably sized buffers. Even before those 18 allocations, the specific tricks that used to work on the old manager, which is very similar to the behavior of linux kernel apparently, no longer work. It used to be that you could reliably get the same memory address if you allocated a same sized structure immediately after freeing another. But that no longer works. The only technique that I currently know of is that the merging of free blocks on the backend allocator is still deterministic. But to use that you must be sure your target has not already triggered LFH for the sizes that you're using while grooming.
- klodolph 6y agoLinux has had this a little longer, since 2005 or so: https://en.wikipedia.org/wiki/Address_space_layout_randomization https://en.wikipedia.org/wiki/Address_space_layout_randomiza... However, even if the “heap is randomized”, that typically just means that the underlying blocks of memory (e.g. what mmap returns) have randomized virtual addresses. The allocator you use will still have to carve up those blocks from the OS—your kernel does not provide malloc(), after all.
- jacobush 6y agoMaybe it should.
- im3w1l 6y agoI think the current design comes from the fact that calling the kernel is expensive so it's best not to do it too often. Maybe with the new ways of interacting with the kernel, like io_uring it can be cheaper.
- pritambaral 6y agoWell, io_uring is cheaper (significantly!) precisely because its for async operations, which can be pipelined. Application logic almost never uses malloc() in asynchronous, pipelineable fashion.
- jacobush 6y agoI’d argue that’s exactly what happens, especially during object initialisation in C++.
- jacobush 6y agoStill, it would eliminate a whole class of bugs, even with insecure languages such as C.
- tsimionescu 6y ago
- mehrdadn 6y agoWow, I didn't realize they've introduced a newer heap implementation (seems to be in Windows 10 version 2004). For anyone else wondering, it seems to be possible to turn on via a manifest: https://chromium.googlesource.com/chromium/src/+/1a9f684dad2f2620c5b88b3cea41c87143cd3c28%5E%21/#F2 https://chromium.googlesource.com/chromium/src/+/1a9f684dad2... Now I'm curious if there's any way to turn it on dynamically from inside a traditional Win32 process.
- delfinom 6y agoNope. It's been requested though https://github.com/microsoft/WinDev/issues/39 https://github.com/microsoft/WinDev/issues/39 You can also just edit the embedded manifest of traditional win32 processes as a hack before runtime :/