
Nerd Sniped by BINFMT_MISC - kingori
https://blog.jessfraz.com/post/nerd-sniped-by-binfmt_misc/
======
jaytaylor
Too bad the more narrow minded segment of the HN population appears to have
buried this one out of spite.. because this is some super pro badass shit,
packaged in a hilarious format by jessfraz. Guess it's not everyone's kind of
humor, a real tradgedy if you ask me.

Can you imagine a future where you don't have to install runtimes to run
things anymore because they are all distributed with everything you need? It
would be amazing and magical in many ways. No more reinstalling the OS because
things got weird after X went berserk.

Being forced to pollute my perfect, pristine machines with multiple versions
of Python, or having to even commit to a single version of anything seems less
good than not having to.

I'd rather burn the extra HDD space to avoid risky installs messing up the
system.

~~~
piva00
What you are describing is just a statically linked binary, the world of
computing moved away from this well before I started my career but there are
pros and cons about it, not only related to disk space.

~~~
pyvpx
what are the pros of dynamically linked binaries, not related to disk and
memory usage?

~~~
pog290
when a security vulnerability is found, you can fix the relevant library
without recompiling all the binaries that are linked to it.

------
modeless
I love the idea of executable single-file containers. I'd take it even
farther. I've recently discovered a way to make polyglot scripts that are
simultaneously executable on Linux, Mac, and Windows[1]. It would be pretty
easy to embed binaries in these scripts, and by simply embedding a binary for
each OS you'd have a cross-platform binary single-file application.

Of course three copies of the binary is not ideal, but it shouldn't even be
necessary. With some deep hacking the platform-specific code could be
minimized and the rest of the binary could be shared. Wouldn't it be fun to
have truly platform-independent binary executables?

[1]
[https://gist.github.com/jdarpinian/6860ddfd92b5b458a20ab6055...](https://gist.github.com/jdarpinian/6860ddfd92b5b458a20ab6055583bc3e)

~~~
heavenlyblue
I don't really see this.

What about packaging - e.g. this file having a proper icon on Windows? What
about distribution via the app market platforms?

How do I go about upgrading the application?

------
EtDybNuvCu
Cool stuff. nixpkgs not too long ago gained support for programmatically
declaring binfmt_misc configuration:
[https://github.com/NixOS/nixpkgs/commit/c64639b54caa6595f9ef...](https://github.com/NixOS/nixpkgs/commit/c64639b54caa6595f9ef62ed2548593b5fe5db66)

------
LinuxBender
The equiv command in Microsoft Windows is "assoc". You can run it with no args
to see what programs are associated with what extensions in Windows. I mention
this because of a security concern.

i.e.

    
    
        assoc
    
        assoc .vbs=txtfile
        assoc .mp4=WMP11.AssocFile.MP4
    

Perhaps it may be worth considering security practices for BINFMT_MISC before
people find any sub-optimal defaults. In the past, clever people would exploit
some of the default associations that applications would insert on Windows
desktops. At some point, desktop file exploring apps may decide to hide "known
extensions. The desktop will also leverage this association.

~~~
cyphar
You need to be root to change binfmt_misc's configuration, so it's not
analgous to Windows' file associations (which the user can also change).

I also believe that xdg-open (and the XDG scheme) is more similar to Windows'
file associations than binfmt_misc, since XDG is more of a user-facing thing.

~~~
LinuxBender
I believe you need to be a on an admin account in Windows to change global
file associations. In fairness though, most people are logged in as an
Administrator.

~~~
auscompgeek
You can also have user file associations on Windows though.

~~~
LinuxBender
Certainly. I supposed the point I am trying to make is that a lot of old
windows behaviors that lead to security incidents are finding their way into
non-desktop linux machines. My servers have binfmt mounted, for example.
SystemD appears to be bringing in a bit of desktop behavior to both desktops
and servers. Maybe this is ok if people are aware?

~~~
cyphar
binfmt_misc has existed for a much longer time than systemd (it was originally
added in _1997_ [1]). It has been used for many features like emulating
binaries "natively" by setting up binfmt_misc so that binaries are executed
inside QEMU if the architecture is different. It has had many other similar
uses for decades.

I'm not a fan of systemd in the slightest, but blaming systemd for an in-
kernel facility that has existed since the mid-90s (and isn't even used by
systemd to my knowledge) doesn't make any sense.

[1]:
[https://elixir.bootlin.com/linux/v4.15.7/source/fs/binfmt_mi...](https://elixir.bootlin.com/linux/v4.15.7/source/fs/binfmt_misc.c)

------
majewsky
FWIW, you don't need to fiddle around with binfmt_misc (which requires root
permissions) to execute a Go program as a script. The following shebang works:

    
    
       ///bin/true; exec /usr/bin/env go run "$0" "$@"
    

See
[https://stackoverflow.com/a/30082862/334761](https://stackoverflow.com/a/30082862/334761)
for detailed explanation what's going on there. The only downside is that all
exit codes != 0 get mapped to exit code 1 by `go run`. It will show the
original exit code on stderr instead.

~~~
zbentley
That's quite cool, but minor point of pedantry: that's not a shebang. A
shebang is interpreted by the operating system, which uses it to find and
launch an interpreter for a file.

Compared to that, the example snipped you provided is doing many more, and
different things:

1\. Launches a shell language interpreter: usually the system default POSIX-
compliant sh, but could (rarely) be something else. Compared to "read the
first line, and if it's a shebang launch python or whatever" in the kernel,
this is massively complicated: it starts another whole runtime. Run "strace"
on a file that just does "///bin/true; sleep 1000" to see exactly how much is
happening just for that shell launch.

1\. Executes /bin/true. It's probably present everywhere, and probably the
right program, but still an assumption.

2\. Evaluates a bunch of string slinging statements in the shell to
interpolate arguments, then replaces itself via "exec".

3\. Launches /usr/bin/env (hopefully the right program, and hopefully in the
right place) to find the go interpreter.

4\. env (hopefully) also calls "exec" again and then launches the go run
command to start the compilation/execution sequence.

That's a _lot_ of stuff. Pretty garden-variety stuff, but still a lot of
additional complexity. A shebang adds none of it, though "trampolining"
shebangs (which themselves are just programs to do basically this) can
reintroduce some internally.

That's the beauty of the shebang as a trick for truly interpreted languages:
it's extremely direct and simple as a means of getting your code executing on
your desired runtime.

------
nwmcsween
Or another cool idea use .preinit_array for shared bins and .init_array for
static bins and inject a .seccomp, .unshare, etc section that gets called in
the preinit, init. This way you can support both shared and static bins with a
tiny size increase.

------
bradknowles
I’m confused. Is this a Microsoft Windows thing?

------
JepZ
> Hacker news, you can shove your comments right up your

...

~~~
sbierwagen
Yes, very odd. Don't think I'll be upvoting this submission.

>Imagine if an entire OS had all the languages packaged this way so that
everything could be “dot slashed” and executed but without actually installing
the language to your host operating system.

This has been technically possible for decades, but the disadvantages (startup
time, memory use, disk use) outweigh the advantages. (better security,
assuming no VM escape bugs, which is an assumption you absolutely can't make,
considering the long list of Xen CVEs) Breezily asserting the superiority of
this solution without acknowledging any possible downsides is also strange...
more press release than blog post.

~~~
Godel_unicode
Containers aren’t VMs. There’s no VM to escape, and Xen has nothing whatsoever
to do with containers. Ironically, there’s a really good explanation of this
topic which was given by the author at a conference.

Also, this is a write-up about something cool that author discovered. It’s
about the fact that dot slash isn’t magic, but rather a feature which can be
(ab)used to do something out of the ordinary. Sounds like a blog post to me.

~~~
sbierwagen
An excellent and helpful correction. But security-wise chroot/runc is _even
worse_ than Xen, since the attack surface is so much bigger!

[https://nvd.nist.gov/vuln/search/results?adv_search=false&fo...](https://nvd.nist.gov/vuln/search/results?adv_search=false&form_type=basic&results_type=overview&search_type=all&query=docker)

[https://nvd.nist.gov/vuln/search/results?adv_search=false&fo...](https://nvd.nist.gov/vuln/search/results?adv_search=false&form_type=basic&results_type=overview&search_type=all&query=chroot)

~~~
jessfraz
See first comment about how it's a pivot root and if you are going to claim
containers are insecure please first capture the flag on
[https://contained.af](https://contained.af) or gfy

~~~
marcosnils
Thanks jessie and cyphar for making HAN great again!

