If a distro build is used, please just paste the package version, e.g. `systemd-250.7-1.fc36.x86_64`.
See https://github.com/systemd/systemd-stable/tags for the list of most recent releases.
For older version please use distribution trackers (see https://systemd.io/CONTRIBUTING#filing-issues).
- placeholder: '251'
+ placeholder: '252'
validations:
required: true
attributes:
label: The systemd version you checked that didn't have the feature you are asking for
description: If this is not the most recently released upstream version, then please check first if it has that feature already.
- placeholder: '251'
+ placeholder: '252'
validations:
required: false
* `$SYSTEMD_DISSECT_VERITY_TIMEOUT_SEC=sec` — takes a timespan, which controls
the timeout waiting for the image to be configured. Defaults to 100 msec.
+* `$SYSTEMD_DISSECT_FILE_SYSTEMS=` — takes a colon-separated list of file
+ systems that may be mounted for automatically dissected disk images. If not
+ specified defaults to something like: `ext4:btrfs:xfs:vfat:erofs:squashfs`
+
* `$SYSTEMD_LOOP_DIRECT_IO` – takes a boolean, which controls whether to enable
LO_FLAGS_DIRECT_IO (i.e. direct IO + asynchronous IO) on loopback block
devices when opening them. Defaults to on, set this to "0" to disable this
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pn*:*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn*:*
+ KEYBOARD_KEY_91=config # MSIControl Center
KEYBOARD_KEY_a0=mute # Fn+F9
KEYBOARD_KEY_ae=volumedown # Fn+F7
KEYBOARD_KEY_b0=volumeup # Fn+F8
KEYBOARD_KEY_e4=f21 # Fn+F3 Touchpad disable
KEYBOARD_KEY_ec=email # envelope button
KEYBOARD_KEY_ee=camera # Fn+F6 camera disable
+ KEYBOARD_KEY_f1=f20 # Microphone mute
+ KEYBOARD_KEY_f2=rotate_display # Rotate screen
KEYBOARD_KEY_f6=wlan # satellite dish1
KEYBOARD_KEY_f7=brightnessdown # Fn+F4
KEYBOARD_KEY_f8=brightnessup # Fn+F5
KEYBOARD_KEY_0213=f22
KEYBOARD_KEY_0214=f23
-# MSI Bravo 15-B5DX FnKeys
-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn*Bravo15B5D*:*
- KEYBOARD_KEY_f1=f20 # Fn+F5 Micmute
-
##########################################
# NEC
##########################################
# subsystem[1]. The default, when unset, is equivalent to:
# ACCEL_MOUNT_MATRIX=1, 0, 0; 0, 1, 0; 0, 0, 1
# eg. the identity matrix,
-# and <value> is an integer value above which an object is considered
-# close by a proximity sensor:
+# and <value> is an integer value above or equal to which an object is
+# considered close by a proximity sensor:
# PROXIMITY_NEAR_LEVEL=100
#
# [1]: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=dfc57732ad38f93ae6232a3b4e64fd077383a0f1
<term><varname>rw</varname></term>
<listitem>
- <para>Configures the root file system and its file system
- type and mount options, as well as whether it shall be
- mounted read-only or read-write initially. For details,
- see
+ <para>Configures the root file system and its file system type and mount options, as well as
+ whether it shall be mounted read-only or read-write initially. For details, see
<citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+
+ <para>If <varname>root=</varname> is not set (or set to <literal>gpt-auto</literal>) the automatic
+ root partition discovery implemented by
+ <citerefentry><refentrytitle>systemd-gpt-auto-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ will be in effect. In this case <varname>rootfstype=</varname>, <varname>rootflags=</varname>,
+ <varname>ro</varname>, <varname>rw</varname> will be interpreted by
+ <command>systemd-gpt-auto-generator</command>.</para>
</listitem>
</varlistentry>
temporary files which will be written to the real location if the
editor exits successfully.</para>
+ <para>If <option>--drop-in=</option> is specified, the given drop-in file name
+ will be used instead of the default <filename>override.conf</filename>.</para>
+
<para>If <option>--full</option> is specified, this will copy the
original units instead of creating drop-in files.</para>
<listitem><para>When used with <command>bind</command>, creates a read-only bind mount.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--drop-in=</option></term>
+
+ <listitem>
+ <para>When used with <command>edit</command>, use the given drop-in file name instead of
+ <filename>override.conf</filename>.</para>
+ </listitem>
+ </varlistentry>
+
<xi:include href="user-system-options.xml" xpointer="host" />
<xi:include href="user-system-options.xml" xpointer="machine" />
<varlistentry>
<term><varname>root=</varname></term>
+ <term><varname>rootfstype=</varname></term>
+ <term><varname>rootflags=</varname></term>
- <listitem><para>When used with the special value <literal>gpt-auto</literal>, automatic discovery of
- the root partition based on the GPT partition type is enabled. Any other value disables this
- generator.</para></listitem>
+ <listitem><para>When <varname>root=</varname> is used with the special value
+ <literal>gpt-auto</literal> (or if the parameter is not used at all), automatic discovery of the root
+ partition based on the GPT partition type is enabled. Any other value disables this
+ logic.</para>
+
+ <para>The <varname>rootfstype=</varname> and <varname>rootflags=</varname> are used to select the
+ file system type and options when the root file system is automatically discovered.</para></listitem>
</varlistentry>
<varlistentry>
<citerefentry><refentrytitle>systemd.path</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.timer</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.slice</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>systemd.scope</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>systemd.nspawn</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ <citerefentry><refentrytitle>systemd.scope</refentrytitle><manvolnum>5</manvolnum></citerefentry>
</para></listitem>
<listitem><para>link files, see
<citerefentry><refentrytitle>systemd-sleep.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>timesyncd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
</para></listitem>
+
+ <listitem><para>nspawn files, see
+ <citerefentry><refentrytitle>systemd.nspawn</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ </para></listitem>
</itemizedlist>
</para>
# Execute the match patterns below, from least-to-most specific.
# Device matching the modalias string (bustype, vendor, product, version, other properties)
-IMPORT{builtin}="hwdb --subsystem=input --lookup-prefix=evdev:",
+IMPORT{builtin}="hwdb --subsystem=input --lookup-prefix=evdev:", \
ENV{.HAVE_HWDB_PROPERTIES}="1"
# AT keyboard matching by the machine's DMI data
assert_se(close_nointr(fd) != -EBADF);
}
- return -1;
+ return -EBADF;
}
for (todo = buffer;;) {
_cleanup_free_ char *first = NULL;
- _cleanup_close_ int child = -1;
+ _cleanup_close_ int child = -EBADF;
struct stat st;
const char *e;
"Refusing to loop over %d potential fds.",
max_fd);
- for (int fd = 3; fd >= 0; fd = fd < max_fd ? fd + 1 : -1) {
+ for (int fd = 3; fd >= 0; fd = fd < max_fd ? fd + 1 : -EBADF) {
int q;
if (fd_in_set(fd, except, n_except))
/* Make sure we can distinguish fd 0 and NULL */
#define FD_TO_PTR(fd) INT_TO_PTR((fd)+1)
#define PTR_TO_FD(p) (PTR_TO_INT(p)-1)
+#define PIPE_EBADF { -EBADF, -EBADF }
int close_nointr(int fd);
int safe_close(int fd);
void safe_close_pair(int p[static 2]);
static inline int safe_close_above_stdio(int fd) {
- if (fd < 3) /* Don't close stdin/stdout/stderr, but still invalidate the fd by returning -1 */
- return -1;
+ if (fd < 3) /* Don't close stdin/stdout/stderr, but still invalidate the fd by returning -EBADF. */
+ return -EBADF;
return safe_close(fd);
}
int rearrange_stdio(int original_input_fd, int original_output_fd, int original_error_fd);
static inline int make_null_stdio(void) {
- return rearrange_stdio(-1, -1, -1);
+ return rearrange_stdio(-EBADF, -EBADF, -EBADF);
}
/* Like TAKE_PTR() but for file descriptors, resetting them to -1 */
r = xfopenat(dir_fd, filename, "re", 0, &f);
if (r < 0) {
- _cleanup_close_ int sk = -1;
+ _cleanup_close_ int sk = -EBADF;
/* ENXIO is what Linux returns if we open a node that is an AF_UNIX socket */
if (r != -ENXIO)
struct iovec_wrapper *iovw_free(struct iovec_wrapper *iovw);
struct iovec_wrapper *iovw_free_free(struct iovec_wrapper *iovw);
void iovw_free_contents(struct iovec_wrapper *iovw, bool free_vectors);
+
int iovw_put(struct iovec_wrapper *iovw, void *data, size_t len);
+static inline int iovw_consume(struct iovec_wrapper *iovw, void *data, size_t len) {
+ /* Move data into iovw or free on error */
+ int r = iovw_put(iovw, data, len);
+ if (r < 0)
+ free(data);
+ return r;
+}
+
int iovw_put_string_field(struct iovec_wrapper *iovw, const char *field, const char *value);
int iovw_put_string_field_free(struct iovec_wrapper *iovw, const char *field, char *value);
void iovw_rebase(struct iovec_wrapper *iovw, char *old, char *new);
_Pragma("GCC diagnostic push")
#endif
-#define DISABLE_WARNING_TYPE_LIMITS \
+#define DISABLE_WARNING_TYPE_LIMITS \
_Pragma("GCC diagnostic push"); \
_Pragma("GCC diagnostic ignored \"-Wtype-limits\"")
+#define DISABLE_WARNING_ADDRESS \
+ _Pragma("GCC diagnostic push"); \
+ _Pragma("GCC diagnostic ignored \"-Waddress\"")
+
#define REENABLE_WARNING \
_Pragma("GCC diagnostic pop")
*p = func(*p); \
}
-/* When func() doesn't return the appropriate type, set variable to empty afterwards */
+/* When func() doesn't return the appropriate type, set variable to empty afterwards.
+ * The func() may be provided by a dynamically loaded shared library, hence add an assertion. */
#define DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(type, func, empty) \
static inline void func##p(type *p) { \
if (*p != (empty)) { \
+ DISABLE_WARNING_ADDRESS; \
+ assert(func); \
+ REENABLE_WARNING; \
func(*p); \
*p = (empty); \
} \
return b ? "enable" : "disable";
}
-static inline const char *empty_to_null(const char *p) {
- return isempty(p) ? NULL : p;
-}
+/* This macro's return pointer will have the "const" qualifier set or unset the same way as the input
+ * pointer. */
+#define empty_to_null(p) \
+ ({ \
+ const char *_p = (p); \
+ (typeof(p)) (isempty(_p) ? NULL : _p); \
+ })
static inline const char *empty_to_na(const char *p) {
return isempty(p) ? "n/a" : p;
static inline const char *empty_or_dash_to_null(const char *p) {
return empty_or_dash(p) ? NULL : p;
}
+#define empty_or_dash_to_null(p) \
+ ({ \
+ const char *_p = (p); \
+ (typeof(p)) (empty_or_dash(_p) ? NULL : _p); \
+ })
char *first_word(const char *s, const char *word) _pure_;
int openpt_allocate_in_namespace(pid_t pid, int flags, char **ret_slave) {
_cleanup_close_ int pidnsfd = -EBADF, mntnsfd = -EBADF, usernsfd = -EBADF, rootfd = -EBADF, fd = -EBADF;
- _cleanup_close_pair_ int pair[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int pair[2] = PIPE_EBADF;
pid_t child;
int r;
int open_terminal_in_namespace(pid_t pid, const char *name, int mode) {
_cleanup_close_ int pidnsfd = -EBADF, mntnsfd = -EBADF, usernsfd = -EBADF, rootfd = -EBADF;
- _cleanup_close_pair_ int pair[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int pair[2] = PIPE_EBADF;
pid_t child;
int r;
size_t l;
int r;
- r = rearrange_stdio(-1, -1, -1);
+ r = make_null_stdio();
if (r < 0) {
log_error_errno(r, "Failed to connect stdin/stdout/stderr with /dev/null: %m");
return EXIT_FAILURE;
static void automount_enter_waiting(Automount *a) {
_cleanup_close_ int ioctl_fd = -EBADF;
- int pipe_fd[2] = { -EBADF, -EBADF };
+ int pipe_fd[2] = PIPE_EBADF;
char name[STRLEN("systemd-") + DECIMAL_STR_MAX(pid_t) + 1];
_cleanup_free_ char *options = NULL;
bool mounted = false;
}
static int dynamic_user_acquire(Manager *m, const char *name, DynamicUser** ret) {
- _cleanup_close_pair_ int storage_socket[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int storage_socket[2] = PIPE_EBADF;
DynamicUser *d;
int r;
if (r < 0)
return r;
- storage_socket[0] = storage_socket[1] = -1;
+ storage_socket[0] = storage_socket[1] = -EBADF;
if (ret) {
d->n_ref++;
uid_t *ret_uid, gid_t *ret_gid,
bool is_user) {
- _cleanup_(unlockfp) int storage_socket0_lock = -1;
+ _cleanup_(unlockfp) int storage_socket0_lock = -EBADF;
_cleanup_close_ int uid_lock_fd = -EBADF;
_cleanup_close_ int etc_passwd_lock_fd = -EBADF;
uid_t num = UID_INVALID; /* a uid if is_user, and a gid otherwise */
}
int dynamic_user_current(DynamicUser *d, uid_t *ret) {
- _cleanup_(unlockfp) int storage_socket0_lock = -1;
+ _cleanup_(unlockfp) int storage_socket0_lock = -EBADF;
_cleanup_close_ int lock_fd = -EBADF;
uid_t uid;
int r;
}
static int dynamic_user_close(DynamicUser *d) {
- _cleanup_(unlockfp) int storage_socket0_lock = -1;
+ _cleanup_(unlockfp) int storage_socket0_lock = -EBADF;
_cleanup_close_ int lock_fd = -EBADF;
uid_t uid;
int r;
static int setup_private_users(uid_t ouid, gid_t ogid, uid_t uid, gid_t gid) {
_cleanup_free_ char *uid_map = NULL, *gid_map = NULL;
- _cleanup_close_pair_ int errno_pipe[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int errno_pipe[2] = PIPE_EBADF;
_cleanup_close_ int unshare_ready_fd = -EBADF;
_cleanup_(sigkill_waitp) pid_t pid = 0;
uint64_t c = 1;
*n = (ExecRuntime) {
.id = TAKE_PTR(id_copy),
- .netns_storage_socket = { -EBADF, -EBADF },
- .ipcns_storage_socket = { -EBADF, -EBADF },
+ .netns_storage_socket = PIPE_EBADF,
+ .ipcns_storage_socket = PIPE_EBADF,
};
*ret = n;
ExecRuntime **ret) {
_cleanup_(namespace_cleanup_tmpdirp) char *tmp_dir = NULL, *var_tmp_dir = NULL;
- _cleanup_close_pair_ int netns_storage_socket[2] = { -EBADF, -EBADF }, ipcns_storage_socket[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int netns_storage_socket[2] = PIPE_EBADF, ipcns_storage_socket[2] = PIPE_EBADF;
int r;
assert(m);
.notify_fd = -EBADF,
.cgroups_agent_fd = -EBADF,
.signal_fd = -EBADF,
- .user_lookup_fds = { -EBADF, -EBADF },
+ .user_lookup_fds = PIPE_EBADF,
.private_listen_fd = -EBADF,
.dev_autofs_fd = -EBADF,
.cgroup_inotify_fd = -EBADF,
}
int setup_shareable_ns(const int ns_storage_socket[static 2], unsigned long nsflag) {
- _cleanup_close_ int ns = -1;
+ _cleanup_close_ int ns = -EBADF;
int r, q;
const char *ns_name, *ns_path;
}
int open_shareable_ns_path(const int ns_storage_socket[static 2], const char *path, unsigned long nsflag) {
- _cleanup_close_ int ns = -1;
+ _cleanup_close_ int ns = -EBADF;
int q, r;
assert(ns_storage_socket);
sd_event_source **ret_event_source,
int *ret_exec_fd) {
- _cleanup_close_pair_ int p[] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int p[] = PIPE_EBADF;
int r;
assert(s);
const SocketAddress *address,
const char *label) {
- _cleanup_close_pair_ int pair[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int pair[2] = PIPE_EBADF;
int fd, r;
pid_t pid;
}
static int socket_accept_in_cgroup(Socket *s, SocketPort *p, int fd) {
- _cleanup_close_pair_ int pair[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int pair[2] = PIPE_EBADF;
int cfd, r;
pid_t pid;
#include <stdio.h>
#include <sys/prctl.h>
#include <sys/statvfs.h>
+#include <sys/auxv.h>
#include <sys/xattr.h>
#include <unistd.h>
META_EXE = _META_MANDATORY_MAX,
META_UNIT,
+ META_PROC_AUXV,
_META_MAX
};
static const char * const meta_field_names[_META_MAX] = {
- [META_ARGV_PID] = "COREDUMP_PID=",
- [META_ARGV_UID] = "COREDUMP_UID=",
- [META_ARGV_GID] = "COREDUMP_GID=",
- [META_ARGV_SIGNAL] = "COREDUMP_SIGNAL=",
- [META_ARGV_TIMESTAMP] = "COREDUMP_TIMESTAMP=",
- [META_ARGV_RLIMIT] = "COREDUMP_RLIMIT=",
- [META_ARGV_HOSTNAME] = "COREDUMP_HOSTNAME=",
- [META_COMM] = "COREDUMP_COMM=",
- [META_EXE] = "COREDUMP_EXE=",
- [META_UNIT] = "COREDUMP_UNIT=",
+ [META_ARGV_PID] = "COREDUMP_PID=",
+ [META_ARGV_UID] = "COREDUMP_UID=",
+ [META_ARGV_GID] = "COREDUMP_GID=",
+ [META_ARGV_SIGNAL] = "COREDUMP_SIGNAL=",
+ [META_ARGV_TIMESTAMP] = "COREDUMP_TIMESTAMP=",
+ [META_ARGV_RLIMIT] = "COREDUMP_RLIMIT=",
+ [META_ARGV_HOSTNAME] = "COREDUMP_HOSTNAME=",
+ [META_COMM] = "COREDUMP_COMM=",
+ [META_EXE] = "COREDUMP_EXE=",
+ [META_UNIT] = "COREDUMP_UNIT=",
+ [META_PROC_AUXV] = "COREDUMP_PROC_AUXV=",
};
typedef struct Context {
const char *meta[_META_MAX];
+ size_t meta_size[_META_MAX];
pid_t pid;
bool is_pid1;
bool is_journald;
} CoredumpStorage;
static const char* const coredump_storage_table[_COREDUMP_STORAGE_MAX] = {
- [COREDUMP_STORAGE_NONE] = "none",
+ [COREDUMP_STORAGE_NONE] = "none",
[COREDUMP_STORAGE_EXTERNAL] = "external",
- [COREDUMP_STORAGE_JOURNAL] = "journal",
+ [COREDUMP_STORAGE_JOURNAL] = "journal",
};
DEFINE_PRIVATE_STRING_TABLE_LOOKUP(coredump_storage, CoredumpStorage);
static int parse_config(void) {
static const ConfigTableItem items[] = {
- { "Coredump", "Storage", config_parse_coredump_storage, 0, &arg_storage },
- { "Coredump", "Compress", config_parse_bool, 0, &arg_compress },
- { "Coredump", "ProcessSizeMax", config_parse_iec_uint64, 0, &arg_process_size_max },
- { "Coredump", "ExternalSizeMax", config_parse_iec_uint64_infinity, 0, &arg_external_size_max },
- { "Coredump", "JournalSizeMax", config_parse_iec_size, 0, &arg_journal_size_max },
- { "Coredump", "KeepFree", config_parse_iec_uint64, 0, &arg_keep_free },
- { "Coredump", "MaxUse", config_parse_iec_uint64, 0, &arg_max_use },
+ { "Coredump", "Storage", config_parse_coredump_storage, 0, &arg_storage },
+ { "Coredump", "Compress", config_parse_bool, 0, &arg_compress },
+ { "Coredump", "ProcessSizeMax", config_parse_iec_uint64, 0, &arg_process_size_max },
+ { "Coredump", "ExternalSizeMax", config_parse_iec_uint64_infinity, 0, &arg_external_size_max },
+ { "Coredump", "JournalSizeMax", config_parse_iec_size, 0, &arg_journal_size_max },
+ { "Coredump", "KeepFree", config_parse_iec_uint64, 0, &arg_keep_free },
+ { "Coredump", "MaxUse", config_parse_iec_uint64, 0, &arg_max_use },
{}
};
return 0;
}
-static int fix_acl(int fd, uid_t uid) {
+static int fix_acl(int fd, uid_t uid, bool allow_user) {
+ assert(fd >= 0);
+ assert(uid_is_valid(uid));
#if HAVE_ACL
int r;
- assert(fd >= 0);
- assert(uid_is_valid(uid));
+ /* We don't allow users to read coredumps if the uid or capabilities were changed. */
+ if (!allow_user)
+ return 0;
if (uid_is_system(uid) || uid_is_dynamic(uid) || uid == UID_NOBODY)
return 0;
static int fix_xattr(int fd, const Context *context) {
static const char * const xattrs[_META_MAX] = {
- [META_ARGV_PID] = "user.coredump.pid",
- [META_ARGV_UID] = "user.coredump.uid",
- [META_ARGV_GID] = "user.coredump.gid",
- [META_ARGV_SIGNAL] = "user.coredump.signal",
- [META_ARGV_TIMESTAMP] = "user.coredump.timestamp",
- [META_ARGV_RLIMIT] = "user.coredump.rlimit",
- [META_ARGV_HOSTNAME] = "user.coredump.hostname",
- [META_COMM] = "user.coredump.comm",
- [META_EXE] = "user.coredump.exe",
+ [META_ARGV_PID] = "user.coredump.pid",
+ [META_ARGV_UID] = "user.coredump.uid",
+ [META_ARGV_GID] = "user.coredump.gid",
+ [META_ARGV_SIGNAL] = "user.coredump.signal",
+ [META_ARGV_TIMESTAMP] = "user.coredump.timestamp",
+ [META_ARGV_RLIMIT] = "user.coredump.rlimit",
+ [META_ARGV_HOSTNAME] = "user.coredump.hostname",
+ [META_COMM] = "user.coredump.comm",
+ [META_EXE] = "user.coredump.exe",
};
int r = 0;
const char *filename,
const char *target,
const Context *context,
- uid_t uid) {
+ uid_t uid,
+ bool allow_user) {
int r;
/* Ignore errors on these */
(void) fchmod(fd, 0640);
- (void) fix_acl(fd, uid);
+ (void) fix_acl(fd, uid, allow_user);
(void) fix_xattr(fd, context);
r = fsync_full(fd);
return 0;
}
+static int parse_auxv64(
+ const uint64_t *auxv,
+ size_t size_bytes,
+ int *at_secure,
+ uid_t *uid,
+ uid_t *euid,
+ gid_t *gid,
+ gid_t *egid) {
+
+ assert(auxv || size_bytes == 0);
+
+ if (size_bytes % (2 * sizeof(uint64_t)) != 0)
+ return log_warning_errno(SYNTHETIC_ERRNO(EIO), "Incomplete auxv structure (%zu bytes).", size_bytes);
+
+ size_t words = size_bytes / sizeof(uint64_t);
+
+ /* Note that we set output variables even on error. */
+
+ for (size_t i = 0; i + 1 < words; i += 2)
+ switch (auxv[i]) {
+ case AT_SECURE:
+ *at_secure = auxv[i + 1] != 0;
+ break;
+ case AT_UID:
+ *uid = auxv[i + 1];
+ break;
+ case AT_EUID:
+ *euid = auxv[i + 1];
+ break;
+ case AT_GID:
+ *gid = auxv[i + 1];
+ break;
+ case AT_EGID:
+ *egid = auxv[i + 1];
+ break;
+ case AT_NULL:
+ if (auxv[i + 1] != 0)
+ goto error;
+ return 0;
+ }
+ error:
+ return log_warning_errno(SYNTHETIC_ERRNO(ENODATA),
+ "AT_NULL terminator not found, cannot parse auxv structure.");
+}
+
+static int parse_auxv32(
+ const uint32_t *auxv,
+ size_t size_bytes,
+ int *at_secure,
+ uid_t *uid,
+ uid_t *euid,
+ gid_t *gid,
+ gid_t *egid) {
+
+ assert(auxv || size_bytes == 0);
+
+ size_t words = size_bytes / sizeof(uint32_t);
+
+ if (size_bytes % (2 * sizeof(uint32_t)) != 0)
+ return log_warning_errno(SYNTHETIC_ERRNO(EIO), "Incomplete auxv structure (%zu bytes).", size_bytes);
+
+ /* Note that we set output variables even on error. */
+
+ for (size_t i = 0; i + 1 < words; i += 2)
+ switch (auxv[i]) {
+ case AT_SECURE:
+ *at_secure = auxv[i + 1] != 0;
+ break;
+ case AT_UID:
+ *uid = auxv[i + 1];
+ break;
+ case AT_EUID:
+ *euid = auxv[i + 1];
+ break;
+ case AT_GID:
+ *gid = auxv[i + 1];
+ break;
+ case AT_EGID:
+ *egid = auxv[i + 1];
+ break;
+ case AT_NULL:
+ if (auxv[i + 1] != 0)
+ goto error;
+ return 0;
+ }
+ error:
+ return log_warning_errno(SYNTHETIC_ERRNO(ENODATA),
+ "AT_NULL terminator not found, cannot parse auxv structure.");
+}
+
+static int grant_user_access(int core_fd, const Context *context) {
+ int at_secure = -1;
+ uid_t uid = UID_INVALID, euid = UID_INVALID;
+ uid_t gid = GID_INVALID, egid = GID_INVALID;
+ int r;
+
+ assert(core_fd >= 0);
+ assert(context);
+
+ if (!context->meta[META_PROC_AUXV])
+ return log_warning_errno(SYNTHETIC_ERRNO(ENODATA), "No auxv data, not adjusting permissions.");
+
+ uint8_t elf[EI_NIDENT];
+ errno = 0;
+ if (pread(core_fd, &elf, sizeof(elf), 0) != sizeof(elf))
+ return log_warning_errno(errno_or_else(EIO),
+ "Failed to pread from coredump fd: %s", STRERROR_OR_EOF(errno));
+
+ if (elf[EI_MAG0] != ELFMAG0 ||
+ elf[EI_MAG1] != ELFMAG1 ||
+ elf[EI_MAG2] != ELFMAG2 ||
+ elf[EI_MAG3] != ELFMAG3 ||
+ elf[EI_VERSION] != EV_CURRENT)
+ return log_info_errno(SYNTHETIC_ERRNO(EUCLEAN),
+ "Core file does not have ELF header, not adjusting permissions.");
+ if (!IN_SET(elf[EI_CLASS], ELFCLASS32, ELFCLASS64) ||
+ !IN_SET(elf[EI_DATA], ELFDATA2LSB, ELFDATA2MSB))
+ return log_info_errno(SYNTHETIC_ERRNO(EUCLEAN),
+ "Core file has strange ELF class, not adjusting permissions.");
+
+ if ((elf[EI_DATA] == ELFDATA2LSB) != (__BYTE_ORDER == __LITTLE_ENDIAN))
+ return log_info_errno(SYNTHETIC_ERRNO(EUCLEAN),
+ "Core file has non-native endianness, not adjusting permissions.");
+
+ if (elf[EI_CLASS] == ELFCLASS64)
+ r = parse_auxv64((const uint64_t*) context->meta[META_PROC_AUXV],
+ context->meta_size[META_PROC_AUXV],
+ &at_secure, &uid, &euid, &gid, &egid);
+ else
+ r = parse_auxv32((const uint32_t*) context->meta[META_PROC_AUXV],
+ context->meta_size[META_PROC_AUXV],
+ &at_secure, &uid, &euid, &gid, &egid);
+ if (r < 0)
+ return r;
+
+ /* We allow access if we got all the data and at_secure is not set and
+ * the uid/gid matches euid/egid. */
+ bool ret =
+ at_secure == 0 &&
+ uid != UID_INVALID && euid != UID_INVALID && uid == euid &&
+ gid != GID_INVALID && egid != GID_INVALID && gid == egid;
+ log_debug("Will %s access (uid="UID_FMT " euid="UID_FMT " gid="GID_FMT " egid="GID_FMT " at_secure=%s)",
+ ret ? "permit" : "restrict",
+ uid, euid, gid, egid, yes_no(at_secure));
+ return ret;
+}
+
static int save_external_coredump(
const Context *context,
int input_fd,
context->meta[META_ARGV_PID], context->meta[META_COMM]);
truncated = r == 1;
+ bool allow_user = grant_user_access(fd, context) > 0;
+
#if HAVE_COMPRESSION
if (arg_compress) {
_cleanup_(unlink_and_freep) char *tmp_compressed = NULL;
uncompressed_size += partial_uncompressed_size;
}
- r = fix_permissions(fd_compressed, tmp_compressed, fn_compressed, context, uid);
+ r = fix_permissions(fd_compressed, tmp_compressed, fn_compressed, context, uid, allow_user);
if (r < 0)
return r;
"SIZE_LIMIT=%"PRIu64, max_size,
"MESSAGE_ID=" SD_MESSAGE_TRUNCATED_CORE_STR);
- r = fix_permissions(fd, tmp, fn, context, uid);
+ r = fix_permissions(fd, tmp, fn, context, uid, allow_user);
if (r < 0)
return log_error_errno(r, "Failed to fix permissions and finalize coredump %s into %s: %m", coredump_tmpfile_name(tmp), fn);
}
static int submit_coredump(
- Context *context,
+ const Context *context,
struct iovec_wrapper *iovw,
int input_fd) {
struct iovec *iovec = iovw->iovec + n;
for (size_t i = 0; i < ELEMENTSOF(meta_field_names); i++) {
- char *p;
-
/* Note that these strings are NUL terminated, because we made sure that a
* trailing NUL byte is in the buffer, though not included in the iov_len
* count (see process_socket() and gather_pid_metadata_*()) */
assert(((char*) iovec->iov_base)[iovec->iov_len] == 0);
- p = startswith(iovec->iov_base, meta_field_names[i]);
+ const char *p = startswith(iovec->iov_base, meta_field_names[i]);
if (p) {
context->meta[i] = p;
+ context->meta_size[i] = iovec->iov_len - strlen(meta_field_names[i]);
break;
}
}
uid_t owner_uid;
pid_t pid;
char *t;
+ size_t size;
const char *p;
int r;
(void) iovw_put_string_field_free(iovw, "COREDUMP_PROC_LIMITS=", t);
p = procfs_file_alloca(pid, "cgroup");
- if (read_full_virtual_file(p, &t, NULL) >=0)
+ if (read_full_virtual_file(p, &t, NULL) >= 0)
(void) iovw_put_string_field_free(iovw, "COREDUMP_PROC_CGROUP=", t);
p = procfs_file_alloca(pid, "mountinfo");
- if (read_full_virtual_file(p, &t, NULL) >=0)
+ if (read_full_virtual_file(p, &t, NULL) >= 0)
(void) iovw_put_string_field_free(iovw, "COREDUMP_PROC_MOUNTINFO=", t);
+ /* We attach /proc/auxv here. ELF coredumps also contain a note for this (NT_AUXV), see elf(5). */
+ p = procfs_file_alloca(pid, "auxv");
+ if (read_full_virtual_file(p, &t, &size) >= 0) {
+ char *buf = malloc(strlen("COREDUMP_PROC_AUXV=") + size + 1);
+ if (buf) {
+ /* Add a dummy terminator to make save_context() happy. */
+ *((uint8_t*) mempcpy(stpcpy(buf, "COREDUMP_PROC_AUXV="), t, size)) = '\0';
+ (void) iovw_consume(iovw, buf, size + strlen("COREDUMP_PROC_AUXV="));
+ }
+
+ free(t);
+ }
+
if (get_process_cwd(pid, &t) >= 0)
(void) iovw_put_string_field_free(iovw, "COREDUMP_CWD=", t);
/* When we're invoked by the kernel, stdout/stderr are closed which is dangerous because the fds
* could get reallocated. To avoid hard to debug issues, let's instead bind stdout/stderr to
* /dev/null. */
- r = rearrange_stdio(STDIN_FILENO, -1, -1);
+ r = rearrange_stdio(STDIN_FILENO, -EBADF, -EBADF);
if (r < 0)
return log_error_errno(r, "Failed to connect stdout/stderr to /dev/null: %m");
if (r < 0)
return log_error_errno(r, "Failed to read encrypted credential data: %m");
- output_path = (argc < 3 || isempty(argv[2]) || streq(argv[2], "-")) ? NULL : argv[2];
+ output_path = (argc < 3 || empty_or_dash(argv[2])) ? NULL : argv[2];
if (arg_name_any)
name = NULL;
}
static int process_root_account(void) {
- _cleanup_close_ int lock = -1;
+ _cleanup_close_ int lock = -EBADF;
_cleanup_(erase_and_freep) char *_hashed_password = NULL;
const char *password, *hashed_password;
const char *etc_passwd, *etc_shadow;
}
static int run(int argc, char *argv[]) {
- _cleanup_close_pair_ int progress_pipe[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int progress_pipe[2] = PIPE_EBADF;
_cleanup_(sd_device_unrefp) sd_device *dev = NULL;
_cleanup_free_ char *dpath = NULL;
_cleanup_fclose_ FILE *console = NULL;
struct iovec server_iov = IOVEC_MAKE((void*) data, size), client_iov = IOVEC_MAKE((void*) data, size);
/* Important: the declaration order matters here! we want that the fds are closed on return after the
* event sources, hence we declare the fds first, the event sources second */
- _cleanup_close_pair_ int server_pair[2] = { -EBADF, -EBADF }, client_pair[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int server_pair[2] = PIPE_EBADF, client_pair[2] = PIPE_EBADF;
_cleanup_(sd_event_source_unrefp) sd_event_source *idle_event_source = NULL,
*server_event_source = NULL, *client_event_source = NULL;
_cleanup_(varlink_server_unrefp) VarlinkServer *s = NULL;
static const char *arg_dest = NULL;
static bool arg_enabled = true;
static bool arg_root_enabled = true;
+static char *arg_root_fstype = NULL;
+static char *arg_root_options = NULL;
static int arg_root_rw = -1;
+STATIC_DESTRUCTOR_REGISTER(arg_root_fstype, freep);
+STATIC_DESTRUCTOR_REGISTER(arg_root_options, freep);
+
static int add_cryptsetup(
const char *id,
const char *what,
what = crypto_what;
fstype = NULL;
+ } else if (fstype) {
+ r = dissect_fstype_ok(fstype);
+ if (r < 0)
+ return log_error_errno(r, "Unable to determine of dissected file system type '%s' is permitted: %m", fstype);
+ if (!r)
+ return log_error_errno(
+ SYNTHETIC_ERRNO(EIDRM),
+ "Refusing to automatically mount uncommon file system '%s' to '%s'.",
+ fstype, where);
}
r = unit_name_from_path(where, ".mount", &unit);
"root",
"/dev/gpt-auto-root",
in_initrd() ? "/sysroot" : "/",
- NULL,
+ arg_root_fstype,
/* rw= */ arg_root_rw > 0,
/* growfs= */ false,
- NULL,
+ arg_root_options,
"Root Partition",
in_initrd() ? SPECIAL_INITRD_ROOT_FS_TARGET : SPECIAL_LOCAL_FS_TARGET);
#else
arg_root_enabled = false;
+ } else if (streq(key, "rootfstype")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
+ return free_and_strdup_warn(&arg_root_fstype, value);
+
+ } else if (streq(key, "rootflags")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
+ if (!strextend_with_separator(&arg_root_options, ",", value))
+ return log_oom();
+
} else if (proc_cmdline_key_streq(key, "rw") && !value)
arg_root_rw = true;
else if (proc_cmdline_key_streq(key, "ro") && !value)
#include "tmpfile-util.h"
int import_fork_tar_x(const char *path, pid_t *ret) {
- _cleanup_close_pair_ int pipefd[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int pipefd[2] = PIPE_EBADF;
bool use_selinux;
pid_t pid;
int r;
pipefd[1] = safe_close(pipefd[1]);
- r = rearrange_stdio(TAKE_FD(pipefd[0]), -1, STDERR_FILENO);
+ r = rearrange_stdio(TAKE_FD(pipefd[0]), -EBADF, STDERR_FILENO);
if (r < 0) {
log_error_errno(r, "Failed to rearrange stdin/stdout: %m");
_exit(EXIT_FAILURE);
}
int import_fork_tar_c(const char *path, pid_t *ret) {
- _cleanup_close_pair_ int pipefd[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int pipefd[2] = PIPE_EBADF;
bool use_selinux;
pid_t pid;
int r;
pipefd[0] = safe_close(pipefd[0]);
- r = rearrange_stdio(-1, TAKE_FD(pipefd[1]), STDERR_FILENO);
+ r = rearrange_stdio(-EBADF, TAKE_FD(pipefd[1]), STDERR_FILENO);
if (r < 0) {
log_error_errno(r, "Failed to rearrange stdin/stdout: %m");
_exit(EXIT_FAILURE);
}
static int transfer_start(Transfer *t) {
- _cleanup_close_pair_ int pipefd[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int pipefd[2] = PIPE_EBADF;
int r;
assert(t);
const void *payload, size_t payload_size,
const void *signature, size_t signature_size) {
- _cleanup_close_pair_ int gpg_pipe[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int gpg_pipe[2] = PIPE_EBADF;
char sig_file_path[] = "/tmp/sigXXXXXX", gpg_home[] = "/tmp/gpghomeXXXXXX";
_cleanup_(sigkill_waitp) pid_t pid = 0;
bool gpg_home_created = false;
return log_error_errno(errno, "Failed to create pipe for gpg: %m");
if (signature_size > 0) {
- _cleanup_close_ int sig_file = -1;
+ _cleanup_close_ int sig_file = -EBADF;
sig_file = mkostemp(sig_file_path, O_RDWR);
if (sig_file < 0)
gpg_pipe[1] = safe_close(gpg_pipe[1]);
- r = rearrange_stdio(TAKE_FD(gpg_pipe[0]), -1, STDERR_FILENO);
+ r = rearrange_stdio(TAKE_FD(gpg_pipe[0]), -EBADF, STDERR_FILENO);
if (r < 0) {
log_error_errno(r, "Failed to rearrange stdin/stdout: %m");
_exit(EXIT_FAILURE);
}
static int run(int argc, char *argv[]) {
- _cleanup_(server_done) Server server = { .epoll_fd = -1 };
+ _cleanup_(server_done) Server server = { .epoll_fd = -EBADF };
_unused_ _cleanup_(notify_on_cleanup) const char *notify_stop = NULL;
int r, n;
#include "fuzz-journald.h"
#include "journald-stream.h"
-static int stream_fds[2] = { -EBADF, -EBADF };
+static int stream_fds[2] = PIPE_EBADF;
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
Server s;
.ll.sll_halen = ETH_ALEN,
.ll.sll_addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
};
- _cleanup_close_ int s = -1;
+ _cleanup_close_ int s = -EBADF;
int r;
assert(ifindex > 0);
.len = ELEMENTSOF(filter),
.filter = filter
};
- _cleanup_close_ int s = -1;
+ _cleanup_close_ int s = -EBADF;
int r;
s = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
.in.sin_port = htobe16(port),
.in.sin_addr.s_addr = address,
};
- _cleanup_close_ int s = -1;
+ _cleanup_close_ int s = -EBADF;
int r;
s = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
.in6.sin6_port = htobe16(DHCP6_PORT_CLIENT),
.in6.sin6_scope_id = ifindex,
};
- _cleanup_close_ int s = -1;
+ _cleanup_close_ int s = -EBADF;
int r;
assert(ifindex > 0);
#include "fd-util.h"
#include "fuzz.h"
-static int test_dhcp_fd[2] = { -EBADF, -EBADF };
+static int test_dhcp_fd[2] = PIPE_EBADF;
int dhcp6_network_send_udp_socket(int s, struct in6_addr *server_address, const void *packet, size_t len) {
return len;
#include "fuzz.h"
#include "lldp-network.h"
-static int test_fd[2] = { -EBADF, -EBADF };
+static int test_fd[2] = PIPE_EBADF;
int lldp_network_bind_raw_socket(int ifindex) {
if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, test_fd) < 0)
#include <netinet/icmp6.h>
#include <unistd.h>
+#include "sd-ndisc.h"
+
#include "alloc-util.h"
-#include "icmp6-util.h"
+#include "fd-util.h"
#include "fuzz.h"
-#include "sd-ndisc.h"
-#include "socket-util.h"
+#include "icmp6-util.h"
#include "ndisc-internal.h"
+#include "socket-util.h"
-static int test_fd[2] = { -EBADF, -EBADF };
+static int test_fd[2] = PIPE_EBADF;
int icmp6_bind_router_solicitation(int index) {
assert_se(socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, test_fd) >= 0);
static int icmp6_bind_router_message(const struct icmp6_filter *filter,
const struct ipv6_mreq *mreq) {
int ifindex = mreq->ipv6mr_interface;
- _cleanup_close_ int s = -1;
+ _cleanup_close_ int s = -EBADF;
int r;
assert(filter);
static const struct ether_addr mac = {
.ether_addr_octet = { 'A', 'B', 'C', '1', '2', '3' },
};
-static int test_fd[2] = { -EBADF, -EBADF };
+static int test_fd[2] = PIPE_EBADF;
static int test_ifindex = 42;
static unsigned test_client_sent_message_count = 0;
static sd_dhcp6_client *client_ref = NULL;
#define TEST_LLDP_TYPE_SYSTEM_NAME "systemd-lldp"
#define TEST_LLDP_TYPE_SYSTEM_DESC "systemd-lldp-desc"
-static int test_fd[2] = { -EBADF, -EBADF };
+static int test_fd[2] = PIPE_EBADF;
static int lldp_rx_handler_calls;
int lldp_network_bind_raw_socket(int ifindex) {
#include "string-util.h"
int bus_container_connect_socket(sd_bus *b) {
- _cleanup_close_pair_ int pair[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int pair[2] = PIPE_EBADF;
_cleanup_close_ int pidnsfd = -EBADF, mntnsfd = -EBADF, usernsfd = -EBADF, rootfd = -EBADF;
int r, error_buf = 0;
pid_t child;
MODE_CHART,
} mode = MODE_BISECT;
Type type = TYPE_LEGACY;
- int i, pair[2] = { -EBADF, -EBADF };
+ int i, pair[2] = PIPE_EBADF;
_cleanup_free_ char *address = NULL, *server_name = NULL;
- _cleanup_close_ int bus_ref = -1;
+ _cleanup_close_ int bus_ref = -EBADF;
const char *unique;
cpu_set_t cpuset;
size_t result;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
const char *hello;
int r;
- _cleanup_close_pair_ int pp[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int pp[2] = PIPE_EBADF;
char x;
r = sd_bus_open_user(&bus);
}
_public_ int sd_notify_barrier(int unset_environment, uint64_t timeout) {
- _cleanup_close_pair_ int pipe_fd[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int pipe_fd[2] = PIPE_EBADF;
int r;
if (pipe2(pipe_fd, O_CLOEXEC) < 0)
int device_monitor_new_full(sd_device_monitor **ret, MonitorNetlinkGroup group, int fd) {
_cleanup_(sd_device_monitor_unrefp) sd_device_monitor *m = NULL;
- _cleanup_close_ int sock = -1;
+ _cleanup_close_ int sock = -EBADF;
int r;
assert(group >= 0 && group < _MONITOR_NETLINK_GROUP_MAX);
}
if (DEBUG_LOGGING) {
- _cleanup_close_ int netns = -1;
+ _cleanup_close_ int netns = -EBADF;
/* So here's the thing: only AF_NETLINK sockets from the main network namespace will get
* hardware events. Let's check if ours is from there, and if not generate a debug message,
sd_event_inotify_handler_t callback,
void *userdata) {
- _cleanup_close_ int donated_fd = donate ? fd : -1;
+ _cleanup_close_ int donated_fd = donate ? fd : -EBADF;
_cleanup_(source_freep) sd_event_source *s = NULL;
struct inotify_data *inotify_data = NULL;
struct inode_data *inode_data = NULL;
sd_event *e = NULL;
sd_event_source *w = NULL, *x = NULL, *y = NULL, *z = NULL, *q = NULL, *t = NULL;
static const char ch = 'x';
- int a[2] = { -EBADF, -EBADF }, b[2] = { -EBADF, -EBADF },
- d[2] = { -EBADF, -EBADF }, k[2] = { -EBADF, -EBADF };
+ int a[2] = PIPE_EBADF, b[2] = PIPE_EBADF,
+ d[2] = PIPE_EBADF, k[2] = PIPE_EBADF;
uint64_t event_now;
int64_t priority;
}
TEST(ratelimit) {
- _cleanup_close_pair_ int p[2] = {-1, -1};
+ _cleanup_close_pair_ int p[2] = PIPE_EBADF;
_cleanup_(sd_event_unrefp) sd_event *e = NULL;
_cleanup_(sd_event_source_unrefp) sd_event_source *s = NULL;
uint64_t interval;
}
TEST(login) {
- _cleanup_close_pair_ int pair[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int pair[2] = PIPE_EBADF;
_cleanup_free_ char *pp = NULL, *qq = NULL,
*display_session = NULL, *cgroup = NULL,
*display = NULL, *remote_user = NULL, *remote_host = NULL,
void *userdata,
sd_bus_error *error) {
- _cleanup_close_pair_ int errno_pipe_fd[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int errno_pipe_fd[2] = PIPE_EBADF;
Image *image = ASSERT_PTR(userdata);
Manager *m = image->userdata;
pid_t child;
void *userdata,
sd_bus_error *error) {
- _cleanup_close_pair_ int errno_pipe_fd[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int errno_pipe_fd[2] = PIPE_EBADF;
Image *image = ASSERT_PTR(userdata);
Manager *m = ASSERT_PTR(image->userdata);
const char *new_name;
}
case MACHINE_CONTAINER: {
- _cleanup_close_pair_ int pair[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int pair[2] = PIPE_EBADF;
_cleanup_free_ char *us = NULL, *them = NULL;
_cleanup_close_ int netns_fd = -EBADF;
const char *p;
case MACHINE_CONTAINER: {
_cleanup_close_ int mntns_fd = -EBADF, root_fd = -EBADF, pidns_fd = -EBADF;
- _cleanup_close_pair_ int pair[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int pair[2] = PIPE_EBADF;
_cleanup_fclose_ FILE *f = NULL;
pid_t child;
int bus_machine_method_open_pty(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_free_ char *pty_name = NULL;
- _cleanup_close_ int master = -1;
+ _cleanup_close_ int master = -EBADF;
Machine *m = ASSERT_PTR(userdata);
int r;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_free_ char *pty_name = NULL;
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *allocated_bus = NULL;
- _cleanup_close_ int master = -1;
+ _cleanup_close_ int master = -EBADF;
sd_bus *container_bus = NULL;
Machine *m = ASSERT_PTR(userdata);
const char *p, *getty;
_cleanup_free_ char *pty_name = NULL;
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *allocated_bus = NULL;
sd_bus *container_bus = NULL;
- _cleanup_close_ int master = -1, slave = -1;
+ _cleanup_close_ int master = -EBADF, slave = -EBADF;
_cleanup_strv_free_ char **env = NULL, **args_wire = NULL, **args = NULL;
Machine *m = ASSERT_PTR(userdata);
const char *p, *unit, *user, *path, *description, *utmp_id;
int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_free_ char *host_basename = NULL, *container_basename = NULL;
const char *src, *dest, *host_path, *container_path;
- _cleanup_close_pair_ int errno_pipe_fd[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int errno_pipe_fd[2] = PIPE_EBADF;
CopyFlags copy_flags = COPY_REFLINK|COPY_MERGE|COPY_HARDLINKS;
_cleanup_close_ int hostfd = -EBADF;
Machine *m = ASSERT_PTR(userdata);
case MACHINE_CONTAINER: {
_cleanup_close_ int mntns_fd = -EBADF, root_fd = -EBADF;
- _cleanup_close_pair_ int pair[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int pair[2] = PIPE_EBADF;
pid_t child;
r = namespace_open(m->leader, NULL, &mntns_fd, NULL, NULL, &root_fd);
REMOVE_HIDDEN,
} mode;
- _cleanup_close_pair_ int errno_pipe_fd[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int errno_pipe_fd[2] = PIPE_EBADF;
_cleanup_close_ int result_fd = -EBADF;
Manager *m = userdata;
Operation *operation;
pipe_fds[0] = safe_close(pipe_fds[0]);
- if (rearrange_stdio(-1, TAKE_FD(pipe_fds[1]), -1) < 0)
+ if (rearrange_stdio(-EBADF, TAKE_FD(pipe_fds[1]), -EBADF) < 0)
_exit(EXIT_FAILURE);
(void) close_all_fds(NULL, 0);
}
static int setup_stdio_as_dev_console(void) {
- _cleanup_close_ int terminal = -1;
+ _cleanup_close_ int terminal = -EBADF;
int r;
/* We open the TTY in O_NOCTTY mode, so that we do not become controller yet. We'll do that later
}
if (arg_console_mode != CONSOLE_PIPE) {
- _cleanup_close_ int master = -1;
+ _cleanup_close_ int master = -EBADF;
_cleanup_free_ char *console = NULL;
/* Allocate a pty and make it available as /dev/console. */
};
_cleanup_(release_lock_file) LockFile uid_shift_lock = LOCK_FILE_INIT;
- _cleanup_close_ int etc_passwd_lock = -1;
+ _cleanup_close_ int etc_passwd_lock = -EBADF;
_cleanup_close_pair_ int
- fd_inner_socket_pair[2] = { -EBADF, -EBADF },
- fd_outer_socket_pair[2] = { -EBADF, -EBADF };
+ fd_inner_socket_pair[2] = PIPE_EBADF,
+ fd_outer_socket_pair[2] = PIPE_EBADF;
- _cleanup_close_ int notify_socket = -1, mntns_fd = -EBADF, fd_kmsg_fifo = -EBADF;
+ _cleanup_close_ int notify_socket = -EBADF, mntns_fd = -EBADF, fd_kmsg_fifo = -EBADF;
_cleanup_(barrier_destroy) Barrier barrier = BARRIER_NULL;
_cleanup_(sd_event_source_unrefp) sd_event_source *notify_event_source = NULL;
_cleanup_(sd_event_unrefp) sd_event *event = NULL;
static int run(int argc, char *argv[]) {
bool secondary = false, remove_directory = false, remove_image = false,
veth_created = false, remove_tmprootdir = false;
- _cleanup_close_ int master = -1;
+ _cleanup_close_ int master = -EBADF;
_cleanup_fdset_free_ FDSet *fds = NULL;
int r, n_fd_passed, ret = EXIT_SUCCESS;
char veth_name[IFNAMSIZ] = "";
else {
_cleanup_(dissected_image_unrefp) DissectedImage *m = NULL;
_cleanup_(rmdir_and_freep) char *tmpdir = NULL;
- _cleanup_(close_pairp) int seq[2] = { -EBADF, -EBADF };
+ _cleanup_(close_pairp) int seq[2] = PIPE_EBADF;
_cleanup_(sigkill_waitp) pid_t child = 0;
/* We now have a loopback block device, let's fork off a child in its own mount namespace, mount it
Image *image,
sd_bus_error *error) {
- _cleanup_close_pair_ int errno_pipe_fd[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int errno_pipe_fd[2] = PIPE_EBADF;
_cleanup_(sigkill_waitp) pid_t child = 0;
PortableState state;
int r;
l->n_search_domains++;
break;
- case DNS_SERVER_SYSTEM:
+ case DNS_SEARCH_DOMAIN_SYSTEM:
LIST_APPEND(domains, m->search_domains, d);
m->n_search_domains++;
break;
.in.sin_family = AF_INET,
.in.sin_port = htobe16(LLMNR_PORT),
};
- _cleanup_close_ int s = -1;
+ _cleanup_close_ int s = -EBADF;
int r;
assert(m);
.in6.sin6_family = AF_INET6,
.in6.sin6_port = htobe16(LLMNR_PORT),
};
- _cleanup_close_ int s = -1;
+ _cleanup_close_ int s = -EBADF;
int r;
assert(m);
.in.sin_family = AF_INET,
.in.sin_port = htobe16(LLMNR_PORT),
};
- _cleanup_close_ int s = -1;
+ _cleanup_close_ int s = -EBADF;
int r;
assert(m);
.in6.sin6_family = AF_INET6,
.in6.sin6_port = htobe16(LLMNR_PORT),
};
- _cleanup_close_ int s = -1;
+ _cleanup_close_ int s = -EBADF;
int r;
assert(m);
.in.sin_family = AF_INET,
.in.sin_port = htobe16(MDNS_PORT),
};
- _cleanup_close_ int s = -1;
+ _cleanup_close_ int s = -EBADF;
int r;
assert(m);
.in6.sin6_family = AF_INET6,
.in6.sin6_port = htobe16(MDNS_PORT),
};
- _cleanup_close_ int s = -1;
+ _cleanup_close_ int s = -EBADF;
int r;
assert(m);
}
static int run(int argc, char *argv[]) {
- _cleanup_(context_save_and_clear) Context c = { .rfkill_fd = -1 };
+ _cleanup_(context_save_and_clear) Context c = { .rfkill_fd = -EBADF };
bool ready = false;
int r, n;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
_cleanup_free_ char *service = NULL, *pty_path = NULL;
- _cleanup_close_ int master = -1;
+ _cleanup_close_ int master = -EBADF;
int r;
assert(bus);
const char *to,
CopyFlags copy_flags) {
- _cleanup_close_ int dt_copy = -1;
+ _cleanup_close_ int dt_copy = -EBADF;
int r;
assert(c);
#define DATA_FD_TMP_LIMIT (1024U*1024U)
int acquire_data_fd(const void *data, size_t size, unsigned flags) {
- _cleanup_close_pair_ int pipefds[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int pipefds[2] = PIPE_EBADF;
char pattern[] = "/dev/shm/data-fd-XXXXXX";
_cleanup_close_ int fd = -EBADF;
int isz = 0, r;
/* Hmm, pity, this didn't fit. Let's fall back to /tmp then, see below */
} else {
- _cleanup_(close_pairp) int pipefds[2] = { -EBADF, -EBADF };
+ _cleanup_(close_pairp) int pipefds[2] = PIPE_EBADF;
int isz;
/* If memfds aren't available, use a pipe. Set O_NONBLOCK so that we will get EAGAIN rather
/* how many times to wait for the device nodes to appear */
#define N_DEVICE_NODE_LIST_ATTEMPTS 10
+int dissect_fstype_ok(const char *fstype) {
+ const char *e;
+ bool b;
+
+ /* When we automatically mount file systems, be a bit conservative by default what we are willing to
+ * mount, just as an extra safety net to not mount with badly maintained legacy file system
+ * drivers. */
+
+ e = secure_getenv("SYSTEMD_DISSECT_FILE_SYSTEMS");
+ if (e) {
+ _cleanup_strv_free_ char **l = NULL;
+
+ l = strv_split(e, ":");
+ if (!l)
+ return -ENOMEM;
+
+ b = strv_contains(l, fstype);
+ } else
+ b = STR_IN_SET(fstype,
+ "btrfs",
+ "erofs",
+ "ext4",
+ "squashfs",
+ "vfat",
+ "xfs");
+ if (b)
+ return true;
+
+ log_debug("File system type '%s' is not allowed to be mounted as result of automatic dissection.", fstype);
+ return false;
+}
+
int probe_filesystem_full(
int fd,
const char *path,
if (!fstype)
return -EAFNOSUPPORT;
+ r = dissect_fstype_ok(fstype);
+ if (r < 0)
+ return r;
+ if (!r)
+ return -EIDRM; /* Recognizable error */
/* We are looking at an encrypted partition? This either means stacked encryption, or the caller
* didn't call dissected_image_decrypt() beforehand. Let's return a recognizable error for this
* -EUCLEAN → fsck for file system failed
* -EBUSY → File system already mounted/used elsewhere (kernel)
* -EAFNOSUPPORT → File system type not supported or not known
+ * -EIDRM → File system is not among allowlisted "common" file systems
*/
if (!(m->partitions[PARTITION_ROOT].found ||
return log_error_errno(r, "File system already mounted elsewhere.");
if (r == -EAFNOSUPPORT)
return log_error_errno(r, "File system type not supported or not known.");
+ if (r == -EIDRM)
+ return log_error_errno(r, "File system is too uncommon, refused.");
if (r < 0)
return log_error_errno(r, "Failed to mount image: %m");
};
_cleanup_strv_free_ char **machine_info = NULL, **os_release = NULL, **initrd_release = NULL, **extension_release = NULL;
- _cleanup_close_pair_ int error_pipe[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int error_pipe[2] = PIPE_EBADF;
_cleanup_(rmdir_and_freep) char *t = NULL;
_cleanup_(sigkill_waitp) pid_t child = 0;
sd_id128_t machine_id = SD_ID128_NULL;
int mount_image_privately_interactively(const char *path, DissectImageFlags flags, char **ret_directory, LoopDevice **ret_loop_device);
int verity_dissect_and_mount(int src_fd, const char *src, const char *dest, const MountOptions *options, const char *required_host_os_release_id, const char *required_host_os_release_version_id, const char *required_host_os_release_sysext_level, const char *required_sysext_scope);
+
+int dissect_fstype_ok(const char *fstype);
}
int parse_elf_object(int fd, const char *executable, bool fork_disable_dump, char **ret, JsonVariant **ret_package_metadata) {
- _cleanup_close_pair_ int error_pipe[2] = { -EBADF, -EBADF },
- return_pipe[2] = { -EBADF, -EBADF },
- json_pipe[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int error_pipe[2] = PIPE_EBADF,
+ return_pipe[2] = PIPE_EBADF,
+ json_pipe[2] = PIPE_EBADF;
_cleanup_(json_variant_unrefp) JsonVariant *package_metadata = NULL;
_cleanup_free_ char *buf = NULL;
int r;
}
static int get_boot_id_for_machine(const char *machine, sd_id128_t *boot_id) {
- _cleanup_close_pair_ int pair[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int pair[2] = PIPE_EBADF;
_cleanup_close_ int pidnsfd = -EBADF, mntnsfd = -EBADF, rootfd = -EBADF;
char buf[SD_ID128_UUID_STRING_MAX];
pid_t pid, child;
}
static LoopDevice* loop_device_free(LoopDevice *d) {
- _cleanup_close_ int control = -1;
+ _cleanup_close_ int control = -EBADF;
int r;
if (!d)
const MountOptions *options,
bool is_image) {
- _cleanup_close_pair_ int errno_pipe_fd[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int errno_pipe_fd[2] = PIPE_EBADF;
_cleanup_close_ int mntns_fd = -EBADF, root_fd = -EBADF, pidns_fd = -EBADF, chased_src_fd = -EBADF;
char mount_slave[] = "/tmp/propagate.XXXXXX", *mount_tmp, *mount_outside, *p;
bool mount_slave_created = false, mount_slave_mounted = false,
}
void pager_open(PagerFlags flags) {
- _cleanup_close_pair_ int fd[2] = { -EBADF, -EBADF }, exe_name_pipe[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int fd[2] = PIPE_EBADF, exe_name_pipe[2] = PIPE_EBADF;
_cleanup_strv_free_ char **pager_args = NULL;
_cleanup_free_ char *l = NULL;
const char *pager, *less_opts;
.context = context,
.server_fd = fd,
.client_fd = -EBADF,
- .server_to_client_buffer = { -EBADF, -EBADF },
- .client_to_server_buffer = { -EBADF, -EBADF },
+ .server_to_client_buffer = PIPE_EBADF,
+ .client_to_server_buffer = PIPE_EBADF,
};
r = set_ensure_put(&context->connections, NULL, c);
_cleanup_(hashmap_freep) Hashmap *cached_name_map = NULL, *cached_id_map = NULL;
_cleanup_(edit_file_free_all) EditFile *edit_files = NULL;
_cleanup_(lookup_paths_free) LookupPaths lp = {};
+ _cleanup_free_ char *drop_in_alloc = NULL, *suffix = NULL;
+ const char *drop_in;
size_t n_edit_files = 0;
int r;
assert(names);
assert(ret_edit_files);
+ if (isempty(arg_drop_in))
+ drop_in = "override.conf";
+ else if (!endswith(arg_drop_in, ".conf")) {
+ drop_in_alloc = strjoin(arg_drop_in, ".conf");
+ if (!drop_in_alloc)
+ return log_oom();
+
+ drop_in = drop_in_alloc;
+ } else
+ drop_in = arg_drop_in;
+
+ if (!filename_is_valid(drop_in))
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid drop-in file name '%s'.", drop_in);
+
+ suffix = strjoin(".d/", drop_in);
+ if (!suffix)
+ return log_oom();
+
r = lookup_paths_init(&lp, arg_scope, 0, arg_root);
if (r < 0)
return r;
r = unit_file_create_new(
&lp,
*name,
- arg_full ? NULL : ".d/override.conf",
+ arg_full ? NULL : suffix,
NULL,
edit_files + n_edit_files);
} else {
r = unit_file_create_new(
&lp,
unit_name,
- ".d/override.conf",
+ suffix,
unit_paths,
edit_files + n_edit_files);
}
mode = "isolate";
suffix = ".target";
} else if (!arg_marked) {
- /* A command in style of "systemctl start <unit1> <unit2> …", "sysemctl stop <unit1> <unit2> …" and so on */
+ /* A command in style of "systemctl start <unit1> <unit2> …", "systemctl stop <unit1> <unit2> …" and so on */
method = verb_to_method(argv[0]);
job_type = verb_to_job_type(argv[0]);
mode = arg_job_mode();
bool arg_read_only = false;
bool arg_mkdir = false;
bool arg_marked = false;
+const char *arg_drop_in = NULL;
STATIC_DESTRUCTOR_REGISTER(arg_types, strv_freep);
STATIC_DESTRUCTOR_REGISTER(arg_states, strv_freep);
STATIC_DESTRUCTOR_REGISTER(arg_host, unsetp);
STATIC_DESTRUCTOR_REGISTER(arg_boot_loader_entry, unsetp);
STATIC_DESTRUCTOR_REGISTER(arg_clean_what, strv_freep);
+STATIC_DESTRUCTOR_REGISTER(arg_drop_in, unsetp);
static int systemctl_help(void) {
_cleanup_free_ char *link = NULL;
" --read-only Create read-only bind mount\n"
" --mkdir Create directory before mounting, if missing\n"
" --marked Restart/reload previously marked units\n"
+ " --drop-in=NAME Edit unit files using the specified drop-in file name\n"
"\nSee the %2$s for details.\n",
program_invocation_short_name,
link,
ARG_MKDIR,
ARG_MARKED,
ARG_NO_WARN,
+ ARG_DROP_IN,
};
static const struct option options[] = {
{ "read-only", no_argument, NULL, ARG_READ_ONLY },
{ "mkdir", no_argument, NULL, ARG_MKDIR },
{ "marked", no_argument, NULL, ARG_MARKED },
+ { "drop-in", required_argument, NULL, ARG_DROP_IN },
{}
};
arg_no_warn = true;
break;
+ case ARG_DROP_IN:
+ arg_drop_in = optarg;
+ break;
+
case '.':
/* Output an error mimicking getopt, and print a hint afterwards */
log_error("%s: invalid option -- '.'", program_invocation_name);
extern bool arg_read_only;
extern bool arg_mkdir;
extern bool arg_marked;
+extern const char *arg_drop_in;
static inline const char* arg_job_mode(void) {
return _arg_job_mode ?: "replace";
size_t *ret_size) {
_cleanup_free_ char *buffer = NULL, *suffixed_url = NULL;
- _cleanup_(close_pairp) int pfd[2] = { -EBADF, -EBADF };
+ _cleanup_(close_pairp) int pfd[2] = PIPE_EBADF;
_cleanup_fclose_ FILE *manifest = NULL;
size_t size = 0;
pid_t pid;
pfd[0] = safe_close(pfd[0]);
- r = rearrange_stdio(-1, pfd[1], STDERR_FILENO);
+ r = rearrange_stdio(-EBADF, pfd[1], STDERR_FILENO);
if (r < 0) {
log_error_errno(r, "Failed to rearrange stdin/stdout: %m");
_exit(EXIT_FAILURE);
static int make_backup(const char *target, const char *x) {
_cleanup_(unlink_and_freep) char *dst_tmp = NULL;
_cleanup_fclose_ FILE *dst = NULL;
- _cleanup_close_ int src = -1;
+ _cleanup_close_ int src = -EBADF;
const char *backup;
struct stat st;
int r;
_cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
_cleanup_(umount_and_rmdir_and_freep) char *unlink_dir = NULL;
#endif
- _cleanup_close_ int lock = -1;
+ _cleanup_close_ int lock = -EBADF;
Item *i;
int r;
decompress_stream_t decompress,
const char *srcfile) {
- _cleanup_close_ int src = -1, dst = -1, dst2 = -1;
+ _cleanup_close_ int src = -EBADF, dst = -EBADF, dst2 = -EBADF;
_cleanup_(unlink_tempfilep) char
pattern[] = "/tmp/systemd-test.compressed.XXXXXX",
pattern2[] = "/tmp/systemd-test.compressed.XXXXXX";
TEST(copy_tree_replace_dirs) {
_cleanup_(rm_rf_physical_and_freep) char *srcp = NULL, *dstp = NULL;
- _cleanup_close_ int src = -1, dst = -1;
+ _cleanup_close_ int src = -EBADF, dst = -EBADF;
/* Create the random source/destination directories */
assert_se((src = mkdtemp_open(NULL, 0, &srcp)) >= 0);
}
TEST(copy_bytes) {
- _cleanup_close_pair_ int pipefd[2] = {-1, -1};
+ _cleanup_close_pair_ int pipefd[2] = PIPE_EBADF;
_cleanup_close_ int infd = -EBADF;
int r, r2;
char buf[1024], buf2[1024];
TEST(copy_data_fd) {
_cleanup_close_ int fd1 = -EBADF, fd2 = -EBADF;
- _cleanup_(close_pairp) int sfd[2] = { -EBADF, -EBADF };
+ _cleanup_(close_pairp) int sfd[2] = PIPE_EBADF;
_cleanup_(sigkill_waitp) pid_t pid = -1;
int r;
_cleanup_(sd_event_source_unrefp) sd_event_source *sigchld_source = NULL;
_cleanup_(sd_event_source_unrefp) sd_event_source *stdout_source = NULL;
_cleanup_(sd_event_source_unrefp) sd_event_source *stderr_source = NULL;
- _cleanup_close_pair_ int outpipe[2] = {-1, -1}, errpipe[2] = {-1, -1};
+ _cleanup_close_pair_ int outpipe[2] = PIPE_EBADF, errpipe[2] = PIPE_EBADF;
_cleanup_strv_free_ char **libraries = NULL;
_cleanup_free_ char *result = NULL;
pid_t pid;
r = safe_fork("(spawn-ldd)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid);
assert_se(r >= 0);
if (r == 0) {
- if (rearrange_stdio(-1, TAKE_FD(outpipe[1]), TAKE_FD(errpipe[1])) < 0)
+ if (rearrange_stdio(-EBADF, TAKE_FD(outpipe[1]), TAKE_FD(errpipe[1])) < 0)
_exit(EXIT_FAILURE);
(void) close_all_fds(NULL, 0);
safe_close(STDERR_FILENO); /* Let's close an fd < 2, to make it more interesting */
- assert_se(rearrange_stdio(-1, -1, -1) >= 0);
+ assert_se(rearrange_stdio(-EBADF, -EBADF, -EBADF) >= 0);
assert_se(fd_get_path(STDIN_FILENO, &path) >= 0);
assert_se(path_equal(path, "/dev/null"));
assert_se(read(0, buffer, sizeof(buffer)) == 6);
assert_se(memcmp(buffer, "foobar", 6) == 0);
- assert_se(rearrange_stdio(-1, 1, 2) >= 0);
+ assert_se(rearrange_stdio(-EBADF, 1, 2) >= 0);
assert_se(write(1, "a", 1) < 0 && errno == ENOSPC);
assert_se(write(2, "y", 1) == 1);
assert_se(read(3, buffer, sizeof(buffer)) == 1);
TEST(take_fd) {
_cleanup_close_ int fd1 = -EBADF, fd2 = -EBADF;
- int array[2] = { -EBADF, -EBADF }, i = 0;
+ int array[2] = PIPE_EBADF, i = 0;
assert_se(fd1 == -EBADF);
assert_se(fd2 == -EBADF);
TEST(read_full_file_socket) {
_cleanup_(rm_rf_physical_and_freep) char *z = NULL;
- _cleanup_close_ int listener = -1;
+ _cleanup_close_ int listener = -EBADF;
_cleanup_free_ char *data = NULL, *clientname = NULL;
union sockaddr_union sa;
const char *j, *jj;
}
static void test_shareable_ns(unsigned long nsflag) {
- _cleanup_close_pair_ int s[2] = { -EBADF, -EBADF };
+ _cleanup_close_pair_ int s[2] = PIPE_EBADF;
pid_t pid1, pid2, pid3;
int r, n = 0;
siginfo_t si;
TEST(getttyname_malloc) {
_cleanup_free_ char *ttyname = NULL;
- _cleanup_close_ int master = -1;
+ _cleanup_close_ int master = -EBADF;
assert_se((master = posix_openpt(O_RDWR|O_NOCTTY)) >= 0);
assert_se(getttyname_malloc(master, &ttyname) >= 0);
_cleanup_(rm_rf_physical_and_freep) char *tmpdir = NULL;
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
_cleanup_(sd_event_unrefp) sd_event *e = NULL;
- _cleanup_(close_pairp) int block_fds[2] = { -EBADF, -EBADF };
+ _cleanup_(close_pairp) int block_fds[2] = PIPE_EBADF;
pthread_t t;
const char *sp;
.connection_retry_usec = DEFAULT_CONNECTION_RETRY_USEC,
- .server_socket = -1,
+ .server_socket = -EBADF,
.ratelimit = (const RateLimit) {
RATELIMIT_INTERVAL_USEC,
};
_unused_ _cleanup_close_ int tty_block_fd = -EBADF;
- _cleanup_close_ int notify = -1, signal_fd = -EBADF;
+ _cleanup_close_ int notify = -EBADF, signal_fd = -EBADF;
struct pollfd pollfd[_FD_MAX];
sigset_t mask;
int r;
};
int udev_ctrl_new_from_fd(UdevCtrl **ret, int fd) {
- _cleanup_close_ int sock = -1;
+ _cleanup_close_ int sock = -EBADF;
UdevCtrl *uctrl;
assert(ret);
*uctrl = (UdevCtrl) {
.n_ref = 1,
.sock = fd >= 0 ? fd : TAKE_FD(sock),
- .sock_connect = -1,
+ .sock_connect = -EBADF,
.bound = fd >= 0,
};
static int udev_ctrl_event_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
UdevCtrl *uctrl = ASSERT_PTR(userdata);
- _cleanup_close_ int sock = -1;
+ _cleanup_close_ int sock = -EBADF;
struct ucred ucred;
int r;
size_t ressize,
bool *ret_truncated) {
- _cleanup_close_pair_ int outpipe[2] = {-1, -1}, errpipe[2] = {-1, -1};
+ _cleanup_close_pair_ int outpipe[2] = PIPE_EBADF, errpipe[2] = PIPE_EBADF;
_cleanup_strv_free_ char **argv = NULL;
char **envp = NULL;
Spawn spawn;
return log_device_error_errno(event->dev, r,
"Failed to fork() to execute command '%s': %m", cmd);
if (r == 0) {
- if (rearrange_stdio(-1, TAKE_FD(outpipe[WRITE_END]), TAKE_FD(errpipe[WRITE_END])) < 0)
+ if (rearrange_stdio(-EBADF, TAKE_FD(outpipe[WRITE_END]), TAKE_FD(errpipe[WRITE_END])) < 0)
_exit(EXIT_FAILURE);
(void) close_all_fds(NULL, 0);
*manager = (Manager) {
.inotify_fd = -EBADF,
- .worker_watch = { -EBADF, -EBADF },
+ .worker_watch = PIPE_EBADF,
.cgroup = TAKE_PTR(cgroup),
};