Closed Toby222 closed 2 years ago
The "no such file or directory" is kind of misleading. It doesn't refer to the actual program (as you can have proven, it's really there) but to the kernel failing to execute it.
When running in a chroot you need to install in it also the interpreter for your CGI script and all of its dependencies (shared libraries.) The "no such file or directory" is the kernel failing to find the interpreter (sh
, perl
, python
, ...) or ld.so failing to load a shared library in the chroot.
(if your CGI script is a compiled program, for e.g. C, Go, rust, ..., you could try to statically compile and copy it in the chroot, it should "just work" then)
Yep, running CGI scripts in a chroot is kind of a pain. gmid also supports FastCGI and, from 1.8 onwards, a reverse-proxying facility that can help alleviate the pain with plain CGI under chroot.
Oh, I almost forgot
(I needed to SC_ALLOW fstatat64, _llseek, and sigreturn to stop errors there)
If you turn that into a PR I'll be happy to merge it!
That's what I initially thought, so I first tried copying sh to the chroot, then made a cgi ... "script" that's just a statically linked C executable, so there should be absolutely no dependencies for it, neither of which worked.
Just to be sure, what ldd hello
(or how the script is named) says? (you could also use file hello
on some systems to tell if an executable is statically linked or not.)
I can't reproduce it on OpenBSD but will try with arch later.
thanks :)
P.S.: copying sh
may not be enough. You need to copy also the shared libraries it depends on (ldd /bin/sh
helps.)
It's decidedly a statically linked file, sadly
gmid is quite strict when it comes to CGI scripts. It inspects the cgi reply for logging purposes but if it cannot read a valid reply it interrupts the cgi script and return 42.
The gemini reply header should be terminate with CRLF (i.e. \r\n
) not by a \n
alone. Since gmid can't find the \r\n
sequence in the first 1024 character of the script output, it discards it and return a 42 CGI error, otherwise it would end up serving an invalid reply.
So, changing your example code to use \r\n
should make it work.
(I should probably add some more logging for these cases so it's easier to understand why gmid is discarding the script output.)
Welp, that worked. I'm not sure why I got a file not found error from execvp if it ran correctly but the output was discarded by gmid. Unless I missed something when debugging and errno was set somewhere else internally.
(Yes some logging would probably help a long way ^^;)
Well, there were two different issues that caused the same return code: the first one being the shell (or some linked library) not being found and the other the malformed header. I'll add some logging for the "read malformed header" case, it affects the reverse proxy case too.
thanks!
Every time I make a request to a cgi file to my gmid server, I get a
42 CGI error
. After some debugging, it seems that this execvp call always fails withNo such file or directory
, despite the file definitely existing and being executable by the gmid user.The regression tests work fine, so I think it might be an error with chroot being configured I've been trying to debug this with low-to-mediocre C-skill but ran out of ideas.
I'm running
gmid
on my RasPi with Arch arm for armv7 architecture. (I needed toSC_ALLOW
fstatat64, _llseek, and sigreturn to stop errors there)I'm using this config: