yasukata / zpoline

system call hook for Linux
Apache License 2.0
459 stars 35 forks source link

why binary rewriting do not support clone3? #13

Closed 486zzx closed 2 months ago

486zzx commented 7 months ago

Why doesn't zpoline support clone3? Is it because of some special features of clone3?

I tried to call the clone3 syscall, but the call didn't happen (The print logs in hook_function() and strace logs are not displayed.), I observed that the code will directly return when encountering the clone3 syscall. The comment mentions that it will fall back to the clone system call. Why does the fallback solve the problem? Will it continue to evolve?

The code is in zpoline/main.c, line 240:

if (rax_on_stack == __NR_clone3)
        return -ENOSYS; /* workaround to trigger the fallback to clone */
yasukata commented 7 months ago

Thank you for your message.

Why doesn't zpoline support clone3? Is it because of some special features of clone3?

The reason why I did this is that the argument setting for clone3 was slightly complicated; I updated the implementation in https://github.com/yasukata/zpoline/commit/6ccbaebc9e96ae0bc24d754a8f68302bf86d809c to handle clone3 without returning -ENOSYS.

Why does the fallback solve the problem?

When I checked, glibc first attempts clone3, and if it gets ENOSYS as the return code, it falls back to clone; the approach, returning -ENOSYS for clone3, could solve the problem because clone, called by glibc as the fallback option of clone3, could be handled by the code below.

    if (rax_on_stack == __NR_clone) {
        if (rdi & CLONE_VM) { // pthread creation
            /* push return address to the stack */
            rsi -= sizeof(uint64_t);
            *((uint64_t *) rsi) = retptr;
        }
    }

Thank you very much for your interest.