1
0
mirror of https://github.com/systemd/systemd.git synced 2025-01-06 17:18:12 +03:00

Compare commits

...

26 Commits

Author SHA1 Message Date
Yu Watanabe
5811a0117c core/namespace: replace MOUNT_PRIVATE_TMP_READ_ONLY with MOUNT_PRIVATE_TMP with .read_only = true 2024-10-24 03:05:06 +09:00
Yu Watanabe
d69ee5acdc core/namespace: coding style cleanups 2024-10-24 03:05:06 +09:00
Yu Watanabe
0cc496b2d2 core/namespace: honor MountEntry.read_only, .options, and so on in static entries
Otherwise, ProtectHome=tmpfs makes /home/ and friends not read-only.
Also, mount options for /run/ specified in MountAPIVFS=yes are not
applied.

The function append_static_mounts() was introduced in
5327c910d2, but at that time, there were
neither .read_only nor .options in the struct. But, when later the
struct is extended, the function was not updated and they were not
copied from the static table.
The fields has been used in static tables since
e4da7d8c79, and also in
94293d65cd.

Fixes #34825.
2024-10-24 02:59:46 +09:00
Integral
b6b8527cd1
refactor: replace sizeof in loop with ELEMENTSOF & FOREACH_ELEMENT (#34863) 2024-10-23 10:32:02 +02:00
Lennart Poettering
4d5d574906 update TODO 2024-10-23 10:27:04 +02:00
Yu Watanabe
967c586e9c man/network: fix typo
Follow-up for 1f5a052963.
2024-10-23 17:25:37 +09:00
Yu Watanabe
f0b974050d measure: fix typo
Follow-up for 0005411352.
2024-10-23 17:25:37 +09:00
Yu Watanabe
82d8a2c810 TEST-55-OOMD: fix typo
Follow-up for 63d4c4271c.
2024-10-23 17:25:37 +09:00
Lennart Poettering
efaa5e0539
Merge pull request #34850 from poettering/openat-report-new-tweaks
openat_report_new() tweaks
2024-10-23 10:25:18 +02:00
Ronan Pigott
c7c9e3c7c0 network: adjust log message about DNR
The only possible error return in this position is -ENODATA, which is
not interesting.
2024-10-23 10:24:39 +02:00
Lennart Poettering
53c5073858
Merge pull request #34861 from poettering/can-idle
logind: introduce CanIdle/CanLock properties on logind session dbus objects
2024-10-23 10:24:23 +02:00
Lennart Poettering
1bf9e308eb logind: also check session class in session_get_idle_hint() 2024-10-22 18:44:05 +02:00
Lennart Poettering
4096fcde09 logind: use RET_GATHER() at one more place 2024-10-22 18:44:05 +02:00
Lennart Poettering
bd91f23acf logind: add CanIdle + CanLock dbus properties to session object
Clients should be able to know if the idle logic is available on a
session without secondary knowledge about the session class. Let's hence
expose a property for that.

Similar for the screen lock concept.

Fixes: #34844
2024-10-22 18:44:05 +02:00
Lennart Poettering
b9633ebb2a fs-util: move attempts counter in openat_report_new() into loop 2024-10-22 17:51:26 +02:00
Lennart Poettering
4ffecbbbee label: move label_ops_reset() up a bit
Let#s move it close to label_ops_set(), since it is somewhat symmetric
to it.
2024-10-22 17:51:26 +02:00
Lennart Poettering
4e4ed4b64d label: add missing assert() to label_ops_set() 2024-10-22 17:51:26 +02:00
Lennart Poettering
3a7ae4ba62 shared: get rid of fileio-label.[ch]
Move the renaming function to reboot-util.h (since it writes out
/run/nologin at shutdown), and let's get rid of fileio-label.[ch] now
that it serves no purpose anymore.
2024-10-22 17:51:26 +02:00
Lennart Poettering
aec1262a2e fileio: port write_string_file_full() to openat_report_new()
This brings two benefits: we will label the created file only if it is
actually created, and we can correctly delete any file we create again
on failure.
2024-10-22 17:51:26 +02:00
Lennart Poettering
8eeb870971 fileio: port write_string_file() to LabelOps, and thus add WRITE_STRING_FILE_LABEL flag
Given that we have the LabelOps abstraction these days, we can teach
write_string_file() to use it, which means we can get rid of
fileio-label.[ch] as a separate concept.

(The only reason that fileio-label.[ch] exists independently of
fileio.[ch] was that the former linekd to libselinux potentially, and
thus had to be in src/shared/ while the other always was in src/basic/.
But the LabelOps vtable provides us with a nice work-around)
2024-10-22 17:51:26 +02:00
Lennart Poettering
4946dd4197 fs-util: tweak how openat_report_new() operates when O_CREAT is used on a dangling symlink
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
2024-10-22 17:51:26 +02:00
Lennart Poettering
64053bed08 fs-util: always call label post ops in xopenat_full(), in both success and error path
For SELinux it is essential that we reset the file creation label both
in the success and in the error path, hence do so.

Moreover, when calling the label post ops do it if possible with the
opened fd of the inode itself, rather than always going via its path,
simply to reduce the attack surface.
2024-10-22 17:51:26 +02:00
Lennart Poettering
da3d81cccd fs-util: don't second guess openat_report_new() return values
If openat_report_new() fails, then 'made_file' will be false, as no file
was created, hence there's no need to skip the unlinkat() explicitly
early, given that we check for 'made_file' anyway in the error path. The
extra error code checks are hence entirely redundant.
2024-10-22 17:51:26 +02:00
Lennart Poettering
d49449c89b label: tweak LabelOps post() hook to take "created" boolean
We have two distinct implementations of the post hook.

1. For SELinux we just reset the selinux label we told the kernel
   earlier to use for new inodes.

2. For SMACK we might apply an xattr to the specified file.

The two calls are quite different: the first call we want to call in all
cases (failure or success), the latter only if we actually managed to
create an inode, in which case it is called on the inode.
2024-10-22 17:51:26 +02:00
Lennart Poettering
652371a3c1 fs-util: always go through the unlink cleanup paths in xopenat_full()
We didn't go through it at all if label_ops_post() failed.
2024-10-22 17:45:41 +02:00
Lennart Poettering
12620ca1fb fs-util: remove misplaced RET_NERRNO() 2024-10-22 17:45:41 +02:00
40 changed files with 290 additions and 253 deletions

2
TODO
View File

@ -129,6 +129,8 @@ Deprecations and removals:
Features:
* port copy.c over to use LabelOps for all labelling.
* port remaining getmntent() users over to libmount. There are subtle
differences in the parsers (see #25371 for example), and it hence makes sense
if we stick to one set of parsers on this, not mix both.

View File

@ -1245,6 +1245,10 @@ node /org/freedesktop/login1/session/1 {
readonly b IdleHint = ...;
readonly t IdleSinceHint = ...;
readonly t IdleSinceHintMonotonic = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b CanIdle = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b CanLock = ...;
readonly b LockedHint = ...;
};
interface org.freedesktop.DBus.Peer { ... };
@ -1349,6 +1353,10 @@ node /org/freedesktop/login1/session/1 {
<variablelist class="dbus-property" generated="True" extra-ref="IdleSinceHintMonotonic"/>
<variablelist class="dbus-property" generated="True" extra-ref="CanIdle"/>
<variablelist class="dbus-property" generated="True" extra-ref="CanLock"/>
<variablelist class="dbus-property" generated="True" extra-ref="LockedHint"/>
<!--End of Autogenerated section-->
@ -1538,6 +1546,10 @@ node /org/freedesktop/login1/session/1 {
<para><varname>LockedHint</varname> shows the locked hint state of this session, as set by the
<function>SetLockedHint()</function> method described above.</para>
<para><varname>CanIdle</varname> indicates whether the session supports the idle hint
concept. Similarly, <varname>CanLock</varname> indicates whether the session supports the screen lock
concept.</para>
</refsect2>
</refsect1>
@ -1619,10 +1631,9 @@ node /org/freedesktop/login1/session/1 {
<function>CanSleep()</function>,
<varname>SleepOperation</varname>, and
<function>ListSessionsEx()</function> were added in version 256.</para>
<para><varname>HandleSecureAttentionKey</varname>,
<function>SecureAttentionKey()</function>,
<varname>PreparingForShutdownWithMetadata</varname>, and
<varname>DesignatedMaintenanceTime</varname> were added in version 257.</para>
<para><varname>HandleSecureAttentionKey</varname>, <function>SecureAttentionKey()</function>,
<varname>PreparingForShutdownWithMetadata</varname>, <varname>DesignatedMaintenanceTime</varname>,
<varname>CanIdle</varname> and <varname>CanLock</varname> were added in version 257.</para>
</refsect2>
<refsect2>
<title>Session Objects</title>

View File

@ -6277,7 +6277,7 @@ DHCP=ipv6
# If the upstream network does not provides any Router Advertisement (RA) messages,
# then uncomment the lines below to make the DHCPv6 client forcibly started in the
# manageed mode.
# managed mode.
#[Network]
#IPv6AcceptRA=no
#[DHCPv6]

View File

@ -18,6 +18,7 @@
#include "fileio.h"
#include "fs-util.h"
#include "hexdecoct.h"
#include "label.h"
#include "log.h"
#include "macro.h"
#include "mkdir.h"
@ -230,22 +231,40 @@ static int write_string_file_atomic_at(
/* Note that we'd really like to use O_TMPFILE here, but can't really, since we want replacement
* semantics here, and O_TMPFILE can't offer that. i.e. rename() replaces but linkat() doesn't. */
mode_t mode = write_string_file_flags_to_mode(flags);
bool call_label_ops_post = false;
if (FLAGS_SET(flags, WRITE_STRING_FILE_LABEL)) {
r = label_ops_pre(dir_fd, fn, mode);
if (r < 0)
return r;
call_label_ops_post = true;
}
r = fopen_temporary_at(dir_fd, fn, &f, &p);
if (r < 0)
return r;
goto fail;
if (call_label_ops_post) {
call_label_ops_post = false;
r = label_ops_post(fileno(f), /* path= */ NULL, /* created= */ true);
if (r < 0)
goto fail;
}
r = write_string_stream_full(f, line, flags, ts);
if (r < 0)
goto fail;
r = fchmod_umask(fileno(f), write_string_file_flags_to_mode(flags));
r = fchmod_umask(fileno(f), mode);
if (r < 0)
goto fail;
if (renameat(dir_fd, p, dir_fd, fn) < 0) {
r = -errno;
r = RET_NERRNO(renameat(dir_fd, p, dir_fd, fn));
if (r < 0)
goto fail;
}
if (FLAGS_SET(flags, WRITE_STRING_FILE_SYNC)) {
/* Sync the rename, too */
@ -257,7 +276,11 @@ static int write_string_file_atomic_at(
return 0;
fail:
(void) unlinkat(dir_fd, p, 0);
if (call_label_ops_post)
(void) label_ops_post(f ? fileno(f) : dir_fd, f ? NULL : fn, /* created= */ !!f);
if (f)
(void) unlinkat(dir_fd, p, 0);
return r;
}
@ -268,9 +291,10 @@ int write_string_file_full(
WriteStringFileFlags flags,
const struct timespec *ts) {
bool call_label_ops_post = false, made_file = false;
_cleanup_fclose_ FILE *f = NULL;
_cleanup_close_ int fd = -EBADF;
int q, r;
int r;
assert(fn);
assert(line);
@ -292,21 +316,40 @@ int write_string_file_full(
goto fail;
return r;
} else
assert(!ts);
}
mode_t mode = write_string_file_flags_to_mode(flags);
if (FLAGS_SET(flags, WRITE_STRING_FILE_LABEL|WRITE_STRING_FILE_CREATE)) {
r = label_ops_pre(dir_fd, fn, mode);
if (r < 0)
goto fail;
call_label_ops_post = true;
}
/* We manually build our own version of fopen(..., "we") that works without O_CREAT and with O_NOFOLLOW if needed. */
fd = openat(dir_fd, fn, O_CLOEXEC|O_NOCTTY |
(FLAGS_SET(flags, WRITE_STRING_FILE_NOFOLLOW) ? O_NOFOLLOW : 0) |
(FLAGS_SET(flags, WRITE_STRING_FILE_CREATE) ? O_CREAT : 0) |
(FLAGS_SET(flags, WRITE_STRING_FILE_TRUNCATE) ? O_TRUNC : 0) |
(FLAGS_SET(flags, WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL) ? O_RDWR : O_WRONLY),
write_string_file_flags_to_mode(flags));
fd = openat_report_new(
dir_fd, fn, O_CLOEXEC | O_NOCTTY |
(FLAGS_SET(flags, WRITE_STRING_FILE_NOFOLLOW) ? O_NOFOLLOW : 0) |
(FLAGS_SET(flags, WRITE_STRING_FILE_CREATE) ? O_CREAT : 0) |
(FLAGS_SET(flags, WRITE_STRING_FILE_TRUNCATE) ? O_TRUNC : 0) |
(FLAGS_SET(flags, WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL) ? O_RDWR : O_WRONLY),
mode,
&made_file);
if (fd < 0) {
r = -errno;
r = fd;
goto fail;
}
if (call_label_ops_post) {
call_label_ops_post = false;
r = label_ops_post(fd, /* path= */ NULL, made_file);
if (r < 0)
goto fail;
}
r = take_fdopen_unlocked(&fd, "w", &f);
if (r < 0)
goto fail;
@ -321,19 +364,24 @@ int write_string_file_full(
return 0;
fail:
if (call_label_ops_post)
(void) label_ops_post(fd >= 0 ? fd : dir_fd, fd >= 0 ? NULL : fn, made_file);
if (made_file)
(void) unlinkat(dir_fd, fn, 0);
if (!(flags & WRITE_STRING_FILE_VERIFY_ON_FAILURE))
return r;
f = safe_fclose(f);
fd = safe_close(fd);
/* OK, the operation failed, but let's see if the right
* contents in place already. If so, eat up the error. */
/* OK, the operation failed, but let's see if the right contents in place already. If so, eat up the
* error. */
if (verify_file(fn, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE) || (flags & WRITE_STRING_FILE_VERIFY_IGNORE_NEWLINE)) > 0)
return 0;
q = verify_file(fn, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE) || (flags & WRITE_STRING_FILE_VERIFY_IGNORE_NEWLINE));
if (q <= 0)
return r;
return 0;
return r;
}
int write_string_filef(

View File

@ -28,11 +28,7 @@ typedef enum {
WRITE_STRING_FILE_MODE_0600 = 1 << 10,
WRITE_STRING_FILE_MODE_0444 = 1 << 11,
WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL = 1 << 12,
/* And before you wonder, why write_string_file_atomic_label_ts() is a separate function instead of just one
more flag here: it's about linking: we don't want to pull -lselinux into all users of write_string_file()
and friends. */
WRITE_STRING_FILE_LABEL = 1 << 13,
} WriteStringFileFlags;
typedef enum {

View File

@ -1077,65 +1077,50 @@ int open_mkdir_at_full(int dirfd, const char *path, int flags, XOpenFlags xopen_
}
int openat_report_new(int dirfd, const char *pathname, int flags, mode_t mode, bool *ret_newly_created) {
unsigned attempts = 7;
int fd;
/* Just like openat(), but adds one thing: optionally returns whether we created the file anew or if
* it already existed before. This is only relevant if O_CREAT is set without O_EXCL, and thus will
* shortcut to openat() otherwise */
if (!ret_newly_created)
return RET_NERRNO(openat(dirfd, pathname, flags, mode));
* shortcut to openat() otherwise.
*
* Note that this routine is a bit more strict with symlinks than regular openat() is. If O_NOFOLLOW
* is not specified, then we'll follow the symlink when opening an existing file but we will *not*
* follow it when creating a new one (because that's a terrible UNIX misfeature and generally a
* security hole). */
if (!FLAGS_SET(flags, O_CREAT) || FLAGS_SET(flags, O_EXCL)) {
fd = openat(dirfd, pathname, flags, mode);
if (fd < 0)
return -errno;
*ret_newly_created = FLAGS_SET(flags, O_CREAT);
if (ret_newly_created)
*ret_newly_created = FLAGS_SET(flags, O_CREAT);
return fd;
}
for (;;) {
for (unsigned attempts = 7;;) {
/* First, attempt to open without O_CREAT/O_EXCL, i.e. open existing file */
fd = openat(dirfd, pathname, flags & ~(O_CREAT | O_EXCL), mode);
if (fd >= 0) {
*ret_newly_created = false;
if (ret_newly_created)
*ret_newly_created = false;
return fd;
}
if (errno != ENOENT)
return -errno;
/* So the file didn't exist yet, hence create it with O_CREAT/O_EXCL. */
fd = openat(dirfd, pathname, flags | O_CREAT | O_EXCL, mode);
/* So the file didn't exist yet, hence create it with O_CREAT/O_EXCL/O_NOFOLLOW. */
fd = openat(dirfd, pathname, flags | O_CREAT | O_EXCL | O_NOFOLLOW, mode);
if (fd >= 0) {
*ret_newly_created = true;
if (ret_newly_created)
*ret_newly_created = true;
return fd;
}
if (errno != EEXIST)
return -errno;
/* Hmm, so now we got EEXIST? This can indicate two things. First, if the path points to a
* dangling symlink, the first openat() will fail with ENOENT because the symlink is resolved
* and the second openat() will fail with EEXIST because symlinks are not followed when
* O_CREAT|O_EXCL is specified. Let's check for this explicitly and fall back to opening with
* just O_CREAT and assume we're the ones that created the file. */
struct stat st;
if (fstatat(dirfd, pathname, &st, AT_SYMLINK_NOFOLLOW) < 0)
return -errno;
if (S_ISLNK(st.st_mode)) {
fd = openat(dirfd, pathname, flags | O_CREAT, mode);
if (fd < 0)
return -errno;
*ret_newly_created = true;
return fd;
}
/* If we're not operating on a symlink, someone might have created the file between the first
* and second call to openat(). Let's try again but with a limit so we don't spin forever. */
/* Hmm, so now we got EEXIST? Then someone might have created the file between the first and
* second call to openat(). Let's try again but with a limit so we don't spin forever. */
if (--attempts == 0) /* Give up eventually, somebody is playing with us */
return -EEXIST;
@ -1164,10 +1149,14 @@ int xopenat_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_
return fd_reopen(dir_fd, open_flags & ~O_NOFOLLOW);
}
bool call_label_ops_post = false;
if (FLAGS_SET(open_flags, O_CREAT) && FLAGS_SET(xopen_flags, XO_LABEL)) {
r = label_ops_pre(dir_fd, path, FLAGS_SET(open_flags, O_DIRECTORY) ? S_IFDIR : S_IFREG);
if (r < 0)
return r;
call_label_ops_post = true;
}
if (FLAGS_SET(open_flags, O_DIRECTORY|O_CREAT)) {
@ -1183,37 +1172,19 @@ int xopenat_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_
else
made_dir = true;
if (FLAGS_SET(xopen_flags, XO_LABEL)) {
r = label_ops_post(dir_fd, path);
if (r < 0)
return r;
}
open_flags &= ~(O_EXCL|O_CREAT);
xopen_flags &= ~XO_LABEL;
}
fd = RET_NERRNO(openat_report_new(dir_fd, path, open_flags, mode, &made_file));
fd = openat_report_new(dir_fd, path, open_flags, mode, &made_file);
if (fd < 0) {
if (IN_SET(fd,
/* We got ENOENT? then someone else immediately removed it after we
* created it. In that case let's return immediately without unlinking
* anything, because there simply isn't anything to unlink anymore. */
-ENOENT,
/* is a symlink? exists already → created by someone else, don't unlink */
-ELOOP,
/* not a directory? exists already → created by someone else, don't unlink */
-ENOTDIR))
return fd;
if (made_dir)
(void) unlinkat(dir_fd, path, AT_REMOVEDIR);
return fd;
r = fd;
goto error;
}
if (FLAGS_SET(open_flags, O_CREAT) && FLAGS_SET(xopen_flags, XO_LABEL)) {
r = label_ops_post(dir_fd, path);
if (call_label_ops_post) {
call_label_ops_post = false;
r = label_ops_post(fd, /* path= */ NULL, made_file || made_dir);
if (r < 0)
goto error;
}
@ -1227,6 +1198,9 @@ int xopenat_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_
return TAKE_FD(fd);
error:
if (call_label_ops_post)
(void) label_ops_post(fd >= 0 ? fd : dir_fd, fd >= 0 ? NULL : path, made_dir || made_file);
if (made_dir || made_file)
(void) unlinkat(dir_fd, path, made_dir ? AT_REMOVEDIR : 0);

View File

@ -6,6 +6,7 @@
*/
#include "gunicode.h"
#include "macro.h"
#define unichar uint32_t
@ -92,7 +93,7 @@ unichar_iswide (unichar c)
{0x20000, 0x2FFFD}, {0x30000, 0x3FFFD},
};
if (bsearch ((void *)(uintptr_t)c, wide, (sizeof (wide) / sizeof ((wide)[0])), sizeof wide[0],
if (bsearch ((void *)(uintptr_t)c, wide, ELEMENTSOF(wide), sizeof wide[0],
interval_compare))
return true;

View File

@ -4,10 +4,13 @@
#include <stddef.h>
#include "label.h"
#include "macro.h"
static const LabelOps *label_ops = NULL;
int label_ops_set(const LabelOps *ops) {
assert(ops);
if (label_ops)
return -EBUSY;
@ -15,6 +18,10 @@ int label_ops_set(const LabelOps *ops) {
return 0;
}
void label_ops_reset(void) {
label_ops = NULL;
}
int label_ops_pre(int dir_fd, const char *path, mode_t mode) {
if (!label_ops || !label_ops->pre)
return 0;
@ -22,13 +29,9 @@ int label_ops_pre(int dir_fd, const char *path, mode_t mode) {
return label_ops->pre(dir_fd, path, mode);
}
int label_ops_post(int dir_fd, const char *path) {
int label_ops_post(int dir_fd, const char *path, bool created) {
if (!label_ops || !label_ops->post)
return 0;
return label_ops->post(dir_fd, path);
}
void label_ops_reset(void) {
label_ops = NULL;
return label_ops->post(dir_fd, path, created);
}

View File

@ -1,15 +1,16 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <stdbool.h>
#include <sys/types.h>
typedef struct LabelOps {
int (*pre)(int dir_fd, const char *path, mode_t mode);
int (*post)(int dir_fd, const char *path);
int (*post)(int dir_fd, const char *path, bool created);
} LabelOps;
int label_ops_set(const LabelOps *label_ops);
void label_ops_reset(void);
int label_ops_pre(int dir_fd, const char *path, mode_t mode);
int label_ops_post(int dir_fd, const char *path);
void label_ops_reset(void);
int label_ops_post(int dir_fd, const char *path, bool created);

View File

@ -530,7 +530,7 @@ static int measure_kernel(PcrState *pcr_states, size_t n) {
/* Our EFI stub measures VirtualSize bytes of the .linux section into PCR 11.
* Notably, VirtualSize can be larger than the section's size on disk. In
* that case the extra space is initialized with zeros, so the stub ends up
* measuring a bunch of zeros. To accomodate this, we have to measure the
* measuring a bunch of zeros. To accommodate this, we have to measure the
* same number of zeros here. We opt to measure extra zeros here instead of
* modifying the stub to only measure the number of bytes on disk as we want
* newer ukify + systemd-measure to work with older versions of the stub and

View File

@ -59,7 +59,6 @@ typedef enum MountMode {
MOUNT_BIND,
MOUNT_BIND_RECURSIVE,
MOUNT_PRIVATE_TMP,
MOUNT_PRIVATE_TMP_READ_ONLY,
MOUNT_PRIVATE_DEV,
MOUNT_BIND_DEV,
MOUNT_EMPTY_DIR,
@ -221,7 +220,7 @@ static const MountEntry protect_system_full_table[] = {
* left writable, as ProtectHome= shall manage those, orthogonally).
*/
static const MountEntry protect_system_strict_table[] = {
{ "/", MOUNT_READ_ONLY, false },
{ "/", MOUNT_READ_ONLY, false },
{ "/proc", MOUNT_READ_WRITE_IMPLICIT, false }, /* ProtectKernelTunables= */
{ "/sys", MOUNT_READ_WRITE_IMPLICIT, false }, /* ProtectKernelTunables= */
{ "/dev", MOUNT_READ_WRITE_IMPLICIT, false }, /* PrivateDevices= */
@ -243,7 +242,6 @@ static const char * const mount_mode_table[_MOUNT_MODE_MAX] = {
[MOUNT_BIND] = "bind",
[MOUNT_BIND_RECURSIVE] = "bind-recursive",
[MOUNT_PRIVATE_TMP] = "private-tmp",
[MOUNT_PRIVATE_TMP_READ_ONLY] = "private-tmp-read-only",
[MOUNT_PRIVATE_DEV] = "private-dev",
[MOUNT_BIND_DEV] = "bind-dev",
[MOUNT_EMPTY_DIR] = "empty-dir",
@ -280,7 +278,7 @@ static const struct {
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(mount_mode, MountMode);
static const char *mount_entry_path(const MountEntry *p) {
static const char* mount_entry_path(const MountEntry *p) {
assert(p);
/* Returns the path of this bind mount. If the malloc()-allocated ->path_buffer field is set we return that,
@ -289,7 +287,7 @@ static const char *mount_entry_path(const MountEntry *p) {
return p->path_malloc ?: p->path_const;
}
static const char *mount_entry_unprefixed_path(const MountEntry *p) {
static const char* mount_entry_unprefixed_path(const MountEntry *p) {
assert(p);
/* Returns the unprefixed path (ie: before prefix_where_needed() ran), if any */
@ -315,7 +313,7 @@ static void mount_entry_consume_prefix(MountEntry *p, char *new_path) {
static bool mount_entry_read_only(const MountEntry *p) {
assert(p);
return p->read_only || IN_SET(p->mode, MOUNT_READ_ONLY, MOUNT_INACCESSIBLE, MOUNT_PRIVATE_TMP_READ_ONLY);
return p->read_only || IN_SET(p->mode, MOUNT_READ_ONLY, MOUNT_INACCESSIBLE);
}
static bool mount_entry_noexec(const MountEntry *p) {
@ -330,13 +328,13 @@ static bool mount_entry_exec(const MountEntry *p) {
return p->exec || p->mode == MOUNT_EXEC;
}
static const char *mount_entry_source(const MountEntry *p) {
static const char* mount_entry_source(const MountEntry *p) {
assert(p);
return p->source_malloc ?: p->source_const;
}
static const char *mount_entry_options(const MountEntry *p) {
static const char* mount_entry_options(const MountEntry *p) {
assert(p);
return p->options_malloc ?: p->options_const;
@ -363,7 +361,7 @@ static void mount_list_done(MountList *ml) {
ml->n_mounts = 0;
}
static MountEntry *mount_list_extend(MountList *ml) {
static MountEntry* mount_list_extend(MountList *ml) {
assert(ml);
if (!GREEDY_REALLOC0(ml->mounts, ml->n_mounts+1))
@ -714,11 +712,16 @@ static int append_static_mounts(MountList *ml, const MountEntry *mounts, size_t
if (!me)
return log_oom_debug();
*me = (MountEntry) {
.path_const = mount_entry_path(m),
.mode = m->mode,
.ignore = m->ignore || ignore_protect,
};
/* No dynamic values allowed. */
assert(m->path_const);
assert(!m->path_malloc);
assert(!m->unprefixed_path_malloc);
assert(!m->source_malloc);
assert(!m->options_malloc);
assert(!m->overlay_layers);
*me = *m;
me->ignore = me->ignore || ignore_protect;
}
return 0;
@ -1741,7 +1744,6 @@ static int apply_one_mount(
return mount_tmpfs(m);
case MOUNT_PRIVATE_TMP:
case MOUNT_PRIVATE_TMP_READ_ONLY:
what = mount_entry_source(m);
make = true;
break;
@ -2397,29 +2399,27 @@ int setup_namespace(const NamespaceParameters *p, char **error_path) {
assert(p->private_tmp == PRIVATE_TMP_CONNECTED);
if (p->tmp_dir) {
bool ro = streq(p->tmp_dir, RUN_SYSTEMD_EMPTY);
MountEntry *me = mount_list_extend(&ml);
if (!me)
return log_oom_debug();
*me = (MountEntry) {
.path_const = "/tmp",
.mode = ro ? MOUNT_PRIVATE_TMP_READ_ONLY : MOUNT_PRIVATE_TMP,
.mode = MOUNT_PRIVATE_TMP,
.read_only = streq(p->tmp_dir, RUN_SYSTEMD_EMPTY),
.source_const = p->tmp_dir,
};
}
if (p->var_tmp_dir) {
bool ro = streq(p->var_tmp_dir, RUN_SYSTEMD_EMPTY);
MountEntry *me = mount_list_extend(&ml);
if (!me)
return log_oom_debug();
*me = (MountEntry) {
.path_const = "/var/tmp",
.mode = ro ? MOUNT_PRIVATE_TMP_READ_ONLY : MOUNT_PRIVATE_TMP,
.mode = MOUNT_PRIVATE_TMP,
.read_only = streq(p->var_tmp_dir, RUN_SYSTEMD_EMPTY),
.source_const = p->var_tmp_dir,
};
}

View File

@ -4,7 +4,6 @@
#include "bpf-socket-bind.h"
#include "bus-util.h"
#include "dbus.h"
#include "fileio-label.h"
#include "fileio.h"
#include "format-util.h"
#include "parse-util.h"

View File

@ -29,7 +29,6 @@
#include "exec-credential.h"
#include "execute.h"
#include "fd-util.h"
#include "fileio-label.h"
#include "fileio.h"
#include "format-util.h"
#include "id128-util.h"
@ -4620,7 +4619,7 @@ int unit_write_setting(Unit *u, UnitWriteFlags flags, const char *name, const ch
return r;
}
r = write_string_file_atomic_label(q, wrapped);
r = write_string_file(q, wrapped, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL);
if (r < 0)
return r;

View File

@ -7,7 +7,7 @@
#include "dropin.h"
#include "errno-util.h"
#include "fd-util.h"
#include "fileio-label.h"
#include "fileio.h"
#include "generator.h"
#include "initrd-util.h"
#include "parse-util.h"
@ -206,7 +206,7 @@ static int process_unit_credentials(const char *credentials_dir) {
if (!p)
return log_oom();
r = write_string_file_at_label(AT_FDCWD, p, d, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_MKDIR_0755);
r = write_string_file(p, d, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_MKDIR_0755|WRITE_STRING_FILE_LABEL);
if (r < 0) {
log_warning_errno(r, "Failed to write unit file '%s' from credential '%s', ignoring: %m",
unit, de->d_name);

View File

@ -19,7 +19,6 @@
#include "env-file-label.h"
#include "env-file.h"
#include "env-util.h"
#include "fileio-label.h"
#include "fileio.h"
#include "hostname-setup.h"
#include "hostname-util.h"
@ -619,7 +618,7 @@ static int context_write_data_static_hostname(Context *c) {
return 0;
}
r = write_string_file_atomic_label("/etc/hostname", c->data[PROP_STATIC_HOSTNAME]);
r = write_string_file("/etc/hostname", c->data[PROP_STATIC_HOSTNAME], WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL);
if (r < 0)
return r;

View File

@ -11,7 +11,6 @@
#include "env-file.h"
#include "env-util.h"
#include "fd-util.h"
#include "fileio-label.h"
#include "fileio.h"
#include "fs-util.h"
#include "kbd-util.h"

View File

@ -29,7 +29,6 @@
#include "escape.h"
#include "event-util.h"
#include "fd-util.h"
#include "fileio-label.h"
#include "fileio.h"
#include "format-util.h"
#include "fs-util.h"
@ -1593,7 +1592,7 @@ static int trigger_device(Manager *m, sd_device *parent) {
static int attach_device(Manager *m, const char *seat, const char *sysfs, sd_bus_error *error) {
_cleanup_(sd_device_unrefp) sd_device *d = NULL;
_cleanup_free_ char *rule = NULL, *file = NULL;
_cleanup_free_ char *file = NULL;
const char *id_for_seat;
int r;
@ -1614,11 +1613,10 @@ static int attach_device(Manager *m, const char *seat, const char *sysfs, sd_bus
if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
return -ENOMEM;
if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
return -ENOMEM;
(void) mkdir_p_label("/etc/udev/rules.d", 0755);
r = write_string_file_atomic_label(file, rule);
r = write_string_filef(
file,
WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_MKDIR_0755|WRITE_STRING_FILE_LABEL,
"TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat);
if (r < 0)
return r;
@ -3286,11 +3284,9 @@ static int method_set_reboot_to_boot_loader_menu(
if (unlink("/run/systemd/reboot-to-boot-loader-menu") < 0 && errno != ENOENT)
return -errno;
} else {
char buf[DECIMAL_STR_MAX(uint64_t) + 1];
xsprintf(buf, "%" PRIu64, x); /* μs granularity */
r = write_string_file_atomic_label("/run/systemd/reboot-to-boot-loader-menu", buf);
r = write_string_filef("/run/systemd/reboot-to-boot-loader-menu",
WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL,
"%" PRIu64, x); /* μs granularity */
if (r < 0)
return r;
}
@ -3479,7 +3475,7 @@ static int method_set_reboot_to_boot_loader_entry(
if (unlink("/run/systemd/reboot-to-boot-loader-entry") < 0 && errno != ENOENT)
return -errno;
} else {
r = write_string_file_atomic_label("/run/systemd/reboot-boot-to-loader-entry", v);
r = write_string_file("/run/systemd/reboot-boot-to-loader-entry", v, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL);
if (r < 0)
return r;
}

View File

@ -109,6 +109,40 @@ static int property_get_idle_hint(
return sd_bus_message_append(reply, "b", session_get_idle_hint(s, NULL) > 0);
}
static int property_get_can_idle(
sd_bus *bus,
const char *path,
const char *interface,
const char *property,
sd_bus_message *reply,
void *userdata,
sd_bus_error *error) {
Session *s = ASSERT_PTR(userdata);
assert(bus);
assert(reply);
return sd_bus_message_append(reply, "b", SESSION_CLASS_CAN_IDLE(s->class));
}
static int property_get_can_lock(
sd_bus *bus,
const char *path,
const char *interface,
const char *property,
sd_bus_message *reply,
void *userdata,
sd_bus_error *error) {
Session *s = ASSERT_PTR(userdata);
assert(bus);
assert(reply);
return sd_bus_message_append(reply, "b", SESSION_CLASS_CAN_LOCK(s->class));
}
static int property_get_idle_since_hint(
sd_bus *bus,
const char *path,
@ -855,14 +889,11 @@ int session_send_lock_all(Manager *m, bool lock) {
assert(m);
HASHMAP_FOREACH(session, m->sessions) {
int k;
if (!SESSION_CLASS_CAN_LOCK(session->class))
continue;
k = session_send_lock(session, lock);
if (k < 0)
r = k;
RET_GATHER(r, session_send_lock(session, lock));
}
return r;
@ -983,6 +1014,8 @@ static const sd_bus_vtable session_vtable[] = {
SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("CanIdle", "b", property_get_can_idle, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("CanLock", "b", property_get_can_lock, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("LockedHint", "b", property_get_locked_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_METHOD("Terminate",

View File

@ -1098,6 +1098,9 @@ int session_get_idle_hint(Session *s, dual_timestamp *t) {
assert(s);
if (!SESSION_CLASS_CAN_IDLE(s->class))
return false;
/* Graphical sessions have an explicit idle hint */
if (SESSION_TYPE_IS_GRAPHICAL(s->type)) {
if (t)

View File

@ -601,11 +601,11 @@ static void serialize_resolvers(
r = sd_dhcp_lease_get_dnr(lease, &resolvers);
if (r < 0)
return (void) log_warning_errno(r, "Failed to get DNR from DHCP lease, ignoring.");
return (void) log_debug_errno(r, "Failed to get DNR from DHCP lease, ignoring: %m");
r = dns_resolvers_to_dot_strv(resolvers, r, &names);
if (r < 0)
return (void) log_warning_errno(r, "Failed to get DoT servers from DHCP DNR, ignoring.");
return (void) log_warning_errno(r, "Failed to get DoT servers from DHCP DNR, ignoring: %m");
if (r > 0)
fputstrv(f, names, NULL, space);
}
@ -617,11 +617,11 @@ static void serialize_resolvers(
r = sd_dhcp6_lease_get_dnr(lease6, &resolvers);
if (r < 0)
return (void) log_warning_errno(r, "Failed to get DNR from DHCPv6 lease, ignoring.");
return (void) log_debug_errno(r, "Failed to get DNR from DHCPv6 lease, ignoring: %m");
r = dns_resolvers_to_dot_strv(resolvers, r, &names);
if (r < 0)
return (void) log_warning_errno(r, "Failed to get DoT servers from DHCPv6 DNR, ignoring.");
return (void) log_warning_errno(r, "Failed to get DoT servers from DHCPv6 DNR, ignoring: %m");
if (r > 0)
fputstrv(f, names, NULL, space);
}

View File

@ -12,7 +12,7 @@
#include "dropin.h"
#include "escape.h"
#include "fd-util.h"
#include "fileio-label.h"
#include "fileio.h"
#include "hashmap.h"
#include "log.h"
#include "macro.h"
@ -87,7 +87,7 @@ int write_drop_in(
if (r < 0)
return r;
return write_string_file_at_label(AT_FDCWD, p, data, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_MKDIR_0755);
return write_string_file(p, data, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_MKDIR_0755|WRITE_STRING_FILE_LABEL);
}
int write_drop_in_format(

View File

@ -1,43 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <sys/stat.h>
#include "fileio-label.h"
#include "fileio.h"
#include "selinux-util.h"
int write_string_file_full_label(int atfd, const char *fn, const char *line, WriteStringFileFlags flags, struct timespec *ts) {
int r;
r = mac_selinux_create_file_prepare_at(atfd, fn, S_IFREG);
if (r < 0)
return r;
r = write_string_file_full(atfd, fn, line, flags, ts);
mac_selinux_create_file_clear();
return r;
}
int create_shutdown_run_nologin_or_warn(void) {
int r;
/* This is used twice: once in systemd-user-sessions.service, in order to block logins when we
* actually go down, and once in systemd-logind.service when shutdowns are scheduled, and logins are
* to be turned off a bit in advance. We use the same wording of the message in both cases.
*
* Traditionally, there was only /etc/nologin, and we managed that. Then, in PAM 1.1
* support for /run/nologin was added as alternative
* (https://github.com/linux-pam/linux-pam/commit/e9e593f6ddeaf975b7fe8446d184e6bc387d450b).
* 13 years later we stopped managing /etc/nologin, leaving it for the administrator to manage.
*/
r = write_string_file_atomic_label("/run/nologin",
"System is going down. Unprivileged users are not permitted to log in anymore. "
"For technical details, see pam_nologin(8).");
if (r < 0)
return log_error_errno(r, "Failed to create /run/nologin: %m");
return 0;
}

View File

@ -1,20 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <stdio.h>
/* These functions are split out of fileio.h (and not for example just flags to the functions they wrap) in order to
* optimize linking: This way, -lselinux is needed only for the callers of these functions that need selinux, but not
* for all */
#include "fileio.h"
int write_string_file_full_label(int atfd, const char *fn, const char *line, WriteStringFileFlags flags, struct timespec *ts);
static inline int write_string_file_at_label(int atfd, const char *fn, const char *line, WriteStringFileFlags flags) {
return write_string_file_full_label(atfd, fn, line, flags, /* ts= */ NULL);
}
static inline int write_string_file_atomic_label(const char *fn, const char *line) {
return write_string_file_at_label(AT_FDCWD, fn, line, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC);
}
int create_shutdown_run_nologin_or_warn(void);

View File

@ -72,7 +72,6 @@ shared_sources = files(
'extension-util.c',
'fdset.c',
'fido2-util.c',
'fileio-label.c',
'find-esp.c',
'firewall-util-nft.c',
'firewall-util.c',

View File

@ -204,3 +204,26 @@ bool kexec_loaded(void) {
return s[0] == '1';
}
int create_shutdown_run_nologin_or_warn(void) {
int r;
/* This is used twice: once in systemd-user-sessions.service, in order to block logins when we
* actually go down, and once in systemd-logind.service when shutdowns are scheduled, and logins are
* to be turned off a bit in advance. We use the same wording of the message in both cases.
*
* Traditionally, there was only /etc/nologin, and we managed that. Then, in PAM 1.1
* support for /run/nologin was added as alternative
* (https://github.com/linux-pam/linux-pam/commit/e9e593f6ddeaf975b7fe8446d184e6bc387d450b).
* 13 years later we stopped managing /etc/nologin, leaving it for the administrator to manage.
*/
r = write_string_file("/run/nologin",
"System is going down. Unprivileged users are not permitted to log in anymore. "
"For technical details, see pam_nologin(8).",
WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL);
if (r < 0)
return log_error_errno(r, "Failed to create /run/nologin: %m");
return 0;
}

View File

@ -1,6 +1,8 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <stdbool.h>
bool reboot_parameter_is_valid(const char *parameter);
int update_reboot_parameter_and_warn(const char *parameter, bool keep);
@ -16,3 +18,5 @@ int reboot_with_parameter(RebootFlags flags);
bool shall_restore_state(void);
bool kexec_loaded(void);
int create_shutdown_run_nologin_or_warn(void);

View File

@ -64,7 +64,7 @@ static int mac_selinux_label_pre(int dir_fd, const char *path, mode_t mode) {
return mac_selinux_create_file_prepare_at(dir_fd, path, mode);
}
static int mac_selinux_label_post(int dir_fd, const char *path) {
static int mac_selinux_label_post(int dir_fd, const char *path, bool created) {
mac_selinux_create_file_clear();
return 0;
}

View File

@ -294,7 +294,10 @@ static int mac_smack_label_pre(int dir_fd, const char *path, mode_t mode) {
return 0;
}
static int mac_smack_label_post(int dir_fd, const char *path) {
static int mac_smack_label_post(int dir_fd, const char *path, bool created) {
if (!created)
return 0;
return mac_smack_fix_full(dir_fd, path, NULL, 0);
}

View File

@ -670,6 +670,9 @@ TEST(openat_report_new) {
ASSERT_OK_ERRNO(symlinkat("target", tfd, "link"));
fd = openat_report_new(tfd, "link", O_RDWR|O_CREAT, 0666, &b);
ASSERT_ERROR(fd, EEXIST);
fd = openat_report_new(tfd, "target", O_RDWR|O_CREAT, 0666, &b);
ASSERT_OK(fd);
fd = safe_close(fd);
ASSERT_TRUE(b);

View File

@ -286,9 +286,8 @@ TEST(id128_at) {
ASSERT_OK_ERRNO(unlinkat(tfd, "etc/machine-id", 0));
ASSERT_OK(id128_write_at(tfd, "etc2/machine-id", ID128_FORMAT_PLAIN, id));
ASSERT_OK_ERRNO(unlinkat(tfd, "etc/machine-id", 0));
ASSERT_OK(id128_write_at(tfd, "etc/hoge-id", ID128_FORMAT_PLAIN, id));
ASSERT_OK_ERRNO(unlinkat(tfd, "etc/machine-id", 0));
ASSERT_OK(id128_write_at(tfd, "etc2/hoge-id", ID128_FORMAT_PLAIN, id));
ASSERT_ERROR(id128_write_at(tfd, "etc/hoge-id", ID128_FORMAT_PLAIN, id), EEXIST);
ASSERT_OK(id128_write_at(tfd, "etc2/machine-id", ID128_FORMAT_PLAIN, id));
/* id128_read_at() */
i = SD_ID128_NULL; /* Not necessary in real code, but for testing that the id is really assigned. */

View File

@ -43,7 +43,7 @@ static int pre_labelling_func(int dir_fd, const char *path, mode_t mode) {
return 0;
}
static int post_labelling_func(int dir_fd, const char *path) {
static int post_labelling_func(int dir_fd, const char *path, bool created) {
int r;
/* assume label policies that restrict certain labels */
@ -140,17 +140,17 @@ TEST(label_ops_post) {
text1 = "Add initial texts to file for testing label operations to file1\n";
assert(labelling_op(fd, text1, "file1.txt", 0644) == 0);
assert_se(label_ops_post(fd, "file1.txt") == 0);
assert_se(label_ops_post(fd, "file1.txt", true) == 0);
assert_se(strlen(text1) == (size_t)buf.st_size);
text2 = "Add text2 data to file2\n";
assert(labelling_op(fd, text2, "file2.txt", 0644) == 0);
assert_se(label_ops_post(fd, "file2.txt") == 0);
assert_se(label_ops_post(fd, "file2.txt", true) == 0);
assert_se(strlen(text2) == (size_t)buf.st_size);
assert_se(label_ops_post(fd, "file3.txt") == -ENOENT);
assert_se(label_ops_post(fd, "/abcd") == -ENOENT);
assert_se(label_ops_post(fd, "/restricted_directory") == -EACCES);
assert_se(label_ops_post(fd, "") == -EINVAL);
assert_se(label_ops_post(fd, "file3.txt", true) == -ENOENT);
assert_se(label_ops_post(fd, "/abcd", true) == -ENOENT);
assert_se(label_ops_post(fd, "/restricted_directory", true) == -EACCES);
assert_se(label_ops_post(fd, "", true) == -EINVAL);
}
DEFINE_TEST_MAIN(LOG_INFO)

View File

@ -74,16 +74,15 @@ TEST(tpm2_util_pbkdf2_hmac_sha256) {
};
uint8_t res[SHA256_DIGEST_SIZE];
for (size_t i = 0; i < sizeof(test_vectors)/sizeof(test_vectors[0]); i++) {
FOREACH_ELEMENT(vector, test_vectors) {
int rc = tpm2_util_pbkdf2_hmac_sha256(
test_vectors[i].pass,
test_vectors[i].passlen,
test_vectors[i].salt,
test_vectors[i].saltlen,
vector->pass,
vector->passlen,
vector->salt,
vector->saltlen,
res);
assert_se(rc == 0);
assert_se(memcmp(test_vectors[i].expected, res, SHA256_DIGEST_SIZE) == 0);
assert_se(memcmp(vector->expected, res, SHA256_DIGEST_SIZE) == 0);
}
}

View File

@ -24,7 +24,6 @@
#include "constants.h"
#include "daemon-util.h"
#include "fd-util.h"
#include "fileio-label.h"
#include "fileio.h"
#include "fs-util.h"
#include "hashmap.h"
@ -395,7 +394,7 @@ static int context_write_data_local_rtc(Context *c) {
if (r < 0)
return r;
return write_string_file_atomic_label("/etc/adjtime", w);
return write_string_file("/etc/adjtime", w, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL);
}
static int context_update_ntp_status(Context *c, sd_bus *bus, sd_bus_message *m) {

View File

@ -557,7 +557,6 @@ static int do_scsi_page83_inquiry(struct scsi_id_device *dev_scsi, int fd,
char *unit_serial_number, char *wwn,
char *wwn_vendor_extension, char *tgpt_group) {
int retval;
unsigned id_ind, j;
unsigned char page_83[SCSI_INQ_BUFF_LEN];
/* also pick up the page 80 serial number */
@ -611,16 +610,14 @@ static int do_scsi_page83_inquiry(struct scsi_id_device *dev_scsi, int fd,
* Search for a match in the prioritized id_search_list - since WWN ids
* come first we can pick up the WWN in check_fill_0x83_id().
*/
for (id_ind = 0;
id_ind < sizeof(id_search_list)/sizeof(id_search_list[0]);
id_ind++) {
FOREACH_ELEMENT(search_value, id_search_list) {
/*
* Examine each descriptor returned. There is normally only
* one or a small number of descriptors.
*/
for (j = 4; j <= ((unsigned)page_83[2] << 8) + (unsigned)page_83[3] + 3; j += page_83[j + 3] + 4) {
for (unsigned j = 4; j <= ((unsigned)page_83[2] << 8) + (unsigned)page_83[3] + 3; j += page_83[j + 3] + 4) {
retval = check_fill_0x83_id(dev_scsi, page_83 + j,
id_search_list + id_ind,
search_value,
serial, serial_short, len,
wwn, wwn_vendor_extension,
tgpt_group);

View File

@ -356,7 +356,7 @@ static bool test_key(
i * BITS_PER_LONG, yes_no(found));
}
/* If there are no keys in the lower block, check the higher blocks */
for (size_t block = 0; block < sizeof(high_key_blocks) / sizeof(struct range) && !found; block++)
for (size_t block = 0; block < ELEMENTSOF(high_key_blocks) && !found; block++)
for (unsigned i = high_key_blocks[block].start; i < high_key_blocks[block].end && !found; i++)
if (test_bit(i, bitmask_key)) {
log_device_debug(dev, "test_key: Found key %x in high block", i);

View File

@ -5,7 +5,7 @@
#include <unistd.h>
#include "alloc-util.h"
#include "fileio-label.h"
#include "fileio.h"
#include "selinux-util.h"
#include "time-util.h"
@ -29,7 +29,7 @@ static int apply_timestamp(const char *path, struct timespec *ts) {
timespec_load_nsec(ts)) < 0)
return log_oom();
r = write_string_file_full_label(AT_FDCWD, path, message, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC, ts);
r = write_string_file_full(AT_FDCWD, path, message, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL, ts);
if (r == -EROFS)
log_debug_errno(r, "Cannot create \"%s\", file system is read-only.", path);
else if (r < 0)

View File

@ -6,11 +6,10 @@
#include <sys/types.h>
#include <unistd.h>
#include "fileio.h"
#include "fileio-label.h"
#include "fs-util.h"
#include "main-func.h"
#include "log.h"
#include "main-func.h"
#include "reboot-util.h"
#include "selinux-util.h"
#include "string-util.h"

View File

@ -55,13 +55,22 @@ if [[ -z "${COVERAGE_BUILD_DIR:-}" ]]; then
bash -xec "test ! -w /home; test ! -w /root; test ! -w /run/user; test ! -e $MARK"
systemd-run --wait --pipe -p ProtectHome=read-only \
bash -xec "test ! -w /home; test ! -w /root; test ! -w /run/user; test -e $MARK"
systemd-run --wait --pipe -p ProtectHome=tmpfs \
bash -xec "test -w /home; test -w /root; test -w /run/user; test ! -e $MARK"
systemd-run --wait --pipe -p ProtectHome=tmpfs -p TemporaryFileSystem=/home/foo \
bash -xec "test ! -w /home; test ! -w /root; test ! -w /run/user; test ! -e $MARK; test -w /home/foo"
systemd-run --wait --pipe -p ProtectHome=no \
bash -xec "test -w /home; test -w /root; test -w /run/user; test -e $MARK"
rm -f "$MARK"
fi
systemd-run --wait --pipe -p PrivateMounts=true -p MountAPIVFS=yes \
bash -xec '[[ "$(findmnt --mountpoint /proc --noheadings -o FSTYPE)" == proc ]];
[[ "$$(findmnt --mountpoint /dev --noheadings -o FSTYPE)" =~ (devtmpfs|tmpfs) ]];
[[ "$$(findmnt --mountpoint /sys --noheadings -o FSTYPE)" =~ (sysfs|tmpfs) ]];
[[ "$$(findmnt --mountpoint /run --noheadings -o FSTYPE)" == tmpfs ]];
[[ "$$(findmnt --mountpoint /run --noheadings -o VFS-OPTIONS)" =~ rw ]];
[[ "$$(findmnt --mountpoint /run --noheadings -o VFS-OPTIONS)" =~ nosuid ]];
[[ "$$(findmnt --mountpoint /run --noheadings -o VFS-OPTIONS)" =~ nodev ]]'
if proc_supports_option "hidepid=off"; then
systemd-run --wait --pipe -p ProtectProc=noaccess -p User=testuser \
bash -xec 'test -e /proc/1; test ! -r /proc/1; test -r /proc/$$$$/comm'

View File

@ -575,6 +575,8 @@ testcase_list_users_sessions_seats() {
session=$(loginctl list-sessions --no-legend | grep -v manager | awk '$3 == "logind-test-user" { print $1 }')
: check that we got a valid session id
busctl get-property org.freedesktop.login1 "/org/freedesktop/login1/session/_3${session?}" org.freedesktop.login1.Session Id
busctl get-property org.freedesktop.login1 "/org/freedesktop/login1/session/_3${session?}" org.freedesktop.login1.Session CanIdle
busctl get-property org.freedesktop.login1 "/org/freedesktop/login1/session/_3${session?}" org.freedesktop.login1.Session CanLock
assert_eq "$(loginctl list-sessions --no-legend | grep -v manager | awk '$3 == "logind-test-user" { print $2 }')" "$(id -ru logind-test-user)"
seat=$(loginctl list-sessions --no-legend | grep -v manager | awk '$3 == "logind-test-user" { print $4 }')
assert_eq "$(loginctl list-sessions --no-legend | grep -v manager | awk '$3 == "logind-test-user" { print $6 }')" user

View File

@ -226,7 +226,7 @@ EOF
}
testcase_duration_override() {
# Verify memory pressure duration can be overriden to non-zero values
# Verify memory pressure duration can be overridden to non-zero values
mkdir -p /run/systemd/system/TEST-55-OOMD-testmunch.service.d/
cat >/run/systemd/system/TEST-55-OOMD-testmunch.service.d/99-duration-test.conf <<EOF
[Service]