One of the big mistakes of Linux is that when you create a file with
open() and O_CREAT and the file already exists as dangling symlink that
the symlink will be followed and the file created that it points to.
This has resulted in many vulnerabilities, and triggered the creation of
the O_MOFOLLOW flag, addressing the problem.
O_NOFOLLOW is less than ideal in many ways, but in particular one: when
actually creating a file it makes sense to set, because it is a problem
to follow final symlinks in that case. But if the file is already
existing, it actually does make sense to follow the symlinks. With
openat_report_new() we distinguish these two cases anyway (the whole
function exists only to distinguish the create and the exists-already
case after all), hence let's do something about this: let's simply never
create files "through symlinks".
This can be implemented very easily: just pass O_NOFOLLOW to the 2nd
openat() call, where we actually create files.
And then basically remove 0dd82dab91
again, because we don't need to care anymore, we already will see ELOOP
when we touch a symlink.
Note that this change means that openat_report_new() will thus start to
deviate from plain openat() behaviour in this one small detail: when
actually creating files we will *never* follow the symlink. That should
be a systematic improvement of security.
Fixes: #34088
Several test cases intentionally trigger assert_return(). So, to avoid
the entire test fails, this introduces several macros that tentatively
make assert_return() not critical.
If it is null, we get the 'base' param unchanged:
$ build/systemd-id128 show 00000000000000000000000000000001 \
--app-specific=00000000000000000000000000000000
00000000000000000000000000000001
This is not good, because it breaks our promise that the base (usually either
machine-id or boot-id) cannot be derived from the result. Some application
using the library could use a null app id, inadvertently exposing the machine
or boot id. (This could happen because of forgotten initialization, or maybe
because the app id is configurable, and the user configures it wrongly.)
Note: the other way the secret is not exposed:
$ build/systemd-id128 show 00000000000000000000000000000000 \
--app-specific=00000000000000000000000000000002
4f63080959264900b0d88d999dae2d3a
Normally systemd would not allow a null machine-id or boot-id, but we can let
the user do the calculation that if they want to.
We exported sd_id128_get_machine_app_specific() and
sd_id128_get_boot_app_specific(). But those operate on the current machine,
and sometimes the user might want to do the same calculation for a different
machine, or an earlier boot, etc. We expose the underlying implementation
to make this easy.
Doesn't really matter since the two unicode symbols are supposedly
equivalent, but let's better follow the unicode recommendations to
prefer greek small letter mu, as per:
https://www.unicode.org/reports/tr25
-1 was used everywhere, but -EBADF or -EBADFD started being used in various
places. Let's make things consistent in the new style.
Note that there are two candidates:
EBADF 9 Bad file descriptor
EBADFD 77 File descriptor in bad state
Since we're initializating the fd, we're just assigning a value that means
"no fd yet", so it's just a bad file descriptor, and the first errno fits
better. If instead we had a valid file descriptor that became invalid because
of some operation or state change, the other errno would fit better.
In some places, initialization is dropped if unnecessary.
EINVAL suggests that the caller passes an invalid argument. EIO is
for "input/output error", i.e. the error you'd get if the disk or
file system is borked, and this error code could be returned by the
underlying read/write functions.
Let's make the functions return an unambiguous error code.
We expose various other forms of UUID helpers already, i.e.
SD_ID128_UUID_FORMAT_STR and SD_ID128_MAKE_UUID_STR(), and we parse
UUIDs, hence add a high-level helper for formatting UUIDs too.
This doesn't add any new code, it just moves some helpers
id128-util.[ch] → sd-id128.[ch], to make them public.
This converts to TEST macro where it is trivial.
Some additional notable changes:
- simplify HAVE_LIBIDN #ifdef in test-dns-domain.c
- use saved_argc/saved_argv in test-copy.c, test-path-util.c,
test-tmpfiles.c and test-unit-file.c
Using OpenSSL brings in an additional dependency for all users of
libsystemd.so even though it's just one API that makes use of it.
The khash implementation is awkward as it requires context switches and
computation inside the kernel, thus leaving the process.
Remove both from libsystemd.so, and use exclusively the internal hmac fallback.
While this is not optimized, the sd-id128 API is not used in
performance-critical contexts where hardware acceleration would make a
noticeable difference.
Similar to sd_bus_error_has_names() that was added in
2b07ec316a.
It is made inline in the hope that the compiler will be able to optimize
all the va_args boilerplate away, and do an efficient comparison when
the arguments are all constants.
This splits out a bunch of functions from fileio.c that have to do with
temporary files. Simply to make the header files a bit shorter, and to
group things more nicely.
No code changes, just some rearranging of source files.
These lines are generally out-of-date, incomplete and unnecessary. With
SPDX and git repository much more accurate and fine grained information
about licensing and authorship is available, hence let's drop the
per-file copyright notice. Of course, removing copyright lines of others
is problematic, hence this commit only removes my own lines and leaves
all others untouched. It might be nicer if sooner or later those could
go away too, making git the only and accurate source of authorship
information.
This part of the copyright blurb stems from the GPL use recommendations:
https://www.gnu.org/licenses/gpl-howto.en.html
The concept appears to originate in times where version control was per
file, instead of per tree, and was a way to glue the files together.
Ultimately, we nowadays don't live in that world anymore, and this
information is entirely useless anyway, as people are very welcome to
copy these files into any projects they like, and they shouldn't have to
change bits that are part of our copyright header for that.
hence, let's just get rid of this old cruft, and shorten our codebase a
bit.
Files which are installed as-is (any .service and other unit files, .conf
files, .policy files, etc), are left as is. My assumption is that SPDX
identifiers are not yet that well known, so it's better to retain the
extended header to avoid any doubt.
I also kept any copyright lines. We can probably remove them, but it'd nice to
obtain explicit acks from all involved authors before doing that.
Package build machines may have module loading disabled, thus AF_ALG
sockets are not available. Skip the tests that cover those (khash and
id128) instead of failing them in this case.
Fixes#5524
Let's store the invocation ID in the per-service keyring as a root-owned key,
with strict access rights. This has the advantage over the environment-based ID
passing that it also works from SUID binaries (as they key cannot be overidden
by unprivileged code starting them), in contrast to the secure_getenv() based
mode.
The invocation ID is now passed in three different ways to a service:
- As environment variable $INVOCATION_ID. This is easy to use, but may be
overriden by unprivileged code (which might be a bad or a good thing), which
means it's incompatible with SUID code (see above).
- As extended attribute on the service cgroup. This cannot be overriden by
unprivileged code, and may be queried safely from "outside" of a service.
However, it is incompatible with containers right now, as unprivileged
containers generally cannot set xattrs on cgroupfs.
- As "invocation_id" key in the kernel keyring. This has the benefit that the
key cannot be changed by unprivileged service code, and thus is safe to
access from SUID code (see above). But do note that service code can replace
the session keyring with a fresh one that lacks the key. However in that case
the key will not be owned by root, which is easily detectable. The keyring is
also incompatible with containers right now, as it is not properly namespace
aware (but this is being worked on), and thus most container managers mask
the keyring-related system calls.
Ideally we'd only have one way to pass the invocation ID, but the different
ways all have limitations. The invocation ID hookup in journald is currently
only available on the host but not in containers, due to the mentioned
limitations.
How to verify the new invocation ID in the keyring:
# systemd-run -t /bin/sh
Running as unit: run-rd917366c04f847b480d486017f7239d6.service
Press ^] three times within 1s to disconnect TTY.
# keyctl show
Session Keyring
680208392 --alswrv 0 0 keyring: _ses
250926536 ----s-rv 0 0 \_ user: invocation_id
# keyctl request user invocation_id
250926536
# keyctl read 250926536
16 bytes of data in key:
9c96317c ac64495a a42b9cd7 4f3ff96b
# echo $INVOCATION_ID
9c96317cac64495aa42b9cd74f3ff96b
# ^D
This creates a new transient service runnint a shell. Then verifies the
contents of the keyring, requests the invocation ID key, and reads its payload.
For comparison the invocation ID as passed via the environment variable is also
displayed.
This adds an API for retrieving an app-specific machine ID to sd-id128.
Internally it calculates HMAC-SHA256 with an 128bit app-specific ID as payload
and the machine ID as key.
(An alternative would have been to use siphash for this, which is also
cryptographically strong. However, as it only generates 64bit hashes it's not
an obvious choice for generating 128bit IDs.)
Fixes: #4667
Accept both files with and without trailing newlines. Apparently some rkt
releases generated them incorrectly, missing the trailing newlines, and we
shouldn't break that.
We currently have code to read and write files containing UUIDs at various
places. Unify this in id128-util.[ch], and move some other stuff there too.
The new files are located in src/libsystemd/sd-id128/ (instead of src/shared/),
because they are actually the backend of sd_id128_get_machine() and
sd_id128_get_boot().
In follow-up patches we can use this reduce the code in nspawn and
machine-id-setup by adopted the common implementation.
There are more than enough calls doing string manipulations to deserve
its own files, hence do something about it.
This patch also sorts the #include blocks of all files that needed to be
updated, according to the sorting suggestions from CODING_STYLE. Since
pretty much every file needs our string manipulation functions this
effectively means that most files have sorted #include blocks now.
Also touches a few unrelated include files.
* Introduce a macro to conditionally execute tests. This avoids
skipping the entire test if some parts require systemd
* Skip the journal tests when no /etc/machine-id is present
* Change test-catalog to load the catalog from the source directory
of systemd.
* /proc/PID/comm got introduced in v2.6.33 but travis is still
using v2.6.32.
* Enable make check and make distcheck on the travis build
* Use -D"CATALOG_DIR=STR($(abs_top_srcdir)/catalog)" as a STRINGIY
would result in the path '/home/ich/source/linux' to be expanded
to '/home/ich/source/1' as linux is defined to 1.