-
Notifications
You must be signed in to change notification settings - Fork 561
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
[RFC] Dump/restore syscall user dispatch via ptrace #2423
base: criu-dev
Are you sure you want to change the base?
[RFC] Dump/restore syscall user dispatch via ptrace #2423
Conversation
@svetly-todorov Thank you for the pull request! Would you be able to add tests for this feature? |
|
||
/* Setup SUD-disable struct */ | ||
memset(&disable, 0, sizeof(disable)); | ||
disable.mode = PR_SYS_DISPATCH_OFF; |
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.
#10 2.352 compel/src/lib/ptrace.c:54:17: error: ‘PR_SYS_DISPATCH_OFF’ undeclared (first use in this function)
#10 2.352 54 | disable.mode = PR_SYS_DISPATCH_OFF;
#10 2.352 | ^~~~~~~~~~~~~~~~~~~
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.
This is probably a case of kernel headers not always being present. I'll go back and explicitly add the #ifdefs to sud.h.
While I'm at it, I'll probably also add some wrappers around the entire SUD architecture, since this only works with newer versions of the kernel, etc.
criu/sud.c
Outdated
struct sys_dispatch_entry *entry; | ||
sud_config_t config; | ||
|
||
entry = sud_lookup(tid_real, true, false); |
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 indentation is also mixed here.
#undef LOG_PREFIX | ||
#define LOG_PREFIX "sys-dispatch: " | ||
|
||
static struct rb_root sud_tid_rb_root = RB_ROOT; |
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.
pls add more info in the commit message to describe what is going on here.
CRIU injects a parasite blob while a process is being dumped. How do you handle where to place a parasite blob? |
We don't worry about the parasite blob during dump because we collect and disable SUD during the compel_wait_task that precedes the infection. It's been a while since I wrote this code, but if I'm remembering correctly, collection of SUD entries happens in this callback. This callback triggers here in compel_wait_task. The callback is necessary for SUD, but not necessary for seccomp, because ptrace can disable seccomp without overwriting its settings. So for seccomp, you can SUSPEND_SECCOMP during compel_wait_task and then read its settings later. But for SUD, you can only read its settings while it is active; ptrace only lets you enable/disable it without a graceful suspend. |
Use the PTRACE_GET/SET_SYSCALL_USER_DISPATCH_CONFIG flags to interface with a tracee's SUD settings. This is scaffolding for infect and seize, which will use ptrace to collect and suspend the SUD status of a seized task. Signed-off-by: Svetly Todorov <[email protected]> Signed-off-by: Gregory Price <[email protected]>
Use the new ptrace wrappers to get the SUD mode of the seized process. If activated, use ptrace_suspend_sud to disable it before proceeding with infection. Signed-off-by: Svetly Todorov <[email protected]> Signed-off-by: Gregory Price <[email protected]>
Introduce function signatures for SUD image generation, dump, and restore. These mirror the functions in seccomp.h/.c. Signed-off-by: Svetly Todorov <[email protected]> Signed-off-by: Gregory Price <[email protected]>
Add the necessary protobuf descriptions, image descriptions, and magic number for saving SUD data. Signed-off-by: Svetly Todorov <[email protected]> Signed-off-by: Gregory Price <[email protected]>
Add hooks for saving SUD status upon infection. Signed-off-by: Svetly Todorov <[email protected]> Signed-off-by: Gregory Price <[email protected]>
Add hooks for dumping SUD image to disk during cr-dump.c. Signed-off-by: Svetly Todorov <[email protected]> Signed-off-by: Gregory Price <[email protected]>
Add hooks for restoring SUD settings throughout cr-restore.c. The implementation is a little unorthodox. Unlike seccomp, SUD isn't suspended while a task is under ptrace. So the parasite code cannot restore the SUD settings because SIGSYS may be triggered when the restorer blob is unmapped. Instead, we opt to reopen the per-core data right before PTRACE_DETACH, and restore the SUD settings then. This way we don't risk triggering SIGSYS via a remote syscall. Signed-off-by: Svetly Todorov <[email protected]> Signed-off-by: Gregory Price <[email protected]>
Signed-off-by: Svetly Todorov <[email protected]>
d4b0cc1
to
c4f248f
Compare
I have pushed up a kind of v2 for this RFC containing some fixes and the beginnings of a test case. CRIU itself should build with the new changes. But the test does not work quite yet. I have to drop development on this for now, because of other work obligations. I may circle back to this in the future. Forgive me! |
Following up on issue #2037.
Use the PTRACE_GET/SET_SYSCALL_USER_DISPATCH flags upstreamed in kernel 6.4 to preserve SUD settings for a target process.
The majority of the implementation mirrors that of the seccomp dump/restore. The most significant difference is that, unlike seccomp, there's no flag for disabling SUD while a target is being ptraced. Therefore restoring it in the parasite blob is dangerous, because remote syscalls can generate a SIGSYS. Instead, restoration happens right before the final PTRACE_DETACH, and not in the parasite code.