-
Notifications
You must be signed in to change notification settings - Fork 38
neonvm-kernel: Patch null ptr deref in x86 pagetable setup #1392
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
ref https://neondb.slack.com/archives/C0807C9SSJ2/p1748363834798349 ref https://neondb.slack.com/archives/C03TN5G758R/p1748944236243709 ref #1391 Broader discussion in the slack threads, but at a high level: 1. We started seeing null pointer dereferences after failed allocations in phys_pud_init() and friends 2. Those functions don't handle allocation failure (because normally they're called during boot, where the allocation cannot fail) 3. The allocation uses the GFP_ATOMIC flag, which *can* fail 4. This has been the case for a while, so whatever reason we're starting to see allocation failures, this code probably does need to be able to handle them. This change consists of two patches: * 00-phys_pgtable_nullptr.patch -- the actual change * 01-debug-phys_pgtable_nullptr.patch -- extra neon-specific logging so that we can scan for any VMs that would have hit the bug. The main idea of the change is to propagate allocation failures by returning zero from the phys_{p4d,pud,pmd}_init() functions, turning that into an -ENOMEM return when we get the chance. Those phys_{p4d,pud,pmd}_init() functions currently return the last physical address mapped; I've assumed that zero is not a valid return, and updated arch_add_memory() to return -ENOMEM if init_memory_mapping() returns zero. This matches the behavior of add_pages(), which is also called by arch_add_memory(). This patch was tested by injecting failure in phys_pud_init for a single call to alloc_low_page() after boot, confirming that: * an allocation failure will no longer cause a null pointer dereference * virtio-mem hotplug succeeds after the initial failure, if made to retry Check the slack threads for more detail on that testing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked at the C code, looks good to me modulo some comments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple high level comments, didn't look at the patch itself yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The patches look good to me! However, I'm not familiar with this code in linux kernel at all, so I cannot say if it's correct – it's possible that error handling here should be more complicated, but I don't really know.
I checked that the patches shouldn't make anything worse – the new code will be executed only on allocation failures, and the current behaviour is NPE, so it cannot get any worse. So it should be totally ok to deploy it to staging/prod, if we want to.
Co-authored-by: Arthur Petukhovsky <[email protected]>
Co-authored-by: Arthur Petukhovsky <[email protected]>
After a recent announcement [1] by Go team, saying they won't proceed with adding error handling syntax to Go, it is evident we have to implement a solution downstream. We already build Linux kernel with custom patches (see #1386, #1392), it is logical that as a next step we should have our own fork of Go, called Neon Go. The first feature is a syntax to handle errors. It supports the following syntax: ... := ... handle err { ... } Which is equivalent to: ..., err := ... if err != nil { ... } Advantages: 1. Easy to read. 2. Easy to write (no need to look for the ! key). Timeline to implement: 5 June - merge to main 6 June - deploy to staging 7 June - deploy to production [1]: https://go.dev/blog/error-syntax NOTE: this is, of course, a joke. I don't have any strong opinion about error handling in Go.
ref https://neondb.slack.com/archives/C0807C9SSJ2/p1748363834798349
ref https://neondb.slack.com/archives/C03TN5G758R/p1748944236243709
ref #1391
Broader discussion in the slack threads, but at a high level:
phys_pud_init()
and friendsGFP_ATOMIC
flag, which can failThis change consists of several patches, matching this thread on LKML.
The main idea of the change is to propagate allocation failures by changing the
phys_*_init()
functions to return-ENOMEM
(which in turn requires changing their return type).This patch was tested by injecting failure in
phys_pud_init()
for a single call toalloc_low_page()
after boot, confirming that:Check the slack threads for more detail on that testing.