diff options
Diffstat (limited to 'util/libreboot-utils')
| -rw-r--r-- | util/libreboot-utils/README.md | 223 | ||||
| -rw-r--r-- | util/libreboot-utils/mkhtemp.c | 67 |
2 files changed, 232 insertions, 58 deletions
diff --git a/util/libreboot-utils/README.md b/util/libreboot-utils/README.md new file mode 100644 index 00000000..135b5dbe --- /dev/null +++ b/util/libreboot-utils/README.md @@ -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). diff --git a/util/libreboot-utils/mkhtemp.c b/util/libreboot-utils/mkhtemp.c index 261227cb..7564800a 100644 --- a/util/libreboot-utils/mkhtemp.c +++ b/util/libreboot-utils/mkhtemp.c @@ -1,47 +1,17 @@ /* SPDX-License-Identifier: MIT * Copyright (c) 2026 Leah Rowe <leah@libreboot.org> * - * WORK IN PROGRESS (proof of concept), or, v0.0000001 - * - * 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. - * - * 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. + * Hardened mktemp (mkhtemp!) * - * 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. + * WORK IN PROGRESS (proof of concept), or, v0.0000001 + * DO NOT PUT THIS IN YOUR LINUX DISTRO YET. * - * 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. + * I will remove this notice when the code is mature, and + * probably contact several of your projects myself. * - * 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 ) /| |\ - / \ - - - - - - */ - - - - - - - - - - - - + / \ */ |
