boot: downgrade log messages about invalid timeouts
We correctly handle invalid timeouts being stored in EFI variables, but
because we deal with this gracefully we should downgrade the log level
to warning, and say "ignoring" in the log message.
Jan Čermák [Tue, 24 Jun 2025 16:54:44 +0000 (18:54 +0200)]
journal-gatewayd: fix handling of num_skip pointing beyond the last entry
When `num_skip` is supplied to the `Range` header, journal-gatewayd
always returns the very last record even though it should have been
skipped. This is because the `sd_journal_next_skip` always returns
non-zero value on the first call, leading to one iteration of the
`request_reader_entries` returning the last record.
To avoid this unexpected behavior, check that the number of lines we
have skipped by is not lower than the requested skip value. If it is,
then it means there are lines which should not be returned now -
decrement the n_skip counter then and return from the function, closing
the stream if follow flag is not set.
terminal-util: switch from TCSADRAIN to TCSANOW for all tcsetattr() calls
TCSADRAIN means tcsetattr() will become blocking (waiting for ability to
write out queued bytes), which is problematic, if the referenced TTY is
dead for some reason.
Since all these calls just modify *input* parameters anyway (i.e. mostly
local echo, and canonical mode), forcing out queued output is kinda
pointless anyway, hence just don't do it: leave it in the queue and just
change the flags we want to change.
The tcsetattr(3) man page kinda hints that we want to use TCSANOW here,
because it documents for TCSADRAIN:
"This option should be used when changing parameters that affect
output."
Which one can read so that TCSADRAIN should not be used if it doesn't
affect output, which is the case here.
I'm not convinced by the reasoning here. The practice of
forward declarations should be confined in headers only,
and any actual invocation of functions in source files
needs to include the original header. strv_split_full()
for instance takes ExtractFlags, and callers will need
to include extract-word.h to get the value definitions.
Now, indeed some -util headers export the most relevant
system header too, notably pidfd-util. But fs-util doesn't
seem to be coupled with any specific header, hence I'm
skeptical about such inclusion.
Yu Watanabe [Tue, 24 Jun 2025 17:31:48 +0000 (02:31 +0900)]
man: fix @BUILD_ROOT@ insertion
@BUILD_ROOT@ is replaced with the _quoted_ build path. Hence, if
@BUILD_ROOT@ is quoted, the result is doubly quoted, and the script does
not work if the path contains spaces.
Yu Watanabe [Sat, 21 Jun 2025 16:40:25 +0000 (01:40 +0900)]
fs-util: use int for argument that takes F_OK and friends
access_nofollow() is a simple wrapper of faccessat(), and it is defined as
```
int faccessat(int dirfd, const char *pathname, int mode, int flags);
```
Yu Watanabe [Sat, 21 Jun 2025 16:34:36 +0000 (01:34 +0900)]
fs-util: include fcntl.h in fs-util.h
fs-util.h provides access_nofollow() but it did not include neither
fcntl.h nor unistd.h, which define F_OK and friends. Hence we cannot use
the function without including one of the headers. Let's include fcntl.h
in fs-util.h, then we can use the function by simply including fs-util.h.
Yu Watanabe [Thu, 19 Jun 2025 15:59:32 +0000 (00:59 +0900)]
tree-wide: include missing_fs.h only where necessary
The additional definitions provided by the header are
- EXT4_IOC_RESIZE_FS, used in resize-fs.c,
- FILEID_KERNFS, used in cgroup-util.c and pidfd-util.c.
udev: reset loopback block device ownership and mode on detach
Loopback block devices are agressively reused, without being removed in
between. This means various inode attributes on their device nodes will
– so far – remain in effect between uses of the devices. Since there are
applications which change access mode/ownership of such devices after
attaching files to them, let's undo this again when we detect them to be
unused again.
user-record: also support "aliases" in the "status" section of user records
Some user record providers might want to implement case-insensitive user
record matching, or other forms of non-normalized matching. So far
uderdb didn't allow that, because client's typically revalidate the
returned user records against the search keys (at least our clients do)
– they check if the search user name is actually part of the user record
and its aliases.
In order to support such lookups we thus need to allow the looup keys to
be part of the user record, but also not be persisted in it, because
the number of casings/spellings of a username might be ridiculously
high.
A nice way out is to allow "aliases" not only in the main part of the
record, but also in the "status" part, that contains information
dynamically determined at query time. We can insert a second "aliases"
field there, which the parser will then merge with the primary "aliases"
field, but the existing rules around "status" ensure tha the data is
never persisted.
console: when switching console modes and one doesn't work, always go for the next
So far we already had a logic in place to go for the next mode if some
mode doesn't work – but it was only applied if we'd actively cycle
through resolutions.
Let's extend the logic and always apply it: whenever we try to switch to
a mode, and it doesn't work, go to the next one until we find one that
works.
Let's downgrade the log message about our attempts to deal with an
ordering cycle to warning, because this is a "positive" thing, we try to
improve an earlier error.
OTOH increase the log level when we first log about the cycle to error,
since that highlights the actual problem.
Yu Watanabe [Sun, 22 Jun 2025 23:55:54 +0000 (08:55 +0900)]
glob-util: rework safe_glob()
Currently, callers of safe_glob() set an empty glob_t or glob_t with
opendir func, and all other components are always zero.
So, let's introduce safe_glob_full() which optionally takes opendir
function, rather than glob_t, and returns result strv, rather than
storing results in glob_t.
Also, introduce safe_glob() which is a trivial wrapper of
safe_glob_full() without opendir func.
Yu Watanabe [Sun, 22 Jun 2025 02:09:11 +0000 (11:09 +0900)]
test-glob-util: drop redundant test cases
The removed glob() with GLOB_ALTDIRFUNC is exactly the same as what
safe_glob() does, which is tested in TEST(safe_glob) below.
Let's drop the test cases.
Valentin David [Mon, 10 Mar 2025 09:53:41 +0000 (10:53 +0100)]
Use paths specified from environment variables for /etc configuration files
Some configuration files that need updates are directly under in /etc. To
update them atomically, we need write access to /etc. For Ubuntu Core this is
an issue as /etc is not writable. Only a selection of subdirectories can be
writable. The general solution is symlinks or bind mounts to writable places.
But for atomic writes in /etc, that does not work. So Ubuntu has had a patch
for that that did not age well.
Instead we would like to introduce some environment variables for alternate
paths.
While it is for now expected that there is a symlink from the standard, we
still try to read them from that alternate path. This is important for
`/etc/localtime`, which is a symlink, so we cannot have an indirect symlink or
bind mount for it.
Since machine-id is typically written only once and not updated. This commit
does not cover it. An initrd can properly create it and bind mount it.
userdb: when loading a user record from JSON, mark 'secret' section in JSON variant as sensitive as side effect
When we load a user record we retain a reference to the original JSON.
Thus the loaded objects might live at least as long as our user record
object, hence we better make sure we set the 'sensitive' flag for the
'secret' section if it's not marked like that yet.
This is paranoia only: we already should be setting this flag properly
earlier, when acquiring the json variant in the first place. But it's
better to be safe than sorry.
homed: set "secrets" section to 'sensitive' in more places
We already do this in all placed where we it *really* matters, i.e. for
passwords PINs. But let's do this also at any place where we add the
section at all, regardless whether it is for storing a pw or something
else.
With this we establish the rule that if it's in "secrets", then it
shall be marked "sensitive".
Bastien Nocera [Sat, 21 Jun 2025 18:01:18 +0000 (20:01 +0200)]
hwdb: Add hwbd definitions for maker tools
As originally added back in 2016 in 68ea57b21d4d ("Added support
for 3D printers to uaccess (ID_MAKER_TOOL)").
The first devices added would be 3D printers compatible with Flashprint
from Flashforge, as listed in this connector plugin:
https://github.com/Mrnt/OctoPrint-FlashForge/blob/master/octoprint_flashforge/__init__.py#L28
See https://github.com/flathub/com.flashforge.FlashPrint/issues/59
copy: when looking for file holes, consider empty data segments
This could mean that we hit EOF, or it could mean that somebody punched
a hole concurrently where we are currently looking. Let's figure this
out by simply trying to copy a single byte, which will give us a
definitive answer.
Jan Čermák [Wed, 18 Jun 2025 15:32:49 +0000 (17:32 +0200)]
journal-gatewayd: make num_entries in Range header optional again
Since 435c372ce5059082212d37ac7039844f14f34a80 added in v256,
num_entries part of the Range header is mandatory and error is returned
when it's not filled in. This makes using the "follow" argument clumsy,
because for an indefinite following of the logs, arbitrary high number
must be specified. This change makes it possible to omit it again and
documents this behavior in the man page.
Moreover, as the cursor part of the header was never mandatory, enclose
it in square brackets in the documentation as well and elaborate how
indexing works.
Following are some concrete examples of the Range header which are now
accepted:
entries= (or entries=:)
- everything starting from the first event
entries=cursor
- everything starting from `cursor`
entries=:-9:10
- last 10 events and close the connection
If the follow flag is set:
entries=:-4:10
- last 5 events, wait for 5 new and close connection
entries=:-9:
- last 10 events and keep streaming
Note that only the very last one is changing current behavior, but
reintroduces pre-v256 compatibility.
We cannot compare a boolean with a bit mask. This worked only by
accident, since MANAGER_IS_INHIBITED_CHECK_DELAY happened to be 1. But
we need to do this properly.
It's not sufficient to append a DNS key to a packet, we must also update
the qdcount too. We got this right in most tests but didn#t here.
Moreover, we must extract the packet then to actually have a DnsQuestion
properly filled in.
Fix that. Without this the tests didn't test anything reasonable.
Now that we have recognizable errors, let's print clear error messages
when we try to unlock a TPM slot. And in case of the token plugin
propagate this as ENOANO so that libcryptsetup recognizes this as bad
PIN. (ENOANO is documented as the error to return in that case)
tpm2-util: recognize DA lockout mode and PIN failures properly
When we create the policy session the previously passed PIN will be
checked. This means we'll see PIN errors here, in case the PIN is wrong
or if DA lockout mode has been triggered.
Recognize these two errors, and bubble up recognizable errors.
Lukas Nykryn [Wed, 18 Jun 2025 11:33:25 +0000 (13:33 +0200)]
man: encourage the creation of empty machine-id instead of deleting it
Current text hints that machine-id in template image should be empty
if the system is read-only. But most of the bare metal systems and
regular VMs have /etc read-only at this phase of boot.
The function getdents64() was introduced in glibc-2.30, and our baseline
on glibc is 2.31. Hence, we can assume the function always exists.
The posix_getdents() wrapper was introduced for compatibility with musl.
However, even the latest release of musl does not provide posix_getdents()
yet. Also, even with musl, by defining _LARGEFILE64_SOURCE, we can get
getdents64() and struct dirent64. Hence, the wrapper is anyway not
necessary.
Yu Watanabe [Mon, 9 Jun 2025 15:39:38 +0000 (00:39 +0900)]
mallinfo-util: assume mallinfo() exists
The check existed for musl. Let's remove it, as we explicitly request glibc.
While removing the check, this also drops generic_mallinfo, introduces
a tiny converter from struct mallinfo to struct mallinfo2 if mallinfo2()
does not exist, and renames mallinfo-util.h to malloc.h.
With this change, we can drop many ifdefs and casts in .c files.
When we remove an existing inode in order to create a symlink we need to
create the symlink via a pinned directory again, instead of using an
absolute path, otherwise this will not work in the --root= case.
Let's fix this, and switch this over to symlinkat_atomic_full().
env-file: port write_env_file() to label_ops_pre()
Let's make more use of label_ops_pre()/label_ops_post(), and replace
write_env_file_label() by a flag to write_env_file().
This simplifies and normalizes the code.
This also makes one relevant change: it sets the new
WRITE_ENV_FILE_LABEL flag in firstboot.c when we write locale.conf,
where we previously did not (but should have). This should address one
detail of #37857.