@dysfun@whitequark why is this a problem? as long as you have virtual memory, you pay something like up to 4093 bytes of data memory more than you need, plus some inefficiency of TLBs and page tables?
@whitequark compiler function attribute that teaches the compiler to lazily copy the stack after setjmp() has been called, so you basically have one active stack pointer and one stack pointer for saving old stack contents, and every callee of such a function, immediately after the call returns, backs up the current state of the now-active frame into memory referenced by the setjmp buffer
Pretty far up the list of things I find terrible about Linux development is how emailed patches often have no clear machine-readably-specified commit they should apply to which is available in git - so it takes some manual effort to figure out how to locally apply them so that I can look at the entire codebase with the patches applied.
Looking at a complex patch series with just 3 lines of context would be a really bad idea...
@whitequark does one of the two implementations involve more thread switches, where you have lots of "thread A wakes thread B, then thread A goes to sleep"? AFAIK the kernel already can't handle those particularly well (https://youtu.be/KXuZi9aeGTw?t=611), and I imagine adding more noise to the scheduler could make things worse?
fun Linux fact: because MAP_SHARED|MAP_ANONYMOUS is actually a file-backed mapping under the hood, unmapping part of such a mapping does not discard the data stored in that part:
$ cat mremap.c #define _GNU_SOURCE #include <err.h> #include <stdio.h> #include <sys/mman.h> int main(void) { char *p = mmap(NULL, 0x2000, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0); if (p == MAP_FAILED) err(1, "mmap"); p[0x1000] = 'X'; if (munmap(p+0x1000, 0x1000)) err(1, "munmap"); // that 'X' we just wrote... is it gone? // nope, let's bring it back! p = mremap(p, 0x1000, 0x2000, MREMAP_MAYMOVE); if (p == MAP_FAILED) err(1, "mremap"); printf("p[0x1000]='%c'\n", p[0x1000]); } $ gcc -o mremap mremap.c $ ./mremap p[0x1000]='X' $
@alanc aah, and I guess that also means it's safe if the compiler optimizes malloc(0) into NULL when the libc doesn't do that, only the other direction would break stuff...
@alanc trying to determine at build time if malloc can return NULL seems kinda unsafe anyway? like, what if the same kind of compiler optimization also applies to the code that uses the macro, or if an update to the libc changes this behavior?
I added code to Linux to help KASAN detect specific types of UAFs more reliably (https://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab.git/commit/?h=slab/for-6.12/rcu_barriers&id=b8c8ba73c68bb3c3e9dad22f488b86c540c839f9), it's been in the linux-next integration tree for, I don't know, a month or so maybe (though it's not in the mainline tree yet), and still there are zero hits on LKML of bugs caught where the stack trace involves my detection... It's nice that there apparently aren't a lot of easy-to-find bugs of this type around but it's also a little disappointing to not immediately get some nice results from my work...
human borrow checker (but logic bugs are best bugs).works at Google Project Zero.The density of logic bugs (compared to memory corruption bugs) goes down as the privilege differential between attacker context and target context goes up.