Skip to content
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

clone(..., ..., CLONE_VM|CLONE_VFORK|SIGCHLD, ...) returns Invalid Argument #1005

Closed
therealkenc opened this issue Aug 29, 2016 · 14 comments
Closed

Comments

@therealkenc
Copy link
Collaborator

therealkenc commented Aug 29, 2016

Build 14905. Following test case prints: "clone() returned: Invalid argument" on WSL (Trusty). Function foo() spawns successfully on native Ubuntu. It appears to be a construct used in glibc 2.24, possibly here. Problem looks a lot like #158, which notes clone() progress was made in 14352, but this combination of flags still seems to trip. File under "vote for it on User Voice".

[test case edited Feb 2 2017]

/* clone-test.c */
#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>

#define STACK_SIZE 16364

int foo(void* arg) {
    printf("child arg: %s\n", (const char*)arg);
    _exit(0);
}

int main(int argc, char *argv[]) {
    void** child_stack = (void **)malloc(STACK_SIZE);
    int ret = clone(foo, 
        child_stack + STACK_SIZE, 
        CLONE_VM|CLONE_VFORK|SIGCHLD, 
        (void*)"hello");
    sleep(1);
    if (ret == -1) {
        printf("clone() returned: %s\n", strerror(errno));
    }
    else {
        printf("clone() okay!\n");
    }
    printf("exiting\n");
}

strace:

execve("./a.out", ["./a.out"], [/* 19 vars */]) = 0
brk(NULL)                               = 0xaaf000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f33a6640000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=111528, ...}) = 0
mmap(NULL, 111528, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f33a6609000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\t\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1864888, ...}) = 0
mmap(NULL, 3967392, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f33a6030000
mprotect(0x7f33a61ef000, 2097152, PROT_NONE) = 0
mmap(0x7f33a63ef000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 
   3, 0x1bf000) = 0x7f33a63ef000
mmap(0x7f33a63f5000, 14752, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS,
   -1, 0) = 0x7f33a63f5000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f33a6630000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f33a6600000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f33a65f0000
arch_prctl(ARCH_SET_FS, 0x7f33a6600700) = 0
mprotect(0x7f33a63ef000, 16384, PROT_READ) = 0
mprotect(0x600000, 4096, PROT_READ)     = 0
mprotect(0x7f33a6625000, 4096, PROT_READ) = 0
munmap(0x7f33a6609000, 111528)          = 0
brk(NULL)                               = 0xaaf000
brk(0xad4000)                           = 0xad4000
clone(child_stack=0xacef60, flags=CLONE_VM|CLONE_VFORK|SIGCHLD) = -1 EINVAL (Invalid argument)
nanosleep({1, 0}, 0x7fffe12a46d0)       = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
write(1, "clone() returned: Invalid argume"..., 35) = 35
write(1, "exiting\n", 8)                = 8
exit_group(0)                           = ?
+++ exited with 0 +++
@fpqc
Copy link

fpqc commented Aug 29, 2016

Given that he answered the other linked thread on clone(), maybe ping @stehufntdev

@stehufntdev
Copy link
Collaborator

Thanks for reporting the issue. There is limited support for the different supported clone flags, but we are currently working through fixes in this area.

@iz0eyj
Copy link

iz0eyj commented Aug 31, 2016

@stehufntdev clone(child_stack=0, flags=CLONE_NEWUSER|SIGCHLD) = -1 EINVAL (Invalid argument) with Vivaldi browser

@stehufntdev
Copy link
Collaborator

Thanks iz0eyj, I can confirm we do not support user namespaces (CLONE_NEWUSER) but are tracking that work.

@fpqc
Copy link

fpqc commented Aug 31, 2016

@iz0eyj By the way, Arch linux does not support user namespaces by default either. If you install Arch's build of Vivaldi off the AUR, it should in theory work.

@stehufntdev Not all distros even support user namespaces for security reasons (and therefore, to use unprivileged containers you need to use an unsupported custom kernel). You should probably be aware of this before you go to implement it.

Here is the quote from the Wiki: "Due to security concerns, the default Arch kernel does not ship with the ability to run containers as an unprivileged user; therefore, it is normal to see a missing status for "User namespaces" when running the check. See FS#36969 for this feature request."

@fpqc
Copy link

fpqc commented Sep 1, 2016

@iz0eyj By the way, you might be able to get Vivaldi to launch with "--no-sandbox". This disables the use of "User Namespaces". Some of the Vivaldi devs are curious if it will actually work.

@iz0eyj
Copy link

iz0eyj commented Sep 1, 2016

@fpqc many thanks fpqc, Vivaldi is a nice browser and I'm happy to report something to devs.
Now I'm testing Xenial (only a little problem with sudo command solved in 2 min.).

@JackieKu
Copy link

JackieKu commented Sep 2, 2016

Please be noted locale-gen fails with compressed charmap due to this bug. It makes use of posix_spawn[p]() which is implemented on top of the clone(...CLONE_VM|CLONE_VFORK|SIGCHLD...). I think this issue is somewhat important because posix_spawn[p] is in POSIX, and locale-gen is rather fundamental to the glibc systems.

@therealkenc
Copy link
Collaborator Author

therealkenc commented Dec 2, 2016

Cool if this is a dup, but note the failure mode here is EINVAL on clone(...,CLONE_VM|CLONE_VFORK|SIGCHLD, ...), not ENOMEM on vfork() as in #851 et al. You can allocate all the page file size in the world but the above test case fails with EINVAL, at least at the time of writing.

@benhillis
Copy link
Member

@therealkenc - You're totally right, this is different. I should have read through this more closely before closing. This is missing flag support in the clone system call.

@stehufntdev
Copy link
Collaborator

We updated the code to handle clone vfork (i.e. CLONE_VM|CLONE_VFORK|SIGCHLD) the same as vfork so a fix should be out for insider builds soon. As part of this change we realized we have some differences in vfork and those will be patched up later.

@therealkenc
Copy link
Collaborator Author

Thanks @stehufntdev! This is confirmed fixed in 15046. I am guessing 15042 as well, but is also not in the release notes. I'm going to try out Yakkety now since this was the major blocker. #555 will need some grease.

@stehufntdev
Copy link
Collaborator

Thanks for confirming! Yes we are still tracking #555.

@jbleonesio
Copy link

In build 17666.rs_prerelease.180504-1501 the following clone flags are still unsupported (testcase: clone_syscall.zip):

  1. CLONE_CHILD_SETTID
  2. CLONE_IO
  3. CLONE_NEWCGROUP
  4. CLONE_NEWNET
  5. CLONE_NEWUSER

CLONE_CHILD_SETTID lack of support is preventing Flatpak to install applications.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants