5 ms·
Related (and hilarious): https://scholar.harvard.edu/files/mickens/files/thenightwatch.pdf https://scholar.harvard.edu/files/mickens/files/thenightwatc... > Wh
by jacinda 2y ago
Related (and hilarious): https://scholar.harvard.edu/files/mickens/files/thenightwatch.pdf https://scholar.harvard.edu/files/mickens/files/thenightwatc...
> What is despair? I have known it—hear my song. Despair is
when you’re debugging a kernel driver and you look at a memory dump and you see that a pointer has a value of 7. THERE IS
NO HARDWARE ARCHITECTURE THAT IS ALIGNED ON
7. Furthermore, 7 IS TOO SMALL AND ONLY EVIL CODE
WOULD TRY TO ACCESS SMALL NUMBER MEMORY.
Misaligned, small-number memory accesses have stolen
decades from my life.
All James Mickens' USENIX articles are fun (for a very specific subset of computer scientist - the kind that would comment on this thread). https://mickens.seas.harvard.edu/wisdom-james-mickens https://mickens.seas.harvard.edu/wisdom-james-mickens
- hinkley 2y agoI don’t know if it’s still a thing but there used to be debugging tools that would put a page of memory marked as either read only or unreadable in front of every malloc call so that any pointer arithmetic with a math error would trigger a page fault which could be debugged. It worked in apps that didn’t use too much of total memory or too many fine grained allocations. I mean obviously turning every 8 byte pointer into a whole memory page could consume all of memory very quickly. But in front of arrays or large data structures that could work.
- saagarjha 2y agoIn this case the write bypassed page protections
- dwattttt 2y agoIt shouldn't bypass page protections, that would be a kernel bug. And quite a bit harder to achieve too, since the kernel would still be using the same virtual address mapping as user space there.
- saagarjha 2y agoThey made the pages read-only for themselves; the kernel has the ability to write through that.
- dwattttt 2y agoSure, but only by either changing the page permissions on the page that virtual address is on, or by remapping it elsewhere as writable; both of those are heavy handed operations, and neither would be in the "report the result of an IO operation" path. x86 page table entries can't express "user read only, kernel read/write"
- jcalvinowens 2y agoThe user mapping may be read only, but the kernel will likely use other writable mappings to the same page. Linux for example maintains a big writable linear mapping of all RAM at all times (on 64-bit), you can corrupt read-only user pages through it all day and never fault. Code running in the kernel generlly uses virtual addresses from that mapping.
- dwattttt 2y agoBy policy, asking the Windows kernel to write to an address happens within an SEH try/catch, and a failure will result in the kernel returning an error code. The kernel has no reason to be trying to bypass page protections; what if you asked it to write to a shared read-only page?
- jcalvinowens 2y agoMost kernel code will be dealing with a different set of virtual addresses, which map the entire address space read/write. Those addresses necessarily alias the physical pages backing any userspace mapping, and thus allow corrupting them e.g. via buffer overflows beyond page boundaries. The try-catch dance you're describing is only necessary for accessing the userspace mapping (because it might fault). Kernel code which dereferences kernel pointers doesn't do that. Pages don't get remapped into userspace: userspace gets an additional aliased mapping with restricted permissions. The kernel's writable mapping still exists. There's nothing to "bypass", what permissions userspace applies its user mapping of the same physical page has no effect on the kernel mapping.
- lupire 2y agoI don't understand. Pointers aren't numbers, and can only be compared when inside a common array. What is small number memory? :-)
- MobiusHorizons 2y agoI realize you are probably referring to UB in c/c++, but of course in hardware memory addresses are numbers. And when debugging, it’s really the hardware version of events that matters, since the compiler has already done whatever optimizations it wants.
- ryao 2y agoPointers are numbers representing memory addresses. This is very obvious if you look at the definition of NULL in C. It is: #define NULL ((void *)0) As of C99, C also has uintptr_t, which lets you treat pointers as integers.
- moomin 2y agoI mean, that’s horribly misleading. There’s no guarantee that “zero” is actually an int zero. (Although I’m pretty sure it is on Intel and ARM.)