thehajime / linux

Linux kernel source tree
https://lkl.github.io/
Other
3 stars 1 forks source link

CLONE_VM-less clone(2) #20

Open thehajime opened 1 month ago

thehajime commented 1 month ago

suppose we have a simple .c program using clone(2).

    pid = clone(childFunc, stackTop, CLONE_NEWUTS | SIGCHLD, argv[1]);
    if (pid == -1)
        errExit("clone");
    printf("clone() returned %ld\n", (long) pid);

(from https://github.com/nabla-containers/nabla-linux/blob/master/tests/clone.c#L64-L67) (this is similar to an example in https://man7.org/linux/man-pages/man2/clone.2.html)

with recent musl, the childFunc is called after printf("clone...") of parent, which corrupts the stack used by clone wrapper of musl (below).

https://git.musl-libc.org/cgit/musl/tree/src/linux/clone.c?id=fa4a8abd06a401822cc8ba4e352a219544c0118d#n53

    /* If CLONE_VM is used, it's impossible to give the child a consistent
     * thread structure. In this case, the best we can do is assume the
     * caller is content with an extremely restrictive execution context
     * like the one vfork() would provide. */
    if (flags & CLONE_VM) return __syscall_ret(
        __clone(func, stack, flags, arg, ptid, tls, ctid));

    __block_all_sigs(&csa.sigmask);
    LOCK(__abort_lock);

    /* Setup the a wrapper start function for the child process to do
     * mimic _Fork in producing a consistent execution state. */
    csa.func = func;
    csa.arg = arg;
    int ret = __clone(clone_start, stack, flags, &csa, ptid, tls, ctid);

    __post_Fork(ret);
    __restore_sigs(&csa.sigmask);
    return __syscall_ret(ret);
}

csa.func is overwritten by printf of parent, which is the original program fails to run.

need to investigate what is the defined/undefined behavior and what can be possibly addressed this situation.