-
-
Notifications
You must be signed in to change notification settings - Fork 4
strange argv handling / mangled argv ? #6
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
Comments
Thanks for the report. This is odd indeed, I wonder if it's a side effect of the way binfmt_misc passes arguments through to the handler. |
On Fedora 40, the package is configured to register itself to binfmt-misc with "POCF" flags. So binfmt-dispatcher receives the calling args several times (argv AND fd 3). |
Happened to me yesterday as well, not on Fedora but Asahi Alarm, but still. We ship |
Mine works after changing this: diff --git a/src/main.rs b/src/main.rs
index b7305ad..3b6a26b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -42,7 +42,7 @@ fn main() {
trace!("Configuration:\n{:#?}", settings);
// Collect command line arguments to pass through
- let args: Vec<OsString> = env::args_os().skip(1).collect();
+ let mut args: Vec<OsString> = env::args_os().skip(1).collect();
trace!("Args:\n{:#?}", args);
if args.is_empty() {
abort("No arguments passed, re-run with --help to learn more.");
@@ -60,13 +60,6 @@ fn main() {
}
}
- // File descriptor 3 is where binfmt_misc typically passes the executable
- let binary: PathBuf = read_link("/proc/self/fd/3").unwrap_or_else(|e| {
- error!("Failed to read the executable from fd#3: {}", e);
- exit(1);
- });
- trace!("Binary: {:#?}", binary);
-
let mut interpreter_id = &settings.defaults.interpreter;
for binary in settings.binaries.values() {
if Path::new(&binary.path) == canonicalize(&args[0]).unwrap() {
@@ -156,8 +149,9 @@ fn main() {
command = Command::new(interpreter_path);
}
- command.arg(binary);
-
+ let new_binary = args.remove(0);
+ args.remove(0);
+ command.arg(new_binary);
// Pass through all the arguments
command.args(&args); Hope this helps. The reason why I'm dropping what is given through fd-3 is we lose the original command line if we did this: fd-3 will give the full path to the actual binary. And some programs check how they are called to perform different actions (decompress vs compress for example). |
Maybe you should open a pull request? |
Ok, there's a few things going on here. Per the spec, when using the O flag the kernel is supposed to open the binary for us and pass the file descriptor to us. This is preferred because it allows the interpreter to work even when the binary isn't readable directly by it. The read_link() hack you see there was the only way I could get it to work. I wasn't expecting this to end up including the args as well. Ideally, we wouldn't do that at all, and just hand over the fd to the underlying implementation to consume. For the time being, I agree it probably makes sense to drop this logic, at least until it can be implemented correctly. If we do that though we should also drop the O from the flags for clarity. As suggested, please feel free to send a PR for this. |
resolves AsahiLinux#6 binfmt-dispatcher gets typically registered to binfmt-misc with flags `POCF`. - `P` will preserve the original argv[0] used - `O` will give the resolved binary (e.g. after symlink derefence) as an open file in fd 3 - but we can't use it as-is as FEX (at least) doesn't support taking "pathname" (execve) as an open file descriptor. - `C` and `F` are irrelevant here. To support properly binary file already open as fd 3, FEX needs to be patched to use `fexecve(3, argv, env)` kind of call when requested, it doesn't appear to support it yet.
resolves AsahiLinux#6 binfmt-dispatcher gets typically registered to binfmt-misc with flags `POCF`. - `P` will preserve the original argv[0] used - `O` will give the resolved binary (e.g. after symlink derefence) as an open file in fd 3 - but we can't use it as-is as FEX (at least) doesn't support taking "pathname" (execve) as an open file descriptor. - `C` and `F` are irrelevant here. To support properly binary file already open as fd 3, FEX needs to be patched to use `fexecve(3, argv, env)` kind of call when requested, it doesn't appear to support it yet. Signed-off-by: Fabrice A. Marie <[email protected]>
I'm running Fedora 40 in a UTM VM on MacOS, on an M1 chip.
The relevant software versions I have are:
To test my setup, I made a small
ls
equivalent in standard C, and compiled it under Fedora 40 x86_64. I then copy it into my as/var/tmp/fexls
. The source code for that test is attached asfexls.c
. It expects a path argument on the command line and lists the files at that path likels
would. Again this is just to test my fex setup.When I run
/var/tmp/fexls /var/tmp
from my shell, I get this:Why is my argv mangled?
When I run directly (without binfmt-dispatcher)
FEXInterpreter /var/tmp/fexls /var/tmp/
I get the correct output:My binfmt-dispatcher configuration file
/etc/binfmt-dispatcher.toml
is standard (I just disabled muvm only):Am I doing something wrong? Or is there a bug here?
The C code for
fexls.c
:and I compile it with:
gcc -Wall -Wextra -O2 -o fexls fexls.c
.I can confirm the ELF is indeed x86_64:
The text was updated successfully, but these errors were encountered: