89luca89 / 89luca89/distrobox

[Error] distrobox-export --bin silently overwrites an existing binary on the host

Open
#2,200 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
13k
Forks
541
Avg merge
20h 47m
Merged PRs (30d)
4

Description

**Describe the bug**

`distrobox-export --bin` replaces whatever is already sitting at the destination, without checking and without saying anything. If the host has a binary of the same name in the export path, it is gone and a wrapper script is there instead.

I came at this sideways. I keep two boxes with separate home directories so that the same command line tool runs with completely separate config in each, and I was about to export one of them to the host when it occurred to me that my own copy of that tool lives in `~/.local/bin` — which is the default export path, under exactly the name the wrapper would take. So I tried it with a throwaway name first, and my file was replaced without a word:

```console
$ printf '#!/bin/sh\necho "host original"\n' > ~/.local/bin/demo-tool && chmod +x ~/.local/bin/demo-tool

$ distrobox enter mybox -- distrobox-export --bin /usr/bin/demo-tool
/usr/bin/demo-tool from mybox exported successfully in /home/user/.local/bin.
OK!

$ head -3 ~/.local/bin/demo-tool
#!/bin/sh
# distrobox_binary
# name: mybox
```

No prompt, no warning, exit status OK. Had I run that against the real name, I'd have swapped my own installation for a wrapper that shells back into the container, and it would have taken me a while to work out why.

Looking at `export_binary`, there is a writability test and then a straight redirect:

```sh
# test if we have writing rights on the file
if ! touch "${dest_file}"; then
printf >&2 "Error: cannot create destination file %s.\n" "${dest_file}"
return 1
fi

# create the script from template and write to file
if generate_script > "${dest_file}"; then
```

`touch` succeeds on a file that already exists, so that check passes happily for someone else's binary. What makes me think this is an oversight rather than a decision is that the delete path is careful about exactly this — `--delete` refuses when the target doesn't contain `distrobox_binary`, so it won't remove a file it didn't create. Export has no matching guard.

**To Reproduce**

1. Put any executable at `~/.local/bin/demo-tool` on the host.
2. Put an executable of the same name in a box, e.g. `/usr/bin/demo-tool`.
3. From the box, run `distrobox-export --bin /usr/bin/demo-tool`.
4. The host file is now the wrapper. The original is not backed up anywhere.

**Expected behavior**

Refuse when the destination exists and isn't itself a distrobox export, the mirror image of what `--delete` already does — with a flag to override for anyone who wants the current behaviour. Overwriting a previous export of the same binary is obviously fine and should stay silent.

**Logs**

Nothing useful to attach — the command reports success, because from its point of view it succeeded.

**Desktop (please complete the following information):**

- podman
- podman 5.8.4
- distrobox 1.8.2.5, and this is unchanged on `main`
- Fedora 44
- distribution package

On the v2 question in the template: I checked before filing. `internal/inside-distrobox/assets/distrobox-export` on `main` differs from 1.8.2.5 by 23 lines, and all of them are the `DISTROBOX_ENTER_PATH` → `DISTROBOX_PATH` rework. `export_binary` is untouched, so v2 behaves the same way.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.