Then, we can drop label_len or label_size arguments at various places.
While doing this, SCM_SECURITY is now ignored when SELinux is disabled
or when it contains embedded NUL.
_cleanup_(manager_freep) Manager *m = NULL;
_cleanup_close_ int sealed_fd = -EBADF, unsealed_fd = -EBADF;
_cleanup_(unlink_tempfilep) char name[] = "/tmp/fuzz-journald-native-fd.XXXXXX";
- char *label = NULL;
- size_t label_len = 0;
struct ucred ucred;
struct timeval *tv = NULL;
.uid = geteuid(),
.gid = getegid(),
};
- (void) manager_process_native_file(m, sealed_fd, &ucred, tv, label, label_len);
+ (void) manager_process_native_file(m, sealed_fd, &ucred, tv, /* label= */ NULL);
unsealed_fd = mkostemp_safe(name);
assert_se(unsealed_fd >= 0);
assert_se(write(unsealed_fd, data, size) == (ssize_t) size);
assert_se(lseek(unsealed_fd, 0, SEEK_SET) == 0);
- (void) manager_process_native_file(m, unsealed_fd, &ucred, tv, label, label_len);
+ (void) manager_process_native_file(m, unsealed_fd, &ucred, tv, /* label= */ NULL);
return 0;
}
_cleanup_(manager_freep) Manager *m = NULL;
dummy_manager_new(&m, data, size);
- f(m, m->buffer, size, /* ucred= */ NULL, /* tv= */ NULL, /* label= */ NULL, /* label_len= */ 0);
+ f(m, m->buffer, size, /* ucred= */ NULL, /* tv= */ NULL, /* label= */ NULL);
}
size_t raw_len,
const struct ucred *ucred,
const struct timeval *tv,
- const char *label,
- size_t label_len);
+ const char *label);
void dummy_manager_new(Manager **ret, const uint8_t *buffer, size_t size);
c->invocation_id = SD_ID128_NULL;
c->label = mfree(c->label);
- c->label_size = 0;
c->extra_fields_iovec = mfree(c->extra_fields_iovec);
c->extra_fields_n_iovec = 0;
static int client_context_read_label(
ClientContext *c,
- const char *label, size_t label_size) {
+ const char *label) {
+
+ int r;
assert(c);
assert(pid_is_valid(c->pid));
- assert(label_size == 0 || label);
if (!mac_selinux_use())
return 0;
- if (label_size > 0) {
- char *l;
-
+ if (label) {
/* If we got an SELinux label passed in it counts. */
-
- l = newdup_suffix0(char, label, label_size);
- if (!l)
+ r = free_and_strdup(&c->label, label);
+ if (r < 0)
return -ENOMEM;
-
- free_and_replace(c->label, l);
- c->label_size = label_size;
}
#if HAVE_SELINUX
else {
/* If we got no SELinux label passed in, let's try to acquire one */
- if (sym_getpidcon_raw(c->pid, &con) >= 0 && con) {
+ if (sym_getpidcon_raw(c->pid, &con) >= 0 && con)
free_and_replace(c->label, con);
- c->label_size = strlen(c->label);
- }
}
#endif
Manager *m,
ClientContext *c,
const struct ucred *ucred,
- const char *label, size_t label_size,
+ const char *label,
const char *unit_id,
usec_t timestamp) {
client_context_read_uid_gid(c, ucred);
client_context_read_basic(c);
- (void) client_context_read_label(c, label, label_size);
+ (void) client_context_read_label(c, label);
(void) audit_session_from_pid(&PIDREF_MAKE_FROM_PID(c->pid), &c->auditid);
(void) audit_loginuid_from_pid(&PIDREF_MAKE_FROM_PID(c->pid), &c->loginuid);
Manager *m,
ClientContext *c,
const struct ucred *ucred,
- const char *label, size_t label_size,
+ const char *label,
const char *unit_id,
usec_t timestamp) {
if (ucred && gid_is_valid(ucred->gid) && c->gid != ucred->gid)
goto refresh;
- if (label_size > 0 && (label_size != c->label_size || memcmp(label, c->label, label_size) != 0))
+ if (label && !streq_ptr(label, c->label))
goto refresh;
return;
refresh:
- client_context_really_refresh(m, c, ucred, label, label_size, unit_id, timestamp);
+ client_context_really_refresh(m, c, ucred, label, unit_id, timestamp);
}
static void client_context_refresh_on_reload(Manager *m, ClientContext *c) {
Manager *m,
pid_t pid,
const struct ucred *ucred,
- const char *label, size_t label_len,
+ const char *label,
const char *unit_id,
bool add_ref,
ClientContext **ret) {
c->n_ref++;
}
- client_context_maybe_refresh(m, c, ucred, label, label_len, unit_id, USEC_INFINITY);
+ client_context_maybe_refresh(m, c, ucred, label, unit_id, USEC_INFINITY);
*ret = c;
return 0;
c->in_lru = true;
}
- client_context_really_refresh(m, c, ucred, label, label_len, unit_id, USEC_INFINITY);
+ client_context_really_refresh(m, c, ucred, label, unit_id, USEC_INFINITY);
*ret = c;
return 0;
Manager *m,
pid_t pid,
const struct ucred *ucred,
- const char *label, size_t label_len,
+ const char *label,
const char *unit_id,
ClientContext **ret) {
- return client_context_get_internal(m, pid, ucred, label, label_len, unit_id, false, ret);
+ return client_context_get_internal(m, pid, ucred, label, unit_id, /* add_ref= */ false, ret);
}
int client_context_acquire(
Manager *m,
pid_t pid,
const struct ucred *ucred,
- const char *label, size_t label_len,
+ const char *label,
const char *unit_id,
ClientContext **ret) {
- return client_context_get_internal(m, pid, ucred, label, label_len, unit_id, true, ret);
+ return client_context_get_internal(m, pid, ucred, label, unit_id, /* add_ref= */ true, ret);
};
ClientContext *client_context_release(Manager *m, ClientContext *c) {
.gid = getgid(),
};
- r = client_context_acquire(m, ucred.pid, &ucred, NULL, 0, NULL, &m->my_context);
+ r = client_context_acquire(m, ucred.pid, &ucred, /* label= */ NULL, /* unit_id= */ NULL, &m->my_context);
if (r < 0)
log_ratelimit_warning_errno(r, JOURNAL_LOG_RATELIMIT,
"Failed to acquire our own context, ignoring: %m");
/* Acquire PID1's context, but only if we are in non-namespaced mode, since PID 1 is only
* going to log to the non-namespaced journal instance. */
- r = client_context_acquire(m, 1, NULL, NULL, 0, NULL, &m->pid1_context);
+ r = client_context_acquire(m, 1, /* ucred= */ NULL, /* label= */ NULL, /* unit_id= */ NULL, &m->pid1_context);
if (r < 0)
log_ratelimit_warning_errno(r, JOURNAL_LOG_RATELIMIT,
"Failed to acquire PID1's context, ignoring: %m");
sd_id128_t invocation_id;
char *label;
- size_t label_size;
int log_level_max;
Manager *m,
pid_t pid,
const struct ucred *ucred,
- const char *label, size_t label_len,
+ const char *label,
const char *unit_id,
ClientContext **ret);
Manager *m,
pid_t pid,
const struct ucred *ucred,
- const char *label, size_t label_len,
+ const char *label,
const char *unit_id,
ClientContext **ret);
Manager *m,
ClientContext *c,
const struct ucred *ucred,
- const char *label, size_t label_size,
+ const char *label,
const char *unit_id,
usec_t timestamp);
#include "process-util.h"
#include "rm-rf.h"
#include "set.h"
+#include "selinux-util.h"
#include "signal-util.h"
#include "socket-util.h"
#include "stdio-util.h"
iovec[n++] = IOVEC_MAKE_STRING(k); \
}
-#define IOVEC_ADD_SIZED_FIELD(iovec, n, value, value_size, field) \
- if (value_size > 0) { \
- char *k; \
- k = newa(char, STRLEN(field "=") + value_size + 1); \
- *mempcpy_typesafe(stpcpy(k, field "="), value, value_size) = 0; \
- iovec[n++] = IOVEC_MAKE_STRING(k); \
- }
-
static void manager_dispatch_message_real(
Manager *m,
struct iovec *iovec, size_t n, size_t mm,
cmdline1 = set_iovec_string_field(iovec, &n, "_CMDLINE=", c->cmdline);
IOVEC_ADD_NUMERIC_FIELD(iovec, n, c->capability_quintet.effective, uint64_t, capability_is_set, "%" PRIx64, "_CAP_EFFECTIVE");
- IOVEC_ADD_SIZED_FIELD(iovec, n, c->label, c->label_size, "_SELINUX_CONTEXT");
+ IOVEC_ADD_STRING_FIELD(iovec, n, c->label, "_SELINUX_CONTEXT");
IOVEC_ADD_NUMERIC_FIELD(iovec, n, c->auditid, uint32_t, audit_session_is_valid, "%" PRIu32, "_AUDIT_SESSION");
IOVEC_ADD_NUMERIC_FIELD(iovec, n, c->loginuid, uid_t, uid_is_valid, UID_FMT, "_AUDIT_LOGINUID");
assert(n <= mm);
- if (pid_is_valid(object_pid) && client_context_get(m, object_pid, NULL, NULL, 0, NULL, &o) >= 0) {
+ if (pid_is_valid(object_pid) && client_context_get(m, object_pid, /* ucred= */ NULL, /* label= */ NULL, /* unit_id= */ NULL, &o) >= 0) {
IOVEC_ADD_NUMERIC_FIELD(iovec, n, o->pid, pid_t, pid_is_valid, PID_FMT, "OBJECT_PID");
IOVEC_ADD_NUMERIC_FIELD(iovec, n, o->uid, uid_t, uid_is_valid, UID_FMT, "OBJECT_UID");
cmdline2 = set_iovec_string_field(iovec, &n, "OBJECT_CMDLINE=", o->cmdline);
IOVEC_ADD_NUMERIC_FIELD(iovec, n, o->capability_quintet.effective, uint64_t, capability_is_set, "%" PRIx64, "OBJECT_CAP_EFFECTIVE");
- IOVEC_ADD_SIZED_FIELD(iovec, n, o->label, o->label_size, "OBJECT_SELINUX_CONTEXT");
+ IOVEC_ADD_STRING_FIELD(iovec, n, o->label, "OBJECT_SELINUX_CONTEXT");
IOVEC_ADD_NUMERIC_FIELD(iovec, n, o->auditid, uint32_t, audit_session_is_valid, "%" PRIu32, "OBJECT_AUDIT_SESSION");
IOVEC_ADD_NUMERIC_FIELD(iovec, n, o->loginuid, uid_t, uid_is_valid, UID_FMT, "OBJECT_AUDIT_LOGINUID");
uint32_t revents,
void *userdata) {
- size_t label_len = 0, mm;
+ size_t mm;
Manager *m = ASSERT_PTR(userdata);
struct ucred *ucred = NULL;
struct timeval tv_buf, *tv = NULL;
struct cmsghdr *cmsg;
- char *label = NULL;
+ _cleanup_free_ char *label = NULL;
struct iovec iovec;
ssize_t n;
int *fds = NULL, v = 0;
cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
assert(!ucred);
ucred = CMSG_TYPED_DATA(cmsg, struct ucred);
- } else if (cmsg->cmsg_type == SCM_SECURITY) {
+ } else if (cmsg->cmsg_type == SCM_SECURITY && mac_selinux_use()) {
assert(!label);
- label = CMSG_TYPED_DATA(cmsg, char);
- label_len = cmsg->cmsg_len - CMSG_LEN(0);
+ /* Here, we ignore any errors including OOM, as the field is optional. */
+ (void) make_cstring(CMSG_TYPED_DATA(cmsg, char), cmsg->cmsg_len - CMSG_LEN(0),
+ MAKE_CSTRING_ALLOW_TRAILING_NUL, &label);
} else if (cmsg->cmsg_type == SCM_TIMESTAMP &&
cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval))) {
assert(!tv);
if (fd == m->syslog_fd) {
if (n > 0 && n_fds == 0)
- manager_process_syslog_message(m, m->buffer, n, ucred, tv, label, label_len);
+ manager_process_syslog_message(m, m->buffer, n, ucred, tv, label);
else if (n_fds > 0)
log_ratelimit_warning(JOURNAL_LOG_RATELIMIT,
"Got file descriptors via syslog socket. Ignoring.");
} else if (fd == m->native_fd) {
if (n > 0 && n_fds == 0)
- manager_process_native_message(m, m->buffer, n, ucred, tv, label, label_len);
+ manager_process_native_message(m, m->buffer, n, ucred, tv, label);
else if (n == 0 && n_fds == 1)
- (void) manager_process_native_file(m, fds[0], ucred, tv, label, label_len);
+ (void) manager_process_native_file(m, fds[0], ucred, tv, label);
else if (n_fds > 0)
log_ratelimit_warning(JOURNAL_LOG_RATELIMIT,
"Got too many file descriptors via native socket. Ignoring.");
ClientContext *context,
const struct ucred *ucred,
const struct timeval *tv,
- const char *label, size_t label_len) {
+ const char *label) {
/* Process a single entry from a native message. Returns 0 if nothing special happened and the message
* processing should continue, and a negative or positive value otherwise.
const char *buffer, size_t buffer_size,
const struct ucred *ucred,
const struct timeval *tv,
- const char *label, size_t label_len) {
+ const char *label) {
size_t remaining = buffer_size;
ClientContext *context = NULL;
assert(buffer || buffer_size == 0);
if (ucred && pid_is_valid(ucred->pid)) {
- r = client_context_get(m, ucred->pid, ucred, label, label_len, NULL, &context);
+ r = client_context_get(m, ucred->pid, ucred, label, /* unit_id= */ NULL, &context);
if (r < 0)
log_ratelimit_warning_errno(r, JOURNAL_LOG_RATELIMIT,
"Failed to retrieve credentials for PID " PID_FMT ", ignoring: %m",
do {
r = manager_process_entry(m,
(const uint8_t*) buffer + (buffer_size - remaining), &remaining,
- context, ucred, tv, label, label_len);
+ context, ucred, tv, label);
} while (r == 0);
}
int fd,
const struct ucred *ucred,
const struct timeval *tv,
- const char *label, size_t label_len) {
+ const char *label) {
struct stat st;
bool sealed;
return log_ratelimit_error_errno(errno, JOURNAL_LOG_RATELIMIT,
"Failed to map memfd: %m");
- manager_process_native_message(m, p, st.st_size, ucred, tv, label, label_len);
+ manager_process_native_message(m, p, st.st_size, ucred, tv, label);
assert_se(munmap(p, ps) >= 0);
return 0;
return log_ratelimit_error_errno(errno, JOURNAL_LOG_RATELIMIT,
"Failed to read file: %m");
if (n > 0)
- manager_process_native_message(m, p, n, ucred, tv, label, label_len);
+ manager_process_native_message(m, p, n, ucred, tv, label);
return 0;
}
size_t buffer_size,
const struct ucred *ucred,
const struct timeval *tv,
- const char *label,
- size_t label_len);
+ const char *label);
int manager_process_native_file(
Manager *m,
int fd,
const struct ucred *ucred,
const struct timeval *tv,
- const char *label,
- size_t label_len);
+ const char *label);
int manager_open_native_socket(Manager *m, const char *native_socket);
assert(line_break < _LINE_BREAK_MAX);
if (s->context)
- client_context_maybe_refresh(s->manager, s->context, NULL, NULL, 0, NULL, USEC_INFINITY);
+ client_context_maybe_refresh(s->manager, s->context, /* ucred= */ NULL, /* label= */ NULL, /* unit_id= */ NULL, USEC_INFINITY);
else if (pid_is_valid(s->ucred.pid)) {
- r = client_context_acquire(s->manager, s->ucred.pid, &s->ucred, s->label, strlen_ptr(s->label), s->unit_id, &s->context);
+ r = client_context_acquire(s->manager, s->ucred.pid, &s->ucred, s->label, s->unit_id, &s->context);
if (r < 0)
log_ratelimit_warning_errno(r, JOURNAL_LOG_RATELIMIT,
"Failed to acquire client context, ignoring: %m");
size_t raw_len,
const struct ucred *ucred,
const struct timeval *tv,
- const char *label,
- size_t label_len) {
+ const char *label) {
char *t, syslog_priority[STRLEN("PRIORITY=") + DECIMAL_STR_MAX(int)],
syslog_facility[STRLEN("SYSLOG_FACILITY=") + DECIMAL_STR_MAX(int)];
assert(buf[raw_len] == '\0');
if (ucred && pid_is_valid(ucred->pid)) {
- r = client_context_get(m, ucred->pid, ucred, label, label_len, NULL, &context);
+ r = client_context_get(m, ucred->pid, ucred, label, /* unit_id= */ NULL, &context);
if (r < 0)
log_ratelimit_warning_errno(r, JOURNAL_LOG_RATELIMIT,
"Failed to retrieve credentials for PID " PID_FMT ", ignoring: %m",
void manager_forward_syslog(Manager *m, int priority, const char *identifier, const char *message, const struct ucred *ucred, const struct timeval *tv);
-void manager_process_syslog_message(Manager *m, const char *buf, size_t raw_len, const struct ucred *ucred, const struct timeval *tv, const char *label, size_t label_len);
+void manager_process_syslog_message(Manager *m, const char *buf, size_t raw_len, const struct ucred *ucred, const struct timeval *tv, const char *label);
int manager_open_syslog_socket(Manager *m, const char *syslog_socket);
void manager_maybe_warn_forward_syslog_missed(Manager *m);