Let's reduce the chance of failure: if we can't apply the chmod/chown
requested, check if it's applied anyway, and if so, supress the error.
This is even race-free since we operate on an O_PATH fd anyway.
When chase_symlinks is given a root path, it is assumed that all
processed symlinks are restricted under that path. It should not
be necessary to verify components of that prefix path since they
are not relevant to the symlinks.
This change skips unsafe UID transitions in this root prefix, i.e.
it now ignores when an unprivileged user's directory contains a
root-owned directory above the symlink root.
This has been irritating me for quite a while: let's prefix these enum
values with a common prefix, like we do for almost all other enums.
No change in behaviour, just some renaming.
This has the side effect to upgrade the log level at which the log is emitted
from debug to warning.
This might be better since after all we didn't apply a tmpfiles.d/ rule and
that actually might end up being problematic eventually.
We're always interested into finding unsafe transitions so let's make the
helper return true when it finds such transitions so we don't need to negate
its results.
No functional changes.
We previously returned -EPERM but it can be returned for various other reasons
too.
Let's use -ENOLINK instead as this value shouldn't be used currently. This
allows users of CHASE_SAFE to detect without any ambiguities when unsafe
transitions are encountered by chase_symlinks().
All current users of CHASE_SAFE that explicitly reacted on -EPERM have been
converted to react on -ENOLINK.
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.
This flag can be used to make chase_symlinks() emit a warning when it
encounters an error.
Such flag can be useful for generating a comprehensive and detailed warning
since chase_symlinks() can generate a warning with a full context.
For now only warnings for unsafe transitions are produced.
I noticed while profiling journald that we invoke readlinkat() a ton on
open /proc/self/fd/<fd>, and that the returned paths are more often than
not longer than the 99 chars used before, when we look at archived
journal files. This means for these cases we generally need to execute
two rather than one syscalls.
Let's increase the buffer size a tiny bit, so that we reduce the number
of syscalls executed. This is really a low-hanging fruit of
optimization.
This is the counterpiece to the boot counting implemented in
systemd-boot: if a boot is detected as successful we mark drop the
counter again from the booted snippet or kernel image.
Apparently FAT on some recent kernels can't do RENAME_NOREPLACE, and of
course cannot do linkat()/unlinkat() either (as the hard link concept
does not exist on FAT). Add a fallback using an explicit beforehand
faccessat() check. This sucks, but what we can do if the safe operations
are not available?
Fixes: #10063
This flag mimics what "O_NOFOLLOW|O_PATH" does for open(2) that is
chase_symlinks() will not resolve the final pathname component if it's a
symlink and instead will return a file descriptor referring to the symlink
itself.
Note: if CHASE_SAFE is also passed, no safety checking is performed on the
transition done if the symlink would have been followed.
We often open the parent directory of a path. Let's add a common helper
for that, that shortens our code a bit and adds some extra safety
checks, for example it will fail if used on the root directory (which
doesn't really have a parent).
The helper is actually generalized from a function in btrfs-util.[ch]
which already existed for this purpose.
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.
This is mostly fall-out from d1a1f0aaf0,
however some cases are older bugs.
There might be more issues lurking, this was a simple grep for "%m"
across the tree, with all lines removed that mention "errno" at all.
This way we don't need to repeat the argument twice.
I didn't replace all instances. I think it's better to leave out:
- asserts
- comparisons like x & y == x, which are mathematically equivalent, but
here we aren't checking if flags are set, but if the argument fits in the
flags.
Functions whose only purpose is to be used with _cleanup_() should not
touch errno, so that failing removals do not alter errno at unexpected
places.
This is already done in unlink_and_freep(), rmdir_and_freep(),
rm_rf_physical_and_freep(), hence do so for unlink_tempfilep(), too.
Follow-up for #9013
This simplifies the use of tempfiles in tests and fixes "leaked"
temporary files in test-fileio, test-catalog, test-conf-parser.
Not the whole tree is converted.
We can jump to chase_one from two places. In the first 'todo' is set to
'buffer', which comes from path_make_absolute_cwd() and is nonnull In the
second 'todo' is set to 'joined' which is checked to be nonull a few lines
above the jump. So let's kill the code that deals with null todo there.
CID #1390941.
We check the same condition at various places. Let's add a trivial,
common helper for this, and use it everywhere.
It's not going to make things much faster or much shorter, but I think a
lot more readable
If the flag is set only a single step of the normalization is executed,
and the resulting path is returned.
This allows callers to normalize piecemeal, taking into account every
single intermediary path of the normalization.
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.
This is similar to TAKE_PTR() but operates on file descriptors, and thus
assigns -1 to the fd parameter after returning it.
Removes 60 lines from our codebase. Pretty good too I think.
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)
This rearranges chase_symlinks() a bit: if no special flags are
specified it will now revert to behaviour before
b12d25a8d6. However, if the new
CHASE_TRAIL_SLASH flag is specified it will follow the behaviour
introduced by that commit.
I wasn't sure which one to make the beaviour that requires specification
of a flag to enable. I opted to make the "append trailing slash"
behaviour the one to enable by a flag, following the thinking that the
function should primarily be used to generate a normalized path, and I
am pretty sure a path without trailing slash is the more "normalized"
one, as the trailing slash is not really a part of it, but merely a
"decorator" that tells various system calls to generate ENOTDIR if the
path doesn't refer to a path.
Or to say this differently: if the slash was part of normalization then
we really should add it in all cases when the final path is a directory,
not just when the user originally specified it.
Fixes: #8544
Replaces: #8545
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.