1
0
mirror of https://github.com/systemd/systemd synced 2025-09-22 21:34:46 +02:00

Compare commits

...

21 Commits

Author SHA1 Message Date
Lennart Poettering
2b8c2fbb2d
Merge pull request #15765 from benjarobin/fix_kw
Various bug fixes
2020-05-14 09:08:47 +02:00
Lennart Poettering
3250501865
Merge pull request #15660 from benjarobin/perf_barrier_fd
Faster manager_process_barrier_fd and drop message if BARRIER=1 found
2020-05-14 09:07:41 +02:00
Lennart Poettering
de07add2c9
Merge pull request #15801 from poettering/journal-pid-change-fix
journald: stream pid change newline fix
2020-05-14 09:04:23 +02:00
Christian Göttsche
9bf4984a2a selinux: add parenthesis to function names in log messages 2020-05-14 09:03:51 +02:00
Evgeny Vereshchagin
5141b4e3b6 ci: install fdisk on Debian
To judge from https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=947134 and
44ec91ef11,
`util-linux` no longer depends on `fdisk` so it seems it should be installed
manually.
2020-05-14 04:24:49 +03:00
Benjamin Robin
243945e95e test: Add return 0 to main() function (even it is not strictly necessary) 2020-05-13 22:56:42 +02:00
Benjamin Robin
fbb0b66577 systemctl: Check clean_or_freeze_unit(): Add assert if unknown method 2020-05-13 22:56:42 +02:00
Benjamin Robin
81c5a5961f network: 'cur' variable cannot be null, so simplify code 2020-05-13 22:56:42 +02:00
Benjamin Robin
b9c54c4665 tree-wide: Initialize _cleanup_ variables if needed 2020-05-13 22:56:42 +02:00
Benjamin Robin
179b4db439 netlink: Fix assert condition on n_containers 2020-05-13 22:56:42 +02:00
Benjamin Robin
5151b4ccd2 core: Parse the tags list sooner, and use it for multiple function
- Parse the tags list using strv_split_newlines() which remove any
   unnecessary empty string at the end of the strv.
 - Use this parsed list for manager_process_barrier_fd() and every call
   to manager_invoke_notify_message().
 - This also allow to simplify the manager_process_barrier_fd() function.
2020-05-13 22:44:12 +02:00
Lennart Poettering
a3d9aee14f man: document the new _LINE_BREAK= type 2020-05-13 21:32:49 +02:00
Benjamin Robin
d38b3b74db test: Stricter test case for #15654 (Add more checks)
Check:
 - There is only 3 messages logged with type stdout
 - Check all messages logged does not have new line: LINE_BREAK=eof
 - Check that the 3 messages are logged from a different PID
 - Check the 3 MESSAGE= content
2020-05-13 21:32:45 +02:00
Benjamin Robin
c11d8fd1da test: Add a test case for #15654 2020-05-13 21:32:42 +02:00
Lennart Poettering
45ba1ea5e9 journald: rework pid change handling
Let's introduce an explicit line ending marker for line endings due to
pid change.

Let's also make sure we don't get confused with buffer management.

Fixes: #15654
2020-05-13 21:32:38 +02:00
Lennart Poettering
020b4a023c journald: use the fact that client_context_release() returns NULL 2020-05-13 21:32:34 +02:00
Lennart Poettering
549b7379ba journald: rework end of line marker handling to use a field table 2020-05-13 21:32:30 +02:00
Lennart Poettering
5fe7fb0bf6 journald: use log_warning_errno() where appropriate 2020-05-13 21:32:25 +02:00
Benjamin Robin
034e9719ac journald: Increase stdout buffer size sooner, when almost full
If the previous received buffer length is almost equal to the allocated
buffer size, before this change the next read can only receive a couple
of bytes (in the worst case only 1 byte), which is not efficient.
2020-05-13 21:31:58 +02:00
Benjamin Robin
fcee2755ec core: Update prototype of notify_message, tags list is read only
Indicates that the tags list cannot be modified by notify_message function.
Since the tags list is created only once for multiple call to
notify_message functions.
2020-05-10 18:58:03 +02:00
Benjamin Robin
147d8fc1a7 basic: Allow to call STRV_FOREACH_BACKWARDS() with a char * const * strv 2020-05-10 18:57:56 +02:00
23 changed files with 178 additions and 114 deletions

View File

@ -347,15 +347,16 @@
<varlistentry>
<term><varname>_LINE_BREAK=</varname></term>
<listitem>
<para>Only applies to <literal>_TRANSPORT=stdout</literal> records: indicates that the log message in the
standard output/error stream was not terminated with a normal newline character (<literal>\n</literal>,
i.e. ASCII 10). Specifically, when set this field is one of <option>nul</option> (in case the line was
terminated by a NUL byte), <option>line-max</option> (in case the maximum log line length was reached, as
configured with <varname>LineMax=</varname> in
<citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>) or
<option>eof</option> (if this was the last log record of a stream and the stream ended without a final
newline character). Note that this record is not generated when a normal newline character was used for
marking the log line end.</para>
<para>Only applies to <literal>_TRANSPORT=stdout</literal> records: indicates that the log message
in the standard output/error stream was not terminated with a normal newline character
(<literal>\n</literal>, i.e. ASCII 10). Specifically, when set this field is one of
<option>nul</option> (in case the line was terminated by a NUL byte), <option>line-max</option> (in
case the maximum log line length was reached, as configured with <varname>LineMax=</varname> in
<citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>),
<option>eof</option> (if this was the last log record of a stream and the stream ended without a
final newline character), or <option>pid-change</option> (if the process which generated the log
output changed in the middle of a line). Note that this record is not generated when a normal
newline character was used for marking the log line end.</para>
</listitem>
</varlistentry>
<varlistentry>

View File

@ -36,7 +36,7 @@ apt-get -q --allow-releaseinfo-change update
apt-get -y dist-upgrade
apt-get install -y eatmydata
# The following four are needed as long as these deps are not covered by Debian's own packaging
apt-get install -y libfdisk-dev libp11-kit-dev libssl-dev libpwquality-dev
apt-get install -y fdisk libfdisk-dev libp11-kit-dev libssl-dev libpwquality-dev
apt-get purge --auto-remove -y unattended-upgrades
systemctl unmask systemd-networkd
systemctl enable systemd-networkd

View File

@ -106,7 +106,7 @@ bool strv_overlap(char * const *a, char * const *b) _pure_;
#define STRV_FOREACH_BACKWARDS(s, l) \
for (s = ({ \
char **_l = l; \
typeof(l) _l = l; \
_l ? _l + strv_length(_l) - 1U : NULL; \
}); \
(l) && ((s) >= (l)); \

View File

@ -2288,16 +2288,19 @@ static int manager_dispatch_cgroups_agent_fd(sd_event_source *source, int fd, ui
return 0;
}
static bool manager_process_barrier_fd(const char *buf, FDSet *fds) {
assert(buf);
static bool manager_process_barrier_fd(char * const *tags, FDSet *fds) {
/* nothing else must be sent when using BARRIER=1 */
if (STR_IN_SET(buf, "BARRIER=1", "BARRIER=1\n")) {
if (fdset_size(fds) != 1)
log_warning("Got incorrect number of fds with BARRIER=1, closing them.");
if (strv_contains(tags, "BARRIER=1")) {
if (strv_length(tags) == 1) {
if (fdset_size(fds) != 1)
log_warning("Got incorrect number of fds with BARRIER=1, closing them.");
} else
log_warning("Extra notification messages sent with BARRIER=1, ignoring everything.");
/* Drop the message if BARRIER=1 was found */
return true;
} else if (startswith(buf, "BARRIER=1\n") || strstr(buf, "\nBARRIER=1\n") || endswith(buf, "\nBARRIER=1"))
log_warning("Extra notification messages sent with BARRIER=1, ignoring everything.");
}
return false;
}
@ -2306,33 +2309,27 @@ static void manager_invoke_notify_message(
Manager *m,
Unit *u,
const struct ucred *ucred,
const char *buf,
char * const *tags,
FDSet *fds) {
assert(m);
assert(u);
assert(ucred);
assert(buf);
assert(tags);
if (u->notifygen == m->notifygen) /* Already invoked on this same unit in this same iteration? */
return;
u->notifygen = m->notifygen;
if (UNIT_VTABLE(u)->notify_message) {
_cleanup_strv_free_ char **tags = NULL;
tags = strv_split(buf, NEWLINE);
if (!tags) {
log_oom();
return;
}
if (UNIT_VTABLE(u)->notify_message)
UNIT_VTABLE(u)->notify_message(u, ucred, tags, fds);
} else if (DEBUG_LOGGING) {
_cleanup_free_ char *x = NULL, *y = NULL;
else if (DEBUG_LOGGING) {
_cleanup_free_ char *buf = NULL, *x = NULL, *y = NULL;
x = ellipsize(buf, 20, 90);
buf = strv_join(tags, ", ");
if (buf)
x = ellipsize(buf, 20, 90);
if (x)
y = cescape(x);
@ -2361,6 +2358,7 @@ static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t
struct cmsghdr *cmsg;
struct ucred *ucred = NULL;
_cleanup_free_ Unit **array_copy = NULL;
_cleanup_strv_free_ char **tags = NULL;
Unit *u1, *u2, **array;
int r, *fd_array = NULL;
size_t n_fds = 0;
@ -2429,11 +2427,16 @@ static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t
return 0;
}
/* Make sure it's NUL-terminated. */
/* Make sure it's NUL-terminated, then parse it to obtain the tags list */
buf[n] = 0;
tags = strv_split_newlines(buf);
if (!tags) {
log_oom();
return 0;
}
/* possibly a barrier fd, let's see */
if (manager_process_barrier_fd(buf, fds))
if (manager_process_barrier_fd(tags, fds))
return 0;
/* Increase the generation counter used for filtering out duplicate unit invocations. */
@ -2456,16 +2459,16 @@ static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t
/* And now invoke the per-unit callbacks. Note that manager_invoke_notify_message() will handle duplicate units
* make sure we only invoke each unit's handler once. */
if (u1) {
manager_invoke_notify_message(m, u1, ucred, buf, fds);
manager_invoke_notify_message(m, u1, ucred, tags, fds);
found = true;
}
if (u2) {
manager_invoke_notify_message(m, u2, ucred, buf, fds);
manager_invoke_notify_message(m, u2, ucred, tags, fds);
found = true;
}
if (array_copy)
for (size_t i = 0; array_copy[i]; i++) {
manager_invoke_notify_message(m, array_copy[i], ucred, buf, fds);
manager_invoke_notify_message(m, array_copy[i], ucred, tags, fds);
found = true;
}

View File

@ -227,7 +227,7 @@ int mac_selinux_generic_access_check(
if (getfilecon_raw(path, &fcon) < 0) {
r = -errno;
log_warning_errno(r, "SELinux getfilecon_raw on '%s' failed%s (perm=%s): %m",
log_warning_errno(r, "SELinux getfilecon_raw() on '%s' failed%s (perm=%s): %m",
path,
enforce ? "" : ", ignoring",
permission);
@ -243,7 +243,7 @@ int mac_selinux_generic_access_check(
if (getcon_raw(&fcon) < 0) {
r = -errno;
log_warning_errno(r, "SELinux getcon_raw failed%s (perm=%s): %m",
log_warning_errno(r, "SELinux getcon_raw() failed%s (perm=%s): %m",
enforce ? "" : ", ignoring",
permission);
if (!enforce)

View File

@ -3847,7 +3847,7 @@ static int service_dispatch_watchdog(sd_event_source *source, usec_t usec, void
return 0;
}
static bool service_notify_message_authorized(Service *s, pid_t pid, char **tags, FDSet *fds) {
static bool service_notify_message_authorized(Service *s, pid_t pid, FDSet *fds) {
assert(s);
if (s->notify_access == NOTIFY_NONE) {
@ -3894,19 +3894,19 @@ static void service_force_watchdog(Service *s) {
static void service_notify_message(
Unit *u,
const struct ucred *ucred,
char **tags,
char * const *tags,
FDSet *fds) {
Service *s = SERVICE(u);
bool notify_dbus = false;
const char *e;
char **i;
char * const *i;
int r;
assert(u);
assert(ucred);
if (!service_notify_message_authorized(SERVICE(u), ucred->pid, tags, fds))
if (!service_notify_message_authorized(SERVICE(u), ucred->pid, fds))
return;
if (DEBUG_LOGGING) {

View File

@ -539,7 +539,7 @@ typedef struct UnitVTable {
void (*notify_cgroup_oom)(Unit *u);
/* Called whenever a process of this unit sends us a message */
void (*notify_message)(Unit *u, const struct ucred *ucred, char **tags, FDSet *fds);
void (*notify_message)(Unit *u, const struct ucred *ucred, char * const *tags, FDSet *fds);
/* Called whenever a name this Unit registered for comes or goes away. */
void (*bus_name_owner_change)(Unit *u, const char *new_owner);

View File

@ -58,6 +58,9 @@ typedef enum LineBreak {
LINE_BREAK_NUL,
LINE_BREAK_LINE_MAX,
LINE_BREAK_EOF,
LINE_BREAK_PID_CHANGE,
_LINE_BREAK_MAX,
_LINE_BREAK_INVALID = -1,
} LineBreak;
struct StdoutStream {
@ -238,7 +241,11 @@ fail:
return log_error_errno(r, "Failed to save stream data %s: %m", s->state_file);
}
static int stdout_stream_log(StdoutStream *s, const char *p, LineBreak line_break) {
static int stdout_stream_log(
StdoutStream *s,
const char *p,
LineBreak line_break) {
struct iovec *iovec;
int priority;
char syslog_priority[] = "PRIORITY=\0";
@ -250,6 +257,9 @@ static int stdout_stream_log(StdoutStream *s, const char *p, LineBreak line_brea
assert(s);
assert(p);
assert(line_break >= 0);
assert(line_break < _LINE_BREAK_MAX);
if (s->context)
(void) client_context_maybe_refresh(s->server, s->context, NULL, NULL, 0, NULL, USEC_INFINITY);
else if (pid_is_valid(s->ucred.pid)) {
@ -301,17 +311,20 @@ static int stdout_stream_log(StdoutStream *s, const char *p, LineBreak line_brea
iovec[n++] = IOVEC_MAKE_STRING(syslog_identifier);
}
if (line_break != LINE_BREAK_NEWLINE) {
const char *c;
static const char * const line_break_field_table[_LINE_BREAK_MAX] = {
[LINE_BREAK_NEWLINE] = NULL, /* Do not add field if traditional newline */
[LINE_BREAK_NUL] = "_LINE_BREAK=nul",
[LINE_BREAK_LINE_MAX] = "_LINE_BREAK=line-max",
[LINE_BREAK_EOF] = "_LINE_BREAK=eof",
[LINE_BREAK_PID_CHANGE] = "_LINE_BREAK=pid-change",
};
/* If this log message was generated due to an uncommon line break then mention this in the log
* entry */
const char *c = line_break_field_table[line_break];
c = line_break == LINE_BREAK_NUL ? "_LINE_BREAK=nul" :
line_break == LINE_BREAK_LINE_MAX ? "_LINE_BREAK=line-max" :
"_LINE_BREAK=eof";
/* If this log message was generated due to an uncommon line break then mention this in the log
* entry */
if (c)
iovec[n++] = IOVEC_MAKE_STRING(c);
}
message = strjoin("MESSAGE=", p);
if (message)
@ -322,8 +335,8 @@ static int stdout_stream_log(StdoutStream *s, const char *p, LineBreak line_brea
}
static int stdout_stream_line(StdoutStream *s, char *p, LineBreak line_break) {
int r;
char *orig;
int r;
assert(s);
assert(p);
@ -332,10 +345,9 @@ static int stdout_stream_line(StdoutStream *s, char *p, LineBreak line_break) {
p = strstrip(p);
/* line breaks by NUL, line max length or EOF are not permissible during the negotiation part of the protocol */
if (line_break != LINE_BREAK_NEWLINE && s->state != STDOUT_STREAM_RUNNING) {
log_warning("Control protocol line not properly terminated.");
return -EINVAL;
}
if (line_break != LINE_BREAK_NEWLINE && s->state != STDOUT_STREAM_RUNNING)
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
"Control protocol line not properly terminated.");
switch (s->state) {
@ -425,21 +437,43 @@ static int stdout_stream_line(StdoutStream *s, char *p, LineBreak line_break) {
assert_not_reached("Unknown stream state");
}
static int stdout_stream_scan(StdoutStream *s, bool force_flush) {
char *p;
size_t remaining;
static int stdout_stream_found(
StdoutStream *s,
char *p,
size_t l,
LineBreak line_break) {
char saved;
int r;
assert(s);
assert(p);
p = s->buffer;
remaining = s->length;
/* Let's NUL terminate the specified buffer for this call, and revert back afterwards */
saved = p[l];
p[l] = 0;
r = stdout_stream_line(s, p, line_break);
p[l] = saved;
/* XXX: This function does nothing if (s->length == 0) */
return r;
}
static int stdout_stream_scan(
StdoutStream *s,
char *p,
size_t remaining,
LineBreak force_flush,
size_t *ret_consumed) {
size_t consumed = 0;
int r;
assert(s);
assert(p);
for (;;) {
LineBreak line_break;
size_t skip;
size_t skip, found;
char *end1, *end2;
end1 = memchr(p, '\n', remaining);
@ -447,43 +481,40 @@ static int stdout_stream_scan(StdoutStream *s, bool force_flush) {
if (end2) {
/* We found a NUL terminator */
skip = end2 - p + 1;
found = end2 - p;
skip = found + 1;
line_break = LINE_BREAK_NUL;
} else if (end1) {
/* We found a \n terminator */
*end1 = 0;
skip = end1 - p + 1;
found = end1 - p;
skip = found + 1;
line_break = LINE_BREAK_NEWLINE;
} else if (remaining >= s->server->line_max) {
/* Force a line break after the maximum line length */
*(p + s->server->line_max) = 0;
skip = remaining;
found = skip = s->server->line_max;
line_break = LINE_BREAK_LINE_MAX;
} else
break;
r = stdout_stream_line(s, p, line_break);
r = stdout_stream_found(s, p, found, line_break);
if (r < 0)
return r;
remaining -= skip;
p += skip;
consumed += skip;
remaining -= skip;
}
if (force_flush && remaining > 0) {
p[remaining] = 0;
r = stdout_stream_line(s, p, LINE_BREAK_EOF);
if (force_flush >= 0 && remaining > 0) {
r = stdout_stream_found(s, p, remaining, force_flush);
if (r < 0)
return r;
p += remaining;
remaining = 0;
consumed += remaining;
}
if (p > s->buffer) {
memmove(s->buffer, p, remaining);
s->length = remaining;
}
if (ret_consumed)
*ret_consumed = consumed;
return 0;
}
@ -491,10 +522,11 @@ static int stdout_stream_scan(StdoutStream *s, bool force_flush) {
static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred))) control;
StdoutStream *s = userdata;
size_t limit, consumed;
struct ucred *ucred;
struct iovec iovec;
size_t limit;
ssize_t l;
char *p;
int r;
struct msghdr msghdr = {
@ -511,8 +543,8 @@ static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents,
goto terminate;
}
/* If the buffer is full already (discounting the extra NUL we need), add room for another 1K */
if (s->length + 1 >= s->allocated) {
/* If the buffer is almost full, add room for another 1K */
if (s->length + 512 >= s->allocated) {
if (!GREEDY_REALLOC(s->buffer, s->allocated, s->length + 1 + 1024)) {
log_oom();
goto terminate;
@ -522,7 +554,7 @@ static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents,
/* Try to make use of the allocated buffer in full, but never read more than the configured line size. Also,
* always leave room for a terminating NUL we might need to add. */
limit = MIN(s->allocated - 1, s->server->line_max);
assert(s->length <= limit);
iovec = IOVEC_MAKE(s->buffer + s->length, limit - s->length);
l = recvmsg(s->fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
@ -536,32 +568,42 @@ static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents,
cmsg_close_all(&msghdr);
if (l == 0) {
stdout_stream_scan(s, true);
(void) stdout_stream_scan(s, s->buffer, s->length, /* force_flush = */ LINE_BREAK_EOF, NULL);
goto terminate;
}
/* Invalidate the context if the pid of the sender changed. This happens when a forked process
* inherits stdout / stderr from a parent. In this case getpeercred returns the ucred of the parent,
* which can be invalid if the parent has exited in the meantime.
*/
/* Invalidate the context if the PID of the sender changed. This happens when a forked process
* inherits stdout/stderr from a parent. In this case getpeercred() returns the ucred of the parent,
* which can be invalid if the parent has exited in the meantime. */
ucred = CMSG_FIND_DATA(&msghdr, SOL_SOCKET, SCM_CREDENTIALS, struct ucred);
if (ucred && ucred->pid != s->ucred.pid) {
/* force out any previously half-written lines from a different process, before we switch to
/* Force out any previously half-written lines from a different process, before we switch to
* the new ucred structure for everything we just added */
r = stdout_stream_scan(s, true);
r = stdout_stream_scan(s, s->buffer, s->length, /* force_flush = */ LINE_BREAK_PID_CHANGE, NULL);
if (r < 0)
goto terminate;
s->ucred = *ucred;
client_context_release(s->server, s->context);
s->context = NULL;
s->context = client_context_release(s->server, s->context);
p = s->buffer + s->length;
} else {
p = s->buffer;
l += s->length;
}
s->length += l;
r = stdout_stream_scan(s, false);
/* Always copy in the new credentials */
if (ucred)
s->ucred = *ucred;
r = stdout_stream_scan(s, p, l, _LINE_BREAK_INVALID, &consumed);
if (r < 0)
goto terminate;
/* Move what wasn't consumed to the front of the buffer */
assert(consumed <= (size_t) l);
s->length = l - consumed;
memmove(s->buffer, p + consumed, s->length);
return 1;
terminate:

View File

@ -22,4 +22,5 @@ static void test_audit_type(void) {
int main(int argc, char **argv) {
test_audit_type();
return 0;
}

View File

@ -590,8 +590,7 @@ _public_ int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p, int dynamic) {
cur->valid_until = valid_until;
cur->preferred_until = preferred_until;
log_radv("%s prefix %s/%u preferred %s valid %s",
cur? "Updated": "Added",
log_radv("Updated prefix %s/%u preferred %s valid %s",
addr_p, p->opt.prefixlen,
format_timespan(time_string_preferred, FORMAT_TIMESPAN_MAX,
preferred, USEC_PER_SEC),
@ -691,8 +690,7 @@ _public_ int sd_radv_add_route_prefix(sd_radv *ra, sd_radv_route_prefix *p, int
if (valid_until == USEC_INFINITY)
return -EOVERFLOW;
log_radv("%s route prefix %s/%u valid %s",
cur? "Updated": "Added",
log_radv("Updated route prefix %s/%u valid %s",
strempty(pretty), p->opt.prefixlen,
format_timespan(time_string_valid, FORMAT_TIMESPAN_MAX, valid, USEC_PER_SEC));

View File

@ -87,4 +87,5 @@ int main(int argc, char *argv[]) {
test_dhcp_lease_parse_search_domains_no_data();
test_dhcp_lease_parse_search_domains_loops();
test_dhcp_lease_parse_search_domains_wrong_len();
return 0;
}

View File

@ -317,7 +317,7 @@ static void* client1(void *p) {
finish:
if (bus) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *q;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *q = NULL;
r = sd_bus_message_new_method_call(
bus,
@ -485,7 +485,7 @@ static void* client2(void *p) {
finish:
if (bus) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *q;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *q = NULL;
r = sd_bus_message_new_method_call(
bus,

View File

@ -15,8 +15,7 @@
#include "socket-util.h"
#include "strv.h"
#define GET_CONTAINER(m, i) ((i) < (m)->n_containers ? (struct rtattr*)((uint8_t*)(m)->hdr + (m)->containers[i].offset) : NULL)
#define PUSH_CONTAINER(m, new) (m)->container_offsets[(m)->n_containers++] = (uint8_t*)(new) - (uint8_t*)(m)->hdr;
#define GET_CONTAINER(m, i) ((struct rtattr*)((uint8_t*)(m)->hdr + (m)->containers[i].offset))
#define RTA_TYPE(rta) ((rta)->rta_type & NLA_TYPE_MASK)
#define RTA_FLAGS(rta) ((rta)->rta_type & ~NLA_TYPE_MASK)
@ -520,7 +519,8 @@ int sd_netlink_message_open_container(sd_netlink_message *m, unsigned short type
assert_return(m, -EINVAL);
assert_return(!m->sealed, -EPERM);
assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -ERANGE);
/* m->containers[m->n_containers + 1] is accessed both in read and write. Prevent access out of bound */
assert_return(m->n_containers < (RTNL_CONTAINER_DEPTH - 1), -ERANGE);
r = message_attribute_has_type(m, &size, type, NETLINK_TYPE_NESTED);
if (r < 0) {
@ -567,6 +567,7 @@ int sd_netlink_message_open_container_union(sd_netlink_message *m, unsigned shor
assert_return(m, -EINVAL);
assert_return(!m->sealed, -EPERM);
assert_return(m->n_containers < (RTNL_CONTAINER_DEPTH - 1), -ERANGE);
r = type_system_get_type_system_union(m->containers[m->n_containers].type_system, &type_system_union, type);
if (r < 0)
@ -609,6 +610,7 @@ int sd_netlink_message_open_array(sd_netlink_message *m, uint16_t type) {
assert_return(m, -EINVAL);
assert_return(!m->sealed, -EPERM);
assert_return(m->n_containers < (RTNL_CONTAINER_DEPTH - 1), -ERANGE);
r = add_rtattr(m, type | NLA_F_NESTED, NULL, 0);
if (r < 0)
@ -1007,7 +1009,7 @@ int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short typ
int r;
assert_return(m, -EINVAL);
assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -EINVAL);
assert_return(m->n_containers < (RTNL_CONTAINER_DEPTH - 1), -EINVAL);
r = type_system_get_type(m->containers[m->n_containers].type_system,
&nl_type,
@ -1098,7 +1100,7 @@ int sd_netlink_message_enter_array(sd_netlink_message *m, unsigned short type_id
int r;
assert_return(m, -EINVAL);
assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -EINVAL);
assert_return(m->n_containers < (RTNL_CONTAINER_DEPTH - 1), -EINVAL);
r = netlink_message_read_internal(m, type_id, &container, NULL);
if (r < 0)

View File

@ -128,7 +128,7 @@ static void test_address_get(sd_netlink *rtnl, int ifindex) {
}
static void test_route(sd_netlink *rtnl) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req;
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
struct in_addr addr, addr_data;
uint32_t index = 2, u32_data;
int r;

View File

@ -828,7 +828,7 @@ int config_parse_macsec_key_id(
_cleanup_(macsec_transmit_association_free_or_set_invalidp) TransmitAssociation *a = NULL;
_cleanup_(macsec_receive_association_free_or_set_invalidp) ReceiveAssociation *b = NULL;
_cleanup_free_ void *p;
_cleanup_free_ void *p = NULL;
MACsec *s = userdata;
uint8_t *dest;
size_t l;

View File

@ -253,4 +253,5 @@ int main(void) {
test_network_get(manager, loopback);
assert_se(manager_rtnl_enumerate_links(manager) >= 0);
return 0;
}

View File

@ -28,7 +28,7 @@ static ssize_t dnstls_stream_writev(gnutls_transport_ptr_t p, const giovec_t *io
}
int dnstls_stream_connect_tls(DnsStream *stream, DnsServer *server) {
_cleanup_(gnutls_deinitp) gnutls_session_t gs;
_cleanup_(gnutls_deinitp) gnutls_session_t gs = NULL;
int r;
assert(stream);

View File

@ -1743,7 +1743,7 @@ int seccomp_restrict_archs(Set *archs) {
}
int parse_syscall_archs(char **l, Set **archs) {
_cleanup_set_free_ Set *_archs;
_cleanup_set_free_ Set *_archs = NULL;
char **s;
int r;

View File

@ -3775,6 +3775,8 @@ static int clean_or_freeze_unit(int argc, char *argv[], void *userdata) {
method = "FreezeUnit";
else if (streq(argv[0], "thaw"))
method = "ThawUnit";
else
assert_not_reached("Unhandled method");
STRV_FOREACH(name, names) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;

View File

@ -21,7 +21,7 @@ static void do_fstab_filter_options(const char *opts,
int r;
const char *name;
_cleanup_free_ char *value, *filtered;
_cleanup_free_ char *value = NULL, *filtered = NULL;
r = fstab_filter_options(opts, remove, &name, &value, &filtered);
log_info("\"%s\" → %d, \"%s\", \"%s\", \"%s\", expected %d, \"%s\", \"%s\", \"%s\"",

View File

@ -207,7 +207,7 @@ static int link_unsigned_attribute(sd_device *device, const char *attr, unsigned
}
int link_config_load(link_config_ctx *ctx) {
_cleanup_strv_free_ char **files;
_cleanup_strv_free_ char **files = NULL;
char **f;
int r;

View File

@ -87,6 +87,18 @@ journalctl -b -o export -t "$ID" --output-fields=_PID | grep '^_PID=' >/output
grep -q "^_PID=$PID" /output
grep -vq "^_PID=$PID" /output
# https://github.com/systemd/systemd/issues/15654
ID=$(journalctl --new-id128 | sed -n 2p)
printf "This will\nusually fail\nand be truncated\n">/expected
systemd-cat -t "$ID" /bin/sh -c 'env echo -n "This will";echo;env echo -n "usually fail";echo;env echo -n "and be truncated";echo;'
journalctl --sync
journalctl -b -o cat -t "$ID" >/output
cmp /expected /output
[[ $(journalctl -b -o cat -t "$ID" --output-fields=_TRANSPORT | grep -Pc "^stdout$") -eq 3 ]]
[[ $(journalctl -b -o cat -t "$ID" --output-fields=_LINE_BREAK | grep -Pc "^pid-change$") -eq 3 ]]
[[ $(journalctl -b -o cat -t "$ID" --output-fields=_PID | sort -u | grep -c "^.*$") -eq 3 ]]
[[ $(journalctl -b -o cat -t "$ID" --output-fields=MESSAGE | grep -Pc "^(This will|usually fail|and be truncated)$") -eq 3 ]]
# Add new tests before here, the journald restarts below
# may make tests flappy.

View File

@ -20,6 +20,7 @@ ADDITIONAL_DEPS=(python3-libevdev
clang
perl
libpwquality-dev
fdisk
libfdisk-dev
libp11-kit-dev
libssl-dev