Commit Graph

59 Commits

Author SHA1 Message Date
Lennart Poettering ae2a15bc14 macro: introduce TAKE_PTR() macro
This macro will read a pointer of any type, return it, and set the
pointer to NULL. This is useful as an explicit concept of passing
ownership of a memory area between pointers.

This takes inspiration from Rust:

https://doc.rust-lang.org/std/option/enum.Option.html#method.take

and was suggested by Alan Jenkins (@sourcejedi).

It drops ~160 lines of code from our codebase, which makes me like it.
Also, I think it clarifies passing of ownership, and thus helps
readability a bit (at least for the initiated who know the new macro)
2018-03-22 20:21:42 +01:00
Zbigniew Jędrzejewski-Szmek 3ceae1bc14 basic/fs-util: skip fsync_directory_of_file() if /proc/self/fd/ is not available (#8386)
When systemd is running under lorax (in Fedora compose process), it'd think that
it failed to write /etc/machine-id, even though the write succeeded, because
fsync_directory_of_file() would fail, because /proc/self/fd/ is not available.
fsync_directory_of_file() is mostly an additional safety net, so I think it's best
to just silently ignore the error.

Strace of pid1:
35791 stat("/etc", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
35791 openat(AT_FDCWD, "/etc/machine-id", O_RDWR|O_CREAT|O_NOCTTY|O_CLOEXEC, 0444) = 3
35791 umask(022)                        = 000
35791 read(3, "", 38)                   = 0
35791 openat(AT_FDCWD, "/var/lib/dbus/machine-id", O_RDONLY|O_NOCTTY|O_NOFOLLOW|O_CLOEXEC) = -1 ENOENT (No such file o
r directory)
35791 openat(AT_FDCWD, "/sys/class/dmi/id/product_name", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
35791 openat(AT_FDCWD, "/sys/class/dmi/id/sys_vendor", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
35791 openat(AT_FDCWD, "/sys/class/dmi/id/board_vendor", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
35791 openat(AT_FDCWD, "/sys/class/dmi/id/bios_vendor", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
35791 access("/proc/xen", F_OK)         = -1 ENOENT (No such file or directory)
35791 openat(AT_FDCWD, "/sys/hypervisor/type", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
35791 openat(AT_FDCWD, "/proc/cpuinfo", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
35791 getrandom("\xb8\x82\xed\xd4\x35\x11\xd0\xeb\xa6\x79\xd7\x31\x6e\x7b\x99\xce", 16, GRND_NONBLOCK) = 16
35791 writev(2, [{iov_base="Initializing machine ID from random generator.", iov_len=46}, {iov_base="\n", iov_len=1}],
 2) = 47
35791 lseek(3, 0, SEEK_SET)             = 0
35791 ftruncate(3, 0)                   = 0
35791 write(3, "b882edd4351140eba679d7316e7b99ce\n", 33) = 33
35791 fsync(3)                          = 0
35791 fstat(3, {st_mode=S_IFREG|0444, st_size=33, ...}) = 0
35791 readlinkat(AT_FDCWD, "/proc/self/fd/3", 0x564df8c694c0, 99) = -1 ENOENT (No such file or directory)
35791 close(3)                          = 0
35791 umask(022)                        = 022
35791 openat(AT_FDCWD, "/run/machine-id", O_WRONLY|O_CREAT|O_NOCTTY|O_TRUNC|O_CLOEXEC, 0444) = 3
35791 write(3, "b882edd4351140eba679d7316e7b99ce\n", 33) = 33
35791 close(3)                          = 0
35791 umask(022)                        = 022
35791 mount("/run/machine-id", "/etc/machine-id", NULL, MS_BIND, NULL) = 0
35791 writev(2, [{iov_base="Installed transient /etc/machine-id file.", iov_len=41}, {iov_base="\n", iov_len=1}], 2) = 42
35791 mount(NULL, "/etc/machine-id", NULL, MS_RDONLY|MS_REMOUNT|MS_BIND, NULL) = 0

https://bugzilla.redhat.com/show_bug.cgi?id=1552843
2018-03-20 18:20:01 +01:00
Lennart Poettering 11b29a96e9 fs-util: move fsync_directory_of_file() into generic code
This function used by the journal code is pretty useful generically,
let's move it to fs-util.c to make it useful for other code too.
2018-02-20 15:39:31 +01:00
Zbigniew Jędrzejewski-Szmek af229d7a5b login,user-sessions: always warn when we fail to remove nologin file
This usually is very annoying to users who then cannot log in, so
make sure we always warn if that happens (selinux, or whatever other reason).

This reverts a790812cb3.
2018-02-16 10:44:22 +01:00
Lennart Poettering 43767d9d5e fs-util: add new unlinkat_deallocate() helper
This new helper not only removes a file from a directory but also
ensures its space on disk is deallocated, by either punching a hole over
the full file or truncating the file afterwards if the file's link
counter is 0. This is useful in "vacuuming" algorithms to ensure that
client's can't keep the disk space the vacuuming is supposed to recover
pinned simply by keeping an fd open to it.
2018-02-12 11:27:11 +01:00
Yu Watanabe 01e4793de6 fs-util: drop readlink_and_make_absolute_root() 2018-02-09 16:58:56 +09:00
Yu Watanabe 842e456e79 fs-util: drop readlink_and_canonicalize() 2018-02-09 16:49:54 +09:00
Yu Watanabe b539437a05 fs-util: chase_symlinks(): prevent double free
Fixes CID #1385316.
2018-01-21 19:19:28 +09:00
Yu Watanabe 2b6d2dda6b fs-util: use _cleanup_close_ attribute
The commit f14f1806e3 introduced CHASE_SAFE
flag. When the flag is set, then `fd_parent` may not be properly closed.
This sets `_cleanup_close_` attribute to `fd_parent`.
Thus, now `fd_parent` is always closed properly.
2018-01-21 19:07:14 +09:00
Yu Watanabe 22bc57c58a fs-util: chase_symlinks(): support empty root
The commit b1bfb84804 makes chase_symlinks()
recognize empty string for root as an invalid parameter. However,
empty root is often used e.g. systemd-nspawn.
This makes chase_symlinks() support empty string safely.

Fixes #7927.
2018-01-19 11:41:28 +01:00
Lennart Poettering 382a5078a6 fs-util: refuse taking a relative path to chase if "root" is specified and CHASE_PREFIX_ROOT is set
If we take a relative path we first make it absolute, based on the
current working directory. But if CHASE_PREFIX_ROOT is passe we are
supposed to make the path absolute taking the specified root path into
account, but that makes no sense if we talk about the current working
directory as that is relative to the host's root in any case. Hence,
let's refuse this politely.
2018-01-17 12:04:15 +01:00
Lennart Poettering a49424af6a fs-util: extra chase_symlink() safety check on "path" parameter
It's not clear what an empty "path" is even supposed to mean, hence
refuse.
2018-01-17 12:04:15 +01:00
Lennart Poettering b1bfb84804 fs-util: extra safety checks on chase_symlinks() root parameter
Let's handle root="" and root="/" safely.
2018-01-17 12:04:15 +01:00
Zbigniew Jędrzejewski-Szmek e0b6d3cabe
Merge pull request #7816 from poettering/chase-pid
Make MAINPID= and PIDFile= handling more restrictive (and other stuff)
2018-01-15 14:14:34 +04:00
Lennart Poettering 1ed34d75d4 fs-util: add new chase_symlinks() flag CHASE_OPEN
The new flag returns the O_PATH fd of the final component, which may be
converted into a proper fd by open()ing it again through the
/proc/self/fd/xyz path.

Together with O_SAFE this provides us with a somewhat safe way to open()
files in directories potentially owned by unprivileged code, where we
want to refuse operation if any symlink tricks are played pointing to
privileged files.
2018-01-11 15:12:16 +01:00
Lennart Poettering f14f1806e3 fs-util: add new CHASE_SAFE flag to chase_symlinks()
When the flag is specified we won't transition to a privilege-owned
file or directory from an unprivileged-owned one. This is useful when
privileged code wants to load data from a file unprivileged users have
write access to, and validates the ownership, but want's to make sure
that no symlink games are played to read a root-owned system file
belonging to a different context.
2018-01-11 15:12:16 +01:00
Lennart Poettering dccca82b1a log: minimize includes in log.h
log.h really should only include the bare minimum of other headers, as
it is really pulled into pretty much everything else and already in
itself one of the most basic pieces of code we have.

Let's hence drop inclusion of:

1. sd-id128.h because it's entirely unneeded in current log.h
2. errno.h, dito.
3. sys/signalfd.h which we can replace by a simple struct forward
   declaration
4. process-util.h which was needed for getpid_cached() which we now hide
   in a funciton log_emergency_level() instead, which nicely abstracts
   the details away.
5. sys/socket.h which was needed for struct iovec, but a simple struct
   forward declaration suffices for that too.

Ultimately this actually makes our source tree larger (since users of
the functionality above must now include it themselves, log.h won't do
that for them), but I think it helps to untangle our web of includes a
tiny bit.

(Background: I'd like to isolate the generic bits of src/basic/ enough
so that we can do a git submodule import into casync for it)
2018-01-11 14:44:31 +01:00
Lennart Poettering 9e3fa6e827 fs-util: rework touch_file() so that it can touch socket file nodes
Let's rework touch_file() so that it works correctly on sockets, fifos,
and device nodes: let's open an O_PATH file descriptor first and operate
based on that, if we can. This is usually the better option as it this
means we can open AF_UNIX nodes in the file system, and update their
timestamps and ownership correctly. It also means we can correctly touch
symlinks and block/character devices without triggering their drivers.

Moreover, by operating on an O_PATH fd we can make sure that we
operate on the same inode the whole time, and it can't be swapped out in
the middle.

While we are at it, rework the call so that we try to adjust as much as
we can before returning on error. This is a good idea as we call the
function quite often without checking its result, and hence it's best to
leave the files around in the most "correct" fashion possible.
2018-01-05 13:55:08 +01:00
Lennart Poettering fbd0b64f44
tree-wide: make use of new STRLEN() macro everywhere (#7639)
Let's employ coccinelle to do this for us.

Follow-up for #7625.
2017-12-14 19:02:29 +01:00
Yu Watanabe 46e92680e0 fs-util: remove comment about non-existing function 2017-12-03 00:25:00 +09:00
Yu Watanabe a1904a4663 fs-util: chase_symlinks(): remove unnecessary slash at the head
Before this, chase_symlinks("/../../foo/bar",...) returns //foo/bar.
This removes the unnecessary slash at the head.
2017-12-03 00:24:52 +09:00
Zbigniew Jędrzejewski-Szmek a66fee2e97 util-lib: rename fd_check_fstype to fd_is_fs_type
Let's use "is" and "fs_type" for consistency with "is_fs_type".
"check" is also more ambiguous than "is".
2017-11-30 20:43:25 +01:00
Zbigniew Jędrzejewski-Szmek b12d25a8d6 util-lib: use trailing slash in chase_symlinks, fd_is_mount_point, path_is_mount_point
The kernel will reply with -ENOTDIR when we try to access a non-directory under
a name which ends with a slash. But our functions would strip the trailing slash
under various circumstances. Keep the trailing slash, so that

path_is_mount_point("/path/to/file/") return -ENOTDIR when /path/to/file/ is a file.

Tests are added for this change in behaviour.

Also, when called with a trailing slash, path_is_mount_point() would get
"" from basename(), and call name_to_handle_at(3, "", ...), and always
return -ENOENT. Now it'll return -ENOTDIR if the mount point is a file, and
true if it is a directory and a mount point.

v2:
- use strip_trailing_chars()

v3:
- instead of stripping trailing chars(), do the opposite — preserve them.
2017-11-30 20:43:25 +01:00
Lennart Poettering 0133d5553a
Merge pull request #7198 from poettering/stdin-stdout
Add StandardInput=data, StandardInput=file:... and more
2017-11-19 19:49:11 +01:00
Zbigniew Jędrzejewski-Szmek 53e1b68390 Add SPDX license identifiers to source files under the LGPL
This follows what the kernel is doing, c.f.
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5fd54ace4721fc5ce2bb5aef6318fcf17f421460.
2017-11-19 19:08:15 +01:00
Lennart Poettering 99be45a46f fs-util: rename path_is_safe() → path_is_normalized()
Already, path_is_safe() refused paths container the "." dir. Doing that
isn't strictly necessary to be "safe" by most definitions of the word.
But it is necessary in order to consider a path "normalized". Hence,
"path_is_safe()" is slightly misleading a name, but
"path_is_normalize()" is more descriptive, hence let's rename things
accordingly.

No functional changes.
2017-11-17 11:13:44 +01:00
Lennart Poettering 57a4359ee0 fs-util: add access_fd() which is like access() but for fds
Linux doesn't have faccess(), hence let's emulate it. Linux has access()
and faccessat() but neither allows checking the access rights of an fd
passed in directly.
2017-11-17 11:12:33 +01:00
Lennart Poettering 8c4a8ea2ac fs-util: small tweak in chase_symlinks()
If we follow an absolute symlink there's no need to prefix the path with
a "/", since by definition it already has one.

This helps suppressing double "/" in resolved paths containing absolute
symlinks.
2017-10-26 17:54:56 +02:00
Yu Watanabe 4c70109600 tree-wide: use IN_SET macro (#6977) 2017-10-04 16:01:32 +02:00
Lennart Poettering 77b79723a6 fs-util: propagate EEXIST error in symlink_idempotent() as EEXIST
We really shouldn't silently translate the error code here for no
reason.
2017-09-27 17:52:42 +02:00
NeilBrown 655f2da079 tmpfiles: silently ignore any path that passes through autofs (#6506)
If a path passes though an autofs filesystem, then accessing
the path might trigger and automount.  As systemd-tmpfiles is run before
the network is up, and as automounts are often used for networked
filesystems, this can cause a deadlock.

So chase_symlinks is enhance to accept a new flag which tells it
to check for autofs, and return -EREMOTE if autofs is found.

tmpfiles is changed to check just before acting on a path so that it
can avoid autofs even if a symlink was created earlier by tmpfiles
that would send this path through an autofs.

This fixes a deadlock that happens when /home is listed in /etc/fstab as
x-systemd.automount for an NFS directory.
2017-09-04 15:35:07 +02:00
Lennart Poettering df0ff12775 tree-wide: make use of getpid_cached() wherever we can
This moves pretty much all uses of getpid() over to getpid_raw(). I
didn't specifically check whether the optimization is worth it for each
replacement, but in order to keep things simple and systematic I
switched over everything at once.
2017-07-20 20:27:24 +02:00
3chas3 877777d776 util-lib: Fix chase_symlinks() with absolute symlinks (#5185)
If chase_symlinks() encouters an absolute symlink, it resets the todo
buffer to just the newly discovered symlink and discards any of the
remaining previous symlink path.  Regardless of whether or not the
symlink is absolute or relative, we need to preserve the remainder of
the path that has not yet been resolved.
2017-01-31 16:21:15 +03:00
Lennart Poettering 245f1d244b util-lib: accept invoking chase_symlinks() with a NULL return parameter
Let's permit invoking chase_symlinks() with a NULL return parameter. If so, the
resolved name is not returned, and call is useful for checking for existance of
a file, without actually returning its ultimate path.
2016-12-20 20:00:08 +01:00
Reverend Homer 8fb3f00997 tree-wide: replace all readdir cycles with FOREACH_DIRENT{,_ALL} (#4853) 2016-12-09 10:04:30 +01:00
Lennart Poettering cb638b5e96 util-lib: rename CHASE_NON_EXISTING → CHASE_NONEXISTENT
As suggested by @keszybz
2016-12-01 12:49:55 +01:00
Lennart Poettering a9fb08670f fs-util: add new CHASE_NON_EXISTING flag to chase_symlinks()
This new flag controls whether to consider a problem if the referenced path
doesn't actually exist. If specified it's OK if the final file doesn't exist.

Note that this permits one or more final components of the path not to exist,
but these must not contain "../" for safety reasons (or, to be extra safe,
neither "./" and a couple of others, i.e. what path_is_safe() permits).

This new flag is useful when resolving paths before issuing an mkdir() or
open(O_CREAT) on a path, as it permits that the file or directory is created
later.

The return code of chase_symlinks() is changed to return 1 if the file exists,
and 0 if it doesn't. The latter is only returned in case CHASE_NON_EXISTING is
set.
2016-12-01 00:25:51 +01:00
Lennart Poettering c4f4fce79e fs-util: add flags parameter to chase_symlinks()
Let's remove chase_symlinks_prefix() and instead introduce a flags parameter to
chase_symlinks(), with a flag CHASE_PREFIX_ROOT that exposes the behaviour of
chase_symlinks_prefix().
2016-12-01 00:25:51 +01:00
Lennart Poettering a4eaf3cf82 fs-util: change chase_symlinks() behaviour in regards to escaping the root dir
Previously, we'd generate an EINVAL error if it is attempted to escape a root
directory with relative ".." symlinks. With this commit this is changed so that
".." from the root directory is a NOP, following the kernel's own behaviour
where /.. is equivalent to /.

As suggested by @keszybz.
2016-12-01 00:25:51 +01:00
Lennart Poettering fc4b68e557 fs-util: add chase_symlinks_prefix() and extend comments
chase_symlinks() currently expects a fully qualified, absolute path, relative
to the host's root as first argument. Which is useful in many ways, and similar
to the paths unlink(), rename(), open(), … expect. Sometimes it's however
useful to first prefix the specified path with the specified root directory.
Add a new call chase_symlinks_prefix() for this, that is a simple wrapper.
2016-12-01 00:25:51 +01:00
Lennart Poettering e187369587 tree-wide: stop using canonicalize_file_name(), use chase_symlinks() instead
Let's use chase_symlinks() everywhere, and stop using GNU
canonicalize_file_name() everywhere. For most cases this should not change
behaviour, however increase exposure of our function to get better tested. Most
importantly in a few cases (most notably nspawn) it can take the correct root
directory into account when chasing symlinks.
2016-12-01 00:25:51 +01:00
Zbigniew Jędrzejewski-Szmek 605405c6cc tree-wide: drop NULL sentinel from strjoin
This makes strjoin and strjoina more similar and avoids the useless final
argument.

spatch -I . -I ./src -I ./src/basic -I ./src/basic -I ./src/shared -I ./src/shared -I ./src/network -I ./src/locale -I ./src/login -I ./src/journal -I ./src/journal -I ./src/timedate -I ./src/timesync -I ./src/nspawn -I ./src/resolve -I ./src/resolve -I ./src/systemd -I ./src/core -I ./src/core -I ./src/libudev -I ./src/udev -I ./src/udev/net -I ./src/udev -I ./src/libsystemd/sd-bus -I ./src/libsystemd/sd-event -I ./src/libsystemd/sd-login -I ./src/libsystemd/sd-netlink -I ./src/libsystemd/sd-network -I ./src/libsystemd/sd-hwdb -I ./src/libsystemd/sd-device -I ./src/libsystemd/sd-id128 -I ./src/libsystemd-network --sp-file coccinelle/strjoin.cocci --in-place $(git ls-files src/*.c)

git grep -e '\bstrjoin\b.*NULL' -l|xargs sed -i -r 's/strjoin\((.*), NULL\)/strjoin(\1)/'

This might have missed a few cases (spatch has a really hard time dealing
with _cleanup_ macros), but that's no big issue, they can always be fixed
later.
2016-10-23 11:43:27 -04:00
Zbigniew Jędrzejewski-Szmek 3b319885c4 tree-wide: introduce free_and_replace helper
It's a common pattern, so add a helper for it. A macro is necessary
because a function that takes a pointer to a pointer would be type specific,
similarly to cleanup functions. Seems better to use a macro.
2016-10-16 23:35:39 -04:00
Lennart Poettering d944dc9553 namespace: chase symlinks for mounts to set up in userspace
This adds logic to chase symlinks for all mount points that shall be created in
a namespace environment in userspace, instead of leaving this to the kernel.
This has the advantage that we can correctly handle absolute symlinks that
shall be taken relative to a specific root directory. Moreover, we can properly
handle mounts created on symlinked files or directories as we can merge their
mounts as necessary.

(This also drops the "done" flag in the namespace logic, which was never
actually working, but was supposed to permit a partial rollback of the
namespace logic, which however is only mildly useful as it wasn't clear in
which case it would or would not be able to roll back.)

Fixes: #3867
2016-09-25 10:42:18 +02:00
Lennart Poettering 992e8f224b util-lib: rework /tmp and /var/tmp handling code
Beef up the existing var_tmp() call, rename it to var_tmp_dir() and add a
matching tmp_dir() call (the former looks for the place for /var/tmp, the
latter for /tmp).

Both calls check $TMPDIR, $TEMP, $TMP, following the algorithm Python3 uses.
All dirs are validated before use. secure_getenv() is used in order to limite
exposure in suid binaries.

This also ports a couple of users over to these new APIs.

The var_tmp() return parameter is changed from an allocated buffer the caller
will own to a const string either pointing into environ[], or into a static
const buffer. Given that environ[] is mostly considered constant (and this is
exposed in the very well-known getenv() call), this should be OK behaviour and
allows us to avoid memory allocations in most cases.

Note that $TMPDIR and friends override both /var/tmp and /tmp usage if set.
2016-08-04 16:27:07 +02:00
ottopotto 34a8f0811c journalctl: Make temporary files directory configurable (#3574)
journalctl: Use env variable TMPDIR to save temporary files
2016-06-30 07:59:06 -07:00
Lennart Poettering 430fbf8e7f journal: add inotify watches by-fd instead of by-path
This is slightly nicer, since we actually watch the directories we opened and
enumerate. However, primarily this is preparation for adding support for
opening journal files by fd without specifying any path, to be added in a later
commit.
2016-04-25 12:00:03 +02:00
Lennart Poettering 1d9b8e5834 util: drop two unused calls from src/basic/ 2016-02-13 12:28:04 +01:00
Daniel Mack b26fa1a2fb tree-wide: remove Emacs lines from all files
This should be handled fine now by .dir-locals.el, so need to carry that
stuff in every file.
2016-02-10 13:41:57 +01:00
Mantas Mikulėnas 06eeacb6fe basic: fix touch() creating files with 07777 mode
mode_t is unsigned, so MODE_INVALID < 0 can never be true.

This fixes a possible DoS where any user could fill /run by writing to
a world-writable /run/systemd/show-status.
2016-01-29 23:41:09 +02:00