mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-07-11 14:02:52 +02:00
4d4285e63c
Signed-off-by: Leah Rowe <leah@libreboot.org>
248 lines
9.3 KiB
Markdown
248 lines
9.3 KiB
Markdown
Mkhtemp - Hardened mktemp
|
|
-------------------------
|
|
|
|
Just like normal mktemp, but hardened.
|
|
|
|
Create new files and directories randomly as determined by
|
|
the user's TMPDIR, or fallback. These temporary files and
|
|
directories can be generated from e.g. shell scripts, running
|
|
mkhtemp. There is also a library that you could use in your
|
|
program. Portable to Linux and BSD. **WORK IN PROGRESS.
|
|
This is a very new project. Expect bugs - a stable release
|
|
will be announced, when the code has matured.**
|
|
|
|
A brief summary of *why* mkhtemp is more secure (more
|
|
details provided later in this readme - please also
|
|
read the source code):
|
|
|
|
Detect and mitigate symlink attacks, directory access
|
|
race conditions, unsecure TMPDIR (e.g. bad enforce sticky
|
|
bit policy on world writeable dirs), implement in user
|
|
space a virtual sandbox (block directory escape and resolve
|
|
paths by walking from `/` manually instead of relying on
|
|
the kernel/system), voluntarily error out (halt all
|
|
operation) if accessing files you don't own - that's why
|
|
sticky bits are checked for example, even when you're root.
|
|
|
|
Mkhtemp is designed to be the most secure implementation
|
|
possible, of mktemp, offering a heavy amount of hardening
|
|
over traditional mktemp.
|
|
|
|
i.e. please read the source code
|
|
|
|
```
|
|
/*
|
|
* WARNING: WORK IN PROGRESS.
|
|
* Do not use this software in
|
|
* your distro yet. It's ready
|
|
* when it's ready. Read the src.
|
|
*
|
|
* What you see is an early beta.
|
|
*
|
|
* Please do not merge this in
|
|
* your Linux distro package repo
|
|
* yet (unless maybe you're AUR).
|
|
*/
|
|
```
|
|
|
|
Supported mktemp flags:
|
|
|
|
```
|
|
mkhtemp: usage: mkhtemp [-d] [-p dir] [template]
|
|
|
|
-p DIR <-- set directory, overriding TMPDIR
|
|
-d <-- make a directory instead of a file
|
|
-q <-- silence errors (exit status unchanged)
|
|
```
|
|
|
|
The rest of them will be added later (the same ones
|
|
that GNU and BSD mktemp implement). With these options,
|
|
you can generate files/directories already.
|
|
|
|
You can also write a template at the end. e.g.
|
|
|
|
```
|
|
mkhtemp -d -p path/to/directory vickysomething_XXXXXXXXXXX
|
|
```
|
|
|
|
On most sane/normal setups, the program should already
|
|
actually work, but please know that it's very different
|
|
internally than every other mktemp implementation.
|
|
|
|
Read the source code if you're interested. As of this
|
|
time of writing, mkhtemp is very new, and under
|
|
development. A stable release will be announced when ready.
|
|
|
|
### What does mkhtemp do differently?
|
|
|
|
This software attempts to provide mitigation against
|
|
several TOCTOU-based
|
|
attacks e.g. directory rename / symlink / re-mount, and
|
|
generally provides much higher strictness than previous
|
|
implementations such as mktemp, mkstemp or even mkdtemp.
|
|
It uses several modern features by default, e.g. openat2
|
|
and `O_TMPFILE` (plus `O_EXCL`) on Linux, with additional
|
|
hardening; BSD projects only have openat so the code uses
|
|
that there, but some (not all) of the kinds of checks
|
|
Openat2 enforces are done manually (in userspace).
|
|
|
|
File system sandboxing in userspace (pathless discovery,
|
|
and operations are done only with FDs). At startup, the
|
|
root directory is opened, and then everything is relative
|
|
to that.
|
|
|
|
Many programs rely on mktemp, and they use TMPDIR in a way
|
|
that is quite insecure. Mkhtemp intends to change that,
|
|
quite dramatically, with: userspace sandbox (and use OS
|
|
level options e.g. OBSD pledge where available), constant
|
|
identity/ownership checks on files, MUCH stricter ownership
|
|
restrictions (e.g. enforce sticky bit policy on world-
|
|
writeable tmpdirs), preventing operation on other people's
|
|
files (only your own files) - even root is restricted,
|
|
depending on how the code is compiled. Please read the code.
|
|
|
|
Basically, the gist of it is that normal mktemp *trusts*
|
|
your system is set up properly. It will just run however
|
|
you tell it to, on whatever directory you tell it to, and
|
|
if you're able to write to it, it will write to it.
|
|
Some implementations (e.g. OpenBSD one) do some checks,
|
|
but not all of them do *all* checks. The purpose of
|
|
mkhtemp is to be as strict as possible, while still being
|
|
reliable enough that people can use it. Instead of catering
|
|
to legacy requirements, mkhtemp says that systems should
|
|
be secure. So if you're running in an insecure environment,
|
|
the goal of mkhtemp is to *exit* when you run it; better
|
|
this than files being corrupted.
|
|
|
|
Security and reliability are the same thing. They both
|
|
mean that your computer is behaving as it should, in a
|
|
manner that you can predict.
|
|
|
|
It doesn't matter how many containers you have, or how
|
|
memory-safe your programming language is, the same has
|
|
been true forever: code equals bugs, and code usually
|
|
has the same percentage of bugs, so more code equals
|
|
more bugs. Therefore, highly secure systems (such as
|
|
OpenBSD) typically try to keep their code as small and
|
|
clean as possible, so that they can audit it. Mkhtemp
|
|
assumes that your system is hostile, and is designed
|
|
accordingly.
|
|
|
|
What?
|
|
-----
|
|
|
|
This is the utility version, which makes use of the also-
|
|
included library. No docs yet - source code are the docs,
|
|
and the (ever evolving, and hardening) specification.
|
|
|
|
This was written from scratch, for use in nvmutil, and
|
|
it is designed to be portable (BSD, Linux). Patches
|
|
very much welcome.
|
|
|
|
Caution
|
|
-------
|
|
|
|
This is a new utility. Expect bugs.
|
|
|
|
```
|
|
WARNING: This is MUCH stricter than every other mktemp
|
|
implementation, even more so than mkdtemp or
|
|
the OpenBSD version of mkstemp. It *will* break,
|
|
or more specifically, reveal the flaws in, almost
|
|
every major critical infrastructure, because most
|
|
people already use mktemp extremely insecurely.
|
|
```
|
|
|
|
This tool is written by me, for me, and also Libreboot, but
|
|
it will be summitted for review to various Linux distros
|
|
and BSD projects once it has reached maturity.
|
|
|
|
### Why was this written?
|
|
|
|
Atomic writes were implemented in nvmutil (Libreboot's
|
|
Intel GbE NVM editor), but one element remained: the
|
|
program mktemp, itself, which has virtually no securitty
|
|
checks whatsoever. GNU and BSD implementations use
|
|
mkstemp now, which is a bit more secure, and they offer
|
|
additional hardening, but I wanted to be reasonably
|
|
assured that my GbE files were not being corrupted in
|
|
any way, and that naturally led to writing a hardened
|
|
tool. It was originally just going to be for nvmutil,
|
|
but then it became its own standard utility.
|
|
|
|
Existing implementations of mktemp just simply do not
|
|
have sufficient checks in place to prevent misuse. This
|
|
tool, mkhtemp, intentionally focuses on being secure
|
|
instead of easy. For individuals just running Linux on
|
|
their personal machine, it might not make much difference,
|
|
but corporations and projects running computers for lots
|
|
of big infrastructure need something reliable, since
|
|
mktemp is just one of those things everyone uses.
|
|
Every big program needs to make temporary files.
|
|
|
|
But the real reason I wrote this tool is because, it's
|
|
fun, and because I wanted to challenge myself.
|
|
|
|
Roadmap
|
|
-------
|
|
|
|
Some things that are in the near future for mkhtemp
|
|
development:
|
|
|
|
Thoroughly document every known case of CVEs in the wild,
|
|
and major attacks against individuals/projects/corporations
|
|
that were made possible by mktemp - that mkhtemp might
|
|
have prevented. There are several.
|
|
|
|
More hardening; still a lot more that can be done, depending
|
|
on OS. E.g. integrate FreeBSD capsicum.
|
|
|
|
Another example: although usually reliable, comparing the
|
|
inode and device of a file/directory isn't by itself sufficient.
|
|
There are other checks that mkhtemp does; for example I could
|
|
implement it so that directories are more aggressively re-
|
|
opened by mkhtemp itself, mid-operation. This re-opening
|
|
would be quite expensive computationally, but it would then
|
|
allow us to re-check everything, since we store state from
|
|
when the program starts.
|
|
|
|
Tidy up the code: the current code was thrown together in
|
|
a week, and needs tidying. A proper specification should be
|
|
written, to define how it works, and then the code should
|
|
be auditted for compliance. A lot of the functions are
|
|
also quite complex and do a lot; they could be split up.
|
|
|
|
Right now, mkhtemp mainly returns a file descriptor and
|
|
a path, after operation, ironic given the methods it uses
|
|
while opening your file/dir. After it's done, you then have
|
|
to handle everything again. Mkhtemp could keep everything
|
|
open instead, and continue to provide verification; in
|
|
other words, it could provide a completely unified way for
|
|
Linux/BSD programs to open files, write to them atomically,
|
|
and close. Programs like Vim will do this for example, or
|
|
other text editors, but every program has its own way. So
|
|
what mkhtemp could do is provide a well-defined API alongside
|
|
its mktemp hardening. Efforts would be made to avoid
|
|
feature creep, and ensure that the code remains small and
|
|
nimble.
|
|
|
|
Compatibility mode: another thing is that mkhtemp is a bit
|
|
too strict for some users, so it may break some setups. What
|
|
it could do is provide a compatibility mode, and in this
|
|
mode, behave like regular mktemp. That way, it could become
|
|
a drop-in replacement on Linux distros (and BSDs if they
|
|
want it), while providing a more hardened version and
|
|
recommending that where possible.
|
|
|
|
~~Rewrite it in rust~~ (nothing against it though, I just like C89 for some reason)
|
|
|
|
Also, generally document the history of mktemp, and how
|
|
mkhtemp works in comparison.
|
|
|
|
Also a manpage.
|
|
|
|
Once all this is done, and the project is fully polished,
|
|
then it will be ready for your Linux distro. For now, I
|
|
just use it in nvmutil (and I also use it on my personal
|
|
computer).
|