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

Launcher fails with "execv failed: Permission denied (13)" #44

Open
nirvdrum opened this issue Nov 23, 2021 · 2 comments
Open

Launcher fails with "execv failed: Permission denied (13)" #44

nirvdrum opened this issue Nov 23, 2021 · 2 comments

Comments

@nirvdrum
Copy link

I recently installed JRuby 9.3.1.0 using ruby-build. The ruby-build recipe will install the jruby-launcher gem, which will replace bin/jruby in the distribution. When I try to run JRuby, I see the following error:

execv failed: Permission denied (13)

If I fetch the JRuby tarball and run it locally with the original bin/jruby, everything works. I've narrowed the issue down to the replaced launcher from jruby-launcher. Moreover, I've discovered I only get the failure when the JAVA_HOME env var is not set. With other Java applications, that isn't an issue as java is available on the PATH.

Currently, my java command is coming from Homebrew for Linux:

> which java
/home/linuxbrew/.linuxbrew/bin/java

> ls -l (which java)
lrwxrwxrwx 1 nirvdrum nirvdrum 29 Sep 22 14:59 /home/linuxbrew/.linuxbrew/bin/java -> ../Cellar/openjdk/17/bin/java*

> readlink -f (which java)
/home/linuxbrew/.linuxbrew/Cellar/openjdk/17/libexec/bin/java

If I set my JAVA_HOME env var to /home/linuxbrew/.linuxbrew/Cellar/openjdk/17 the launcher begins working.

Here is the strace output when trying to start the launcher:

> strace ./jruby -v
execve("./jruby", ["./jruby", "-v"], 0x7ffed4255d18 /* 79 vars */) = 0
brk(NULL)                               = 0x560ea10cd000
arch_prctl(0x3001 /* ARCH_??? */, 0x7ffe50c88c00) = -1 EINVAL (Invalid argument)
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=109534, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 109534, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f45ae8b1000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libstdc++.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\0\340\22\n\0\0\0\0\0"..., 832) = 832
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=2182368, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f45ae8af000
mmap(NULL, 2197632, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f45ae696000
mmap(0x7f45ae72f000, 1060864, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x99000) = 0x7f45ae72f000
mmap(0x7f45ae832000, 442368, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x19c000) = 0x7f45ae832000
mmap(0x7f45ae89e000, 57344, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x207000) = 0x7f45ae89e000
mmap(0x7f45ae8ac000, 10368, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f45ae8ac000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\3405\0\0\0\0\0\0"..., 832) = 832
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=104984, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 107592, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f45ae67b000
mprotect(0x7f45ae67e000, 90112, PROT_NONE) = 0
mmap(0x7f45ae67e000, 73728, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f45ae67e000
mmap(0x7f45ae690000, 12288, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x15000) = 0x7f45ae690000
mmap(0x7f45ae694000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x18000) = 0x7f45ae694000
close(3)                                = 0
openat(AT_FDCWD, "/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\0\240\206\2\0\0\0\0\0"..., 832) = 832
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
pread64(3, "\4\0\0\0 \0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0"..., 48, 848) = 48
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0+H)\227\201T\214\233\304R\352\306\3379\220%"..., 68, 896) = 68
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=1983576, ...}, AT_EMPTY_PATH) = 0
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
mmap(NULL, 2012056, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f45ae48f000
mmap(0x7f45ae4b5000, 1486848, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x26000) = 0x7f45ae4b5000
mmap(0x7f45ae620000, 311296, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x191000) = 0x7f45ae620000
mmap(0x7f45ae66c000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1dc000) = 0x7f45ae66c000
mmap(0x7f45ae672000, 33688, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f45ae672000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libm.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\0\300\363\0\0\0\0\0\0"..., 832) = 832
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=1364824, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 1364240, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f45ae341000
mmap(0x7f45ae350000, 679936, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xf000) = 0x7f45ae350000
mmap(0x7f45ae3f6000, 618496, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xb5000) = 0x7f45ae3f6000
mmap(0x7f45ae48d000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x14b000) = 0x7f45ae48d000
close(3)                                = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f45ae33f000
arch_prctl(ARCH_SET_FS, 0x7f45ae340180) = 0
mprotect(0x7f45ae66c000, 12288, PROT_READ) = 0
mprotect(0x7f45ae48d000, 4096, PROT_READ) = 0
mprotect(0x7f45ae694000, 4096, PROT_READ) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f45ae33d000
mprotect(0x7f45ae89e000, 45056, PROT_READ) = 0
mprotect(0x560e9fe23000, 4096, PROT_READ) = 0
mprotect(0x7f45ae8fe000, 8192, PROT_READ) = 0
munmap(0x7f45ae8b1000, 109534)          = 0
brk(NULL)                               = 0x560ea10cd000
brk(0x560ea10ee000)                     = 0x560ea10ee000
readlink("/proc/self/exe", "/tmp/jruby/jruby-9.3.1.0/bin/jru"..., 4096) = 34
newfstatat(AT_FDCWD, "/tmp/jruby/jruby-9.3.1.0/bin/jruby", {st_mode=S_IFREG|0755, st_size=97176, ...}, 0) = 0
access("/dev/urandom", R_OK)            = 0
newfstatat(AT_FDCWD, "/home/nirvdrum/.rbenv/shims/java", 0x7ffe50c877a0, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/opt/JetBrains/bin/java", 0x7ffe50c877a0, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/home/nirvdrum/.rbenv/bin/java", 0x7ffe50c877a0, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/home/nirvdrum/.cargo/bin/java", 0x7ffe50c877a0, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/home/nirvdrum/dev/bin/java", 0x7ffe50c877a0, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/opt/wine-staging/bin/java", 0x7ffe50c877a0, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/home/nirvdrum/.local/bin/java", 0x7ffe50c877a0, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/home/nirvdrum/bin/java", 0x7ffe50c877a0, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/home/nirvdrum/.opam/4.11.1/bin/java", 0x7ffe50c877a0, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/home/nirvdrum/.cargo/bin/java", 0x7ffe50c877a0, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/home/nirvdrum/.local/bin/java", 0x7ffe50c877a0, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/home/nirvdrum/bin/java", 0x7ffe50c877a0, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/local/sbin/java", 0x7ffe50c877a0, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/local/bin/java", 0x7ffe50c877a0, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/sbin/java", 0x7ffe50c877a0, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/bin/java", {st_mode=S_IFDIR|0755, st_size=11, ...}, 0) = 0
access("/usr/libexec/java_home", R_OK|X_OK) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/bin/java", {st_mode=S_IFLNK|0777, st_size=22, ...}, AT_SYMLINK_NOFOLLOW) = 0
readlink("/usr", 0x7ffe50c85f40, 1023)  = -1 EINVAL (Invalid argument)
readlink("/usr/bin", 0x7ffe50c85f40, 1023) = -1 EINVAL (Invalid argument)
readlink("/usr/bin/java", "/etc/alternatives/java", 1023) = 22
readlink("/etc", 0x7ffe50c85f40, 1023)  = -1 EINVAL (Invalid argument)
readlink("/etc/alternatives", 0x7ffe50c85f40, 1023) = -1 EINVAL (Invalid argument)
readlink("/etc/alternatives/java", "/usr/lib/jvm/java-1.15.0-openjdk"..., 1023) = 38
readlink("/usr", 0x7ffe50c85f40, 1023)  = -1 EINVAL (Invalid argument)
readlink("/usr/lib", 0x7ffe50c85f40, 1023) = -1 EINVAL (Invalid argument)
readlink("/usr/lib/jvm", 0x7ffe50c85f40, 1023) = -1 EINVAL (Invalid argument)
readlink("/usr/lib/jvm/java-1.15.0-openjdk-amd64", "java-15-openjdk-amd64", 1023) = 21
readlink("/usr/lib/jvm/java-15-openjdk-amd64", 0x7ffe50c85f40, 1023) = -1 EINVAL (Invalid argument)
newfstatat(AT_FDCWD, "/tmp/jruby/jruby-9.3.1.0/lib/jni", {st_mode=S_IFDIR|0775, st_size=440, ...}, 0) = 0
uname({sysname="Linux", nodename="melchior-linux", ...}) = 0
openat(AT_FDCWD, "/tmp/jruby/jruby-9.3.1.0/lib/jni", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3
newfstatat(3, "", {st_mode=S_IFDIR|0775, st_size=440, ...}, AT_EMPTY_PATH) = 0
getdents64(3, 0x560ea10df4e0 /* 22 entries */, 32768) = 768
getdents64(3, 0x560ea10df4e0 /* 0 entries */, 32768) = 0
close(3)                                = 0
access("/usr/lib/lib/modules", R_OK)    = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/release", O_RDONLY) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/tmp/jruby/jruby-9.3.1.0/lib/jruby.jar", {st_mode=S_IFREG|0644, st_size=15651642, ...}, 0) = 0
newfstatat(AT_FDCWD, "/tmp/jruby/jruby-9.3.1.0/lib/jruby.jar", {st_mode=S_IFREG|0644, st_size=15651642, ...}, 0) = 0
newfstatat(AT_FDCWD, "/tmp/jruby/jruby-9.3.1.0/lib/jruby-complete.jar", 0x7ffe50c87280, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/tmp/jruby/jruby-9.3.1.0/lib", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3
newfstatat(3, "", {st_mode=S_IFDIR|0755, st_size=100, ...}, AT_EMPTY_PATH) = 0
brk(0x560ea1110000)                     = 0x560ea1110000
getdents64(3, 0x560ea10e7990 /* 5 entries */, 32768) = 128
getdents64(3, 0x560ea10e7990 /* 0 entries */, 32768) = 0
brk(0x560ea1108000)                     = 0x560ea1108000
close(3)                                = 0
newfstatat(AT_FDCWD, "/usr/lib/jvm/java-15-openjdk-amd64", {st_mode=S_IFDIR|0755, st_size=11, ...}, 0) = 0
execve("/usr/lib/jvm/java-15-openjdk-amd64", ["/usr/lib/jvm/java-15-openjdk-amd"..., "-Djdk.home=/usr/lib", "-Djruby.home=/tmp/jruby/jruby-9."..., "-Djruby.script=jruby", "-Djruby.shell=/bin/sh", "-Djffi.boot.library.path=/tmp/jr"..., "-Xss2048k", "-Dsun.java.command=org.jruby.Mai"..., "-Xbootclasspath/a:/tmp/jruby/jru"..., "-cp", "", "-Djava.security.egd=file:/dev/ur"..., "org/jruby/Main", "-v"], 0x7ffe50c88d70 /* 79 vars */) = -1 EACCES (Permission denied)
newfstatat(1, "", {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0xa), ...}, AT_EMPTY_PATH) = 0
write(1, "execv failed: Permission denied "..., 37execv failed: Permission denied (13)
) = 37
exit_group(255)                         = ?
+++ exited with 255 +++

This looks like a similar situation to #31.

@nirvdrum
Copy link
Author

Debugging this with @headius, it looks like there are two errors. First, my /usr/bin/java, through a chain of symlinks, points at a JVM directory rather than the binary. This appears to be a misuse of Ubuntu's update-alternatives command. I hadn't caught it because java gets picked up in a later PATH entry when working in my shell. The second issue is the launcher, while iterating through PATH entries, finds the bad /usr/bin/java value and assumes it's an executable file and stops searching at that point. Thus, the resolution logic ends up being different from the shell.

I'll fix this on my machine, but it's probably worth making the launcher a bit more resilient. If nothing else, it could present the user with a neater error message.

@headius
Copy link
Member

headius commented Dec 7, 2021

The simple fix will be to check that the java command we find in PATH actually resolves to an executable file rather than a directory. I believe that will resolve this for @nirvdrum and any future users with peculiar java dirs in their PATH.

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

2 participants