mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-07-11 14:02:52 +02:00
@@ -0,0 +1,223 @@
|
||||
Mkhtemp - Hardened mktemp
|
||||
-------------------------
|
||||
|
||||
Create new files and directories randomly as determined by
|
||||
the user's TMPDIR, or fallback. Portable to Linux and BSD.
|
||||
|
||||
NOTE: on Linux, it uses openat2 for i/o, which is more
|
||||
secure. BSDs only have the older openat for now, so
|
||||
mkhtemp uses that there. However, even there, there are
|
||||
several ways in which mkhtemp is better than every
|
||||
previous mktemp.
|
||||
|
||||
```
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
```
|
||||
|
||||
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-
|
||||
mounted by mkhtemp itself, mid-operation. This re-mounting
|
||||
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~~ /jk
|
||||
|
||||
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).
|
||||
@@ -1,47 +1,17 @@
|
||||
/* SPDX-License-Identifier: MIT
|
||||
* Copyright (c) 2026 Leah Rowe <leah@libreboot.org>
|
||||
*
|
||||
* Hardened mktemp (mkhtemp!)
|
||||
*
|
||||
* WORK IN PROGRESS (proof of concept), or, v0.0000001
|
||||
* DO NOT PUT THIS IN YOUR LINUX DISTRO YET.
|
||||
*
|
||||
* Mkhtemp - Hardened mktemp. Create files and directories
|
||||
* randomly as determined by user's TMPDIR, or fallback. It
|
||||
* attemps to provide mitigation against several TOCTOU-based
|
||||
* attacks e.g. directory rename / symlink attacks, and it
|
||||
* generally provides much higher strictness than previous
|
||||
* implementations such as mktemp, mkstemp or even mkdtemp.
|
||||
* I will remove this notice when the code is mature, and
|
||||
* probably contact several of your projects myself.
|
||||
*
|
||||
* It uses several modern features by default, e.g. openat2
|
||||
* and O_TMPFILE on Linux, with additional hardening; BSD
|
||||
* projects only have openat so the code uses that there.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
* See README. This is an ongoing project; no proper docs
|
||||
* yet, and no manpage (yet!) - the code is documentation,
|
||||
* while the specification that it implements evolves.
|
||||
*/
|
||||
|
||||
#if defined(__linux__) && !defined(_GNU_SOURCE)
|
||||
@@ -187,25 +157,6 @@ err_usage:
|
||||
"usage: %s [-d] [-p dir] [template]\n", getnvmprogname());
|
||||
}/*
|
||||
|
||||
|
||||
( >:3 )
|
||||
/| |\
|
||||
/ \
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/ \ */
|
||||
|
||||
Reference in New Issue
Block a user