journald-native.c revision 12a717f8347f3daf0ae46a2b71c7d011d9c12fea
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering/***
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering This file is part of systemd.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Copyright 2011 Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering systemd is free software; you can redistribute it and/or modify it
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering under the terms of the GNU Lesser General Public License as published by
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering (at your option) any later version.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering systemd is distributed in the hope that it will be useful, but
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Lesser General Public License for more details.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering You should have received a copy of the GNU Lesser General Public License
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering***/
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
4871690d9e32608bbd9b18505b5326c2079c9690Allin Cottrell#include <unistd.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include <stddef.h>
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering#include <sys/epoll.h>
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering#include <sys/mman.h>
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering#include "socket-util.h"
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering#include "path-util.h"
13790add4bf648fed816361794d8277a75253410Lennart Poettering#include "selinux-util.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "journald-server.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "journald-native.h"
a09561746f15b84da9471b5c4be74e53d19e4f3fLennart Poettering#include "journald-kmsg.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "journald-console.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "journald-syslog.h"
13790add4bf648fed816361794d8277a75253410Lennart Poettering#include "journald-wall.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "memfd-util.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekbool valid_user_field(const char *p, size_t l, bool allow_protected) {
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering const char *a;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen /* We kinda enforce POSIX syntax recommendations for
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering environment variables here, but make a couple of additional
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering requirements.
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html */
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering /* No empty field names */
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (l <= 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return false;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering /* Don't allow names longer than 64 chars */
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (l > 64)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return false;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering /* Variables starting with an underscore are protected */
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!allow_protected && p[0] == '_')
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return false;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering /* Don't allow digits as first character */
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (p[0] >= '0' && p[0] <= '9')
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return false;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering /* Only allow A-Z0-9 and '_' */
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering for (a = p; a < p + l; a++)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if ((*a < 'A' || *a > 'Z') &&
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering (*a < '0' || *a > '9') &&
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering *a != '_')
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return false;
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return true;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering}
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic bool allow_object_pid(const struct ucred *ucred) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return ucred && ucred->uid == 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering}
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringvoid server_process_native_message(
13790add4bf648fed816361794d8277a75253410Lennart Poettering Server *s,
13790add4bf648fed816361794d8277a75253410Lennart Poettering const void *buffer, size_t buffer_size,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering const struct ucred *ucred,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering const struct timeval *tv,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering const char *label, size_t label_len) {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering struct iovec *iovec = NULL;
13790add4bf648fed816361794d8277a75253410Lennart Poettering unsigned n = 0, j, tn = (unsigned) -1;
13790add4bf648fed816361794d8277a75253410Lennart Poettering const char *p;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering size_t remaining, m = 0, entry_size = 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering int priority = LOG_INFO;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering char *identifier = NULL, *message = NULL;
13790add4bf648fed816361794d8277a75253410Lennart Poettering pid_t object_pid = 0;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(s);
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(buffer || buffer_size == 0);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering p = buffer;
13790add4bf648fed816361794d8277a75253410Lennart Poettering remaining = buffer_size;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering while (remaining > 0) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering const char *e, *q;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering e = memchr(p, '\n', remaining);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!e) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* Trailing noise, let's ignore it, and flush what we collected */
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_debug("Received message with trailing noise, ignoring.");
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek break;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (e == p) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* Entry separator */
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (entry_size + n + 1 > ENTRY_SIZE_MAX) { /* data + separators + trailer */
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_debug("Entry is too big with %u properties and %zu bytes, ignoring.", n, entry_size);
13790add4bf648fed816361794d8277a75253410Lennart Poettering continue;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority, object_pid);
13790add4bf648fed816361794d8277a75253410Lennart Poettering n = 0;
13790add4bf648fed816361794d8277a75253410Lennart Poettering priority = LOG_INFO;
13790add4bf648fed816361794d8277a75253410Lennart Poettering entry_size = 0;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering p++;
13790add4bf648fed816361794d8277a75253410Lennart Poettering remaining--;
13790add4bf648fed816361794d8277a75253410Lennart Poettering continue;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (*p == '.' || *p == '#') {
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* Ignore control commands for now, and
13790add4bf648fed816361794d8277a75253410Lennart Poettering * comments too. */
13790add4bf648fed816361794d8277a75253410Lennart Poettering remaining -= (e - p) + 1;
13790add4bf648fed816361794d8277a75253410Lennart Poettering p = e + 1;
13790add4bf648fed816361794d8277a75253410Lennart Poettering continue;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* A property follows */
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* n existing properties, 1 new, +1 for _TRANSPORT */
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!GREEDY_REALLOC(iovec, m, n + 2 + N_IOVEC_META_FIELDS + !!object_pid * N_IOVEC_OBJECT_FIELDS)) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_oom();
13790add4bf648fed816361794d8277a75253410Lennart Poettering break;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering q = memchr(p, '=', e - p);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (q) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (valid_user_field(p, q - p, false)) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering size_t l;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering l = e - p;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* If the field name starts with an
13790add4bf648fed816361794d8277a75253410Lennart Poettering * underscore, skip the variable,
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering * since that indidates a trusted
13790add4bf648fed816361794d8277a75253410Lennart Poettering * field */
13790add4bf648fed816361794d8277a75253410Lennart Poettering iovec[n].iov_base = (char*) p;
13790add4bf648fed816361794d8277a75253410Lennart Poettering iovec[n].iov_len = l;
13790add4bf648fed816361794d8277a75253410Lennart Poettering entry_size += iovec[n].iov_len;
13790add4bf648fed816361794d8277a75253410Lennart Poettering n++;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* We need to determine the priority
13790add4bf648fed816361794d8277a75253410Lennart Poettering * of this entry for the rate limiting
13790add4bf648fed816361794d8277a75253410Lennart Poettering * logic */
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (l == 10 &&
13790add4bf648fed816361794d8277a75253410Lennart Poettering startswith(p, "PRIORITY=") &&
13790add4bf648fed816361794d8277a75253410Lennart Poettering p[9] >= '0' && p[9] <= '9')
13790add4bf648fed816361794d8277a75253410Lennart Poettering priority = (priority & LOG_FACMASK) | (p[9] - '0');
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering else if (l == 17 &&
13790add4bf648fed816361794d8277a75253410Lennart Poettering startswith(p, "SYSLOG_FACILITY=") &&
13790add4bf648fed816361794d8277a75253410Lennart Poettering p[16] >= '0' && p[16] <= '9')
13790add4bf648fed816361794d8277a75253410Lennart Poettering priority = (priority & LOG_PRIMASK) | ((p[16] - '0') << 3);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering else if (l == 18 &&
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering startswith(p, "SYSLOG_FACILITY=") &&
13790add4bf648fed816361794d8277a75253410Lennart Poettering p[16] >= '0' && p[16] <= '9' &&
13790add4bf648fed816361794d8277a75253410Lennart Poettering p[17] >= '0' && p[17] <= '9')
13790add4bf648fed816361794d8277a75253410Lennart Poettering priority = (priority & LOG_PRIMASK) | (((p[16] - '0')*10 + (p[17] - '0')) << 3);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering else if (l >= 19 &&
13790add4bf648fed816361794d8277a75253410Lennart Poettering startswith(p, "SYSLOG_IDENTIFIER=")) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering char *t;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering t = strndup(p + 18, l - 18);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (t) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering free(identifier);
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering identifier = t;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering } else if (l >= 8 &&
13790add4bf648fed816361794d8277a75253410Lennart Poettering startswith(p, "MESSAGE=")) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering char *t;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering t = strndup(p + 8, l - 8);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (t) {
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering free(message);
13790add4bf648fed816361794d8277a75253410Lennart Poettering message = t;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering } else if (l > strlen("OBJECT_PID=") &&
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering l < strlen("OBJECT_PID=") + DECIMAL_STR_MAX(pid_t) &&
13790add4bf648fed816361794d8277a75253410Lennart Poettering startswith(p, "OBJECT_PID=") &&
13790add4bf648fed816361794d8277a75253410Lennart Poettering allow_object_pid(ucred)) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering char buf[DECIMAL_STR_MAX(pid_t)];
13790add4bf648fed816361794d8277a75253410Lennart Poettering memcpy(buf, p + strlen("OBJECT_PID="), l - strlen("OBJECT_PID="));
13790add4bf648fed816361794d8277a75253410Lennart Poettering char_array_0(buf);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* ignore error */
13790add4bf648fed816361794d8277a75253410Lennart Poettering parse_pid(buf, &object_pid);
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering remaining -= (e - p) + 1;
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering p = e + 1;
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering continue;
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering } else {
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering le64_t l_le;
13790add4bf648fed816361794d8277a75253410Lennart Poettering uint64_t l;
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering char *k;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (remaining < e - p + 1 + sizeof(uint64_t) + 1) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_debug("Failed to parse message, ignoring.");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering break;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek memcpy(&l_le, e + 1, sizeof(uint64_t));
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek l = le64toh(l_le);
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek if (l > DATA_SIZE_MAX) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_debug("Received binary data block of %"PRIu64" bytes is too large, ignoring.", l);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering break;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if ((uint64_t) remaining < e - p + 1 + sizeof(uint64_t) + l + 1 ||
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering e[1+sizeof(uint64_t)+l] != '\n') {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_debug("Failed to parse message, ignoring.");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering break;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek k = malloc((e - p) + 1 + l);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!k) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_oom();
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering break;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering memcpy(k, p, e - p);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering k[e - p] = '=';
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering memcpy(k + (e - p) + 1, e + 1 + sizeof(uint64_t), l);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (valid_user_field(p, e - p, false)) {
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen iovec[n].iov_base = k;
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen iovec[n].iov_len = (e - p) + 1 + l;
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen entry_size += iovec[n].iov_len;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering n++;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering } else
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek free(k);
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering remaining -= (e - p) + 1 + sizeof(uint64_t) + l + 1;
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek p = e + 1 + sizeof(uint64_t) + l + 1;
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek }
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek }
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (n <= 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering goto finish;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering tn = n++;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering IOVEC_SET_STRING(iovec[tn], "_TRANSPORT=journal");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering entry_size += strlen("_TRANSPORT=journal");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (entry_size + n + 1 > ENTRY_SIZE_MAX) { /* data + separators + trailer */
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_debug("Entry is too big with %u properties and %zu bytes, ignoring.",
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering n, entry_size);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering goto finish;
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek }
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (message) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (s->forward_to_syslog)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering server_forward_syslog(s, priority, identifier, message, ucred, tv);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (s->forward_to_kmsg)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering server_forward_kmsg(s, priority, identifier, message, ucred);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (s->forward_to_console)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering server_forward_console(s, priority, identifier, message, ucred);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (s->forward_to_wall)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering server_forward_wall(s, priority, identifier, message, ucred);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority, object_pid);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringfinish:
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering for (j = 0; j < n; j++) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (j == tn)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering continue;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (iovec[j].iov_base < buffer ||
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering (const uint8_t*) iovec[j].iov_base >= (const uint8_t*) buffer + buffer_size)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering free(iovec[j].iov_base);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering free(iovec);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering free(identifier);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering free(message);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering}
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringvoid server_process_native_file(
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Server *s,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering int fd,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering const struct ucred *ucred,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering const struct timeval *tv,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering const char *label, size_t label_len) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering struct stat st;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering bool sealed;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering int r;
41891700e02daf0cab9e86908c76ac6f411bbd57Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering /* Data is in the passed fd, since it didn't fit in a
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering * datagram. */
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(s);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(fd >= 0);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering /* If it's a memfd, check if it is sealed. If so, we can just
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering * use map it and use it, and do not need to copy the data
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering * out. */
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering sealed = memfd_get_sealed(fd) > 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!sealed && (!ucred || ucred->uid != 0)) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering _cleanup_free_ char *sl = NULL, *k = NULL;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering const char *e;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering /* If this is not a sealed memfd, and the peer is unknown or
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering * unprivileged, then verify the path. */
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (asprintf(&sl, "/proc/self/fd/%i", fd) < 0) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_oom();
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = readlink_malloc(sl, &k);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (r < 0) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_error_errno(errno, "readlink(%s) failed: %m", sl);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering e = path_startswith(k, "/dev/shm/");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!e)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering e = path_startswith(k, "/tmp/");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!e)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering e = path_startswith(k, "/var/tmp/");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!e) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_error("Received file outside of allowed directories. Refusing.");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!filename_is_valid(e)) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_error("Received file in subdirectory of allowed directories. Refusing.");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (fstat(fd, &st) < 0) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_error_errno(errno, "Failed to stat passed file, ignoring: %m");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!S_ISREG(st.st_mode)) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_error("File passed is not regular. Ignoring.");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (st.st_size <= 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (st.st_size > ENTRY_SIZE_MAX) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_error("File passed too large. Ignoring.");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (sealed) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering void *p;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering size_t ps;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering /* The file is sealed, we can just map it and use it. */
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering ps = PAGE_ALIGN(st.st_size);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering p = mmap(NULL, ps, PROT_READ, MAP_PRIVATE, fd, 0);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (p == MAP_FAILED) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_error_errno(errno, "Failed to map memfd, ignoring: %m");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering server_process_native_message(s, p, st.st_size, ucred, tv, label, label_len);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert_se(munmap(p, ps) >= 0);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering } else {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering _cleanup_free_ void *p = NULL;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering ssize_t n;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering /* The file is not sealed, we can't map the file here, since
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering * clients might then truncate it and trigger a SIGBUS for
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering * us. So let's stupidly read it */
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering p = malloc(st.st_size);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!p) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_oom();
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering n = pread(fd, p, st.st_size, 0);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (n < 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_error_errno(n, "Failed to read file, ignoring: %m");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering else if (n > 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering server_process_native_message(s, p, n, ucred, tv, label, label_len);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering}
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringint server_open_native_socket(Server*s) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering static const int one = 1;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering int r;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(s);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (s->native_fd < 0) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering union sockaddr_union sa = {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering .un.sun_family = AF_UNIX,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering .un.sun_path = "/run/systemd/journal/socket",
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering };
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering s->native_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (s->native_fd < 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return log_error_errno(errno, "socket() failed: %m");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering unlink(sa.un.sun_path);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering r = bind(s->native_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering if (r < 0)
91bf3b3e124575f6f647bff29766e9d992f55b32Lennart Poettering return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering chmod(sa.un.sun_path, 0666);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering } else
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering fd_nonblock(s->native_fd, 1);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (r < 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return log_error_errno(errno, "SO_PASSCRED failed: %m");
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt
91bf3b3e124575f6f647bff29766e9d992f55b32Lennart Poettering#ifdef HAVE_SELINUX
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (mac_selinux_use()) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one));
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (r < 0)
7b77ed8cf36e8eca6017791626044b61ae2d68e7Lennart Poettering log_warning_errno(errno, "SO_PASSSEC failed: %m");
91bf3b3e124575f6f647bff29766e9d992f55b32Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering#endif
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = setsockopt(s->native_fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one));
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (r < 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return log_error_errno(errno, "SO_TIMESTAMP failed: %m");
91bf3b3e124575f6f647bff29766e9d992f55b32Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = sd_event_add_io(s->event, &s->native_event_source, s->native_fd, EPOLLIN, process_datagram, s);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (r < 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return log_error_errno(r, "Failed to add native server fd to event loop: %m");
91bf3b3e124575f6f647bff29766e9d992f55b32Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering return 0;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering}
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering