0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering/***
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering This file is part of systemd.
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering Copyright 2011 Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering systemd is free software; you can redistribute it and/or modify it
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering under the terms of the GNU Lesser General Public License as published by
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering (at your option) any later version.
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering systemd is distributed in the hope that it will be useful, but
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering Lesser General Public License for more details.
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering You should have received a copy of the GNU Lesser General Public License
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering***/
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
4871690d9e32608bbd9b18505b5326c2079c9690Allin Cottrell#include <stddef.h>
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering#include <sys/epoll.h>
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering#include <sys/mman.h>
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering#include <sys/statvfs.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include <unistd.h>
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "alloc-util.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "fd-util.h"
f4f15635ec05293ffcc83a5b39f624bbabbd8fd0Lennart Poettering#include "fs-util.h"
afc5dbf37fd2399d37976388d9dd9ab470ecf446Lennart Poettering#include "io-util.h"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering#include "journald-console.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "journald-kmsg.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "journald-native.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "journald-server.h"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering#include "journald-syslog.h"
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen#include "journald-wall.h"
a09abc4ae0bdc0200324eaa0416f23ff2170ec4eLennart Poettering#include "memfd-util.h"
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering#include "parse-util.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "path-util.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "selinux-util.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "socket-util.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "string-util.h"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
d18d46ecea80a7f07415edb9264af6a254fd70bbZbigniew Jędrzejewski-Szmekbool valid_user_field(const char *p, size_t l, bool allow_protected) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering const char *a;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering /* We kinda enforce POSIX syntax recommendations for
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering environment variables here, but make a couple of additional
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering requirements.
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html */
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering /* No empty field names */
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (l <= 0)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return false;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering /* Don't allow names longer than 64 chars */
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (l > 64)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return false;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering /* Variables starting with an underscore are protected */
d18d46ecea80a7f07415edb9264af6a254fd70bbZbigniew Jędrzejewski-Szmek if (!allow_protected && p[0] == '_')
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return false;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering /* Don't allow digits as first character */
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (p[0] >= '0' && p[0] <= '9')
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return false;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering /* Only allow A-Z0-9 and '_' */
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering for (a = p; a < p + l; a++)
d18d46ecea80a7f07415edb9264af6a254fd70bbZbigniew Jędrzejewski-Szmek if ((*a < 'A' || *a > 'Z') &&
d18d46ecea80a7f07415edb9264af6a254fd70bbZbigniew Jędrzejewski-Szmek (*a < '0' || *a > '9') &&
d18d46ecea80a7f07415edb9264af6a254fd70bbZbigniew Jędrzejewski-Szmek *a != '_')
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return false;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return true;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering}
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
3b3154df7e2773332bb814e167187367a0ccae4aLennart Poetteringstatic bool allow_object_pid(const struct ucred *ucred) {
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek return ucred && ucred->uid == 0;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek}
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poetteringvoid server_process_native_message(
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering Server *s,
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering const void *buffer, size_t buffer_size,
3b3154df7e2773332bb814e167187367a0ccae4aLennart Poettering const struct ucred *ucred,
3b3154df7e2773332bb814e167187367a0ccae4aLennart Poettering const struct timeval *tv,
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering const char *label, size_t label_len) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering struct iovec *iovec = NULL;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek unsigned n = 0, j, tn = (unsigned) -1;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering const char *p;
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek size_t remaining, m = 0, entry_size = 0;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering int priority = LOG_INFO;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering char *identifier = NULL, *message = NULL;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek pid_t object_pid = 0;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering assert(s);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering assert(buffer || buffer_size == 0);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering p = buffer;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering remaining = buffer_size;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering while (remaining > 0) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering const char *e, *q;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering e = memchr(p, '\n', remaining);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (!e) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering /* Trailing noise, let's ignore it, and flush what we collected */
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering log_debug("Received message with trailing noise, ignoring.");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering break;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (e == p) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering /* Entry separator */
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek if (entry_size + n + 1 > ENTRY_SIZE_MAX) { /* data + separators + trailer */
8c0b803b97bb0ee6603d9be85fb6b69cd6081eafLennart Poettering log_debug("Entry is too big with %u properties and %zu bytes, ignoring.", n, entry_size);
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek continue;
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek }
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority, object_pid);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering n = 0;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering priority = LOG_INFO;
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek entry_size = 0;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering p++;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering remaining--;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering continue;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (*p == '.' || *p == '#') {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering /* Ignore control commands for now, and
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering * comments too. */
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering remaining -= (e - p) + 1;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering p = e + 1;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering continue;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering /* A property follows */
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
12a717f8347f3daf0ae46a2b71c7d011d9c12feaZbigniew Jędrzejewski-Szmek /* n existing properties, 1 new, +1 for _TRANSPORT */
92ee6447b1deef7c79962a8121fdf8e58acb3a83Zbigniew Jędrzejewski-Szmek if (!GREEDY_REALLOC(iovec, m, n + 2 + N_IOVEC_META_FIELDS + N_IOVEC_OBJECT_FIELDS)) {
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek log_oom();
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek break;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering q = memchr(p, '=', e - p);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (q) {
d18d46ecea80a7f07415edb9264af6a254fd70bbZbigniew Jędrzejewski-Szmek if (valid_user_field(p, q - p, false)) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering size_t l;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering l = e - p;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering /* If the field name starts with an
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering * underscore, skip the variable,
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering * since that indidates a trusted
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering * field */
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering iovec[n].iov_base = (char*) p;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering iovec[n].iov_len = l;
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek entry_size += iovec[n].iov_len;
a174f94d529c7ae9be589867308b669ec9b4dcc0Lennart Poettering n++;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering /* We need to determine the priority
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering * of this entry for the rate limiting
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering * logic */
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (l == 10 &&
2a0e0692565f0435657c93498e09cbb2d3517152Shawn Landden startswith(p, "PRIORITY=") &&
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering p[9] >= '0' && p[9] <= '9')
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering priority = (priority & LOG_FACMASK) | (p[9] - '0');
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering else if (l == 17 &&
2a0e0692565f0435657c93498e09cbb2d3517152Shawn Landden startswith(p, "SYSLOG_FACILITY=") &&
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering p[16] >= '0' && p[16] <= '9')
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering priority = (priority & LOG_PRIMASK) | ((p[16] - '0') << 3);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering else if (l == 18 &&
2a0e0692565f0435657c93498e09cbb2d3517152Shawn Landden startswith(p, "SYSLOG_FACILITY=") &&
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering p[16] >= '0' && p[16] <= '9' &&
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering p[17] >= '0' && p[17] <= '9')
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering priority = (priority & LOG_PRIMASK) | (((p[16] - '0')*10 + (p[17] - '0')) << 3);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering else if (l >= 19 &&
2a0e0692565f0435657c93498e09cbb2d3517152Shawn Landden startswith(p, "SYSLOG_IDENTIFIER=")) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering char *t;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering t = strndup(p + 18, l - 18);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (t) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering free(identifier);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering identifier = t;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
1f6b411372076426c0faf0bb350437fb4d82931fLennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering } else if (l >= 8 &&
2a0e0692565f0435657c93498e09cbb2d3517152Shawn Landden startswith(p, "MESSAGE=")) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering char *t;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering t = strndup(p + 8, l - 8);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (t) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering free(message);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering message = t;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
1f6b411372076426c0faf0bb350437fb4d82931fLennart Poettering
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek } else if (l > strlen("OBJECT_PID=") &&
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek l < strlen("OBJECT_PID=") + DECIMAL_STR_MAX(pid_t) &&
2a0e0692565f0435657c93498e09cbb2d3517152Shawn Landden startswith(p, "OBJECT_PID=") &&
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek allow_object_pid(ucred)) {
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek char buf[DECIMAL_STR_MAX(pid_t)];
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek memcpy(buf, p + strlen("OBJECT_PID="), l - strlen("OBJECT_PID="));
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek char_array_0(buf);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek /* ignore error */
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek parse_pid(buf, &object_pid);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering remaining -= (e - p) + 1;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering p = e + 1;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering continue;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering } else {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering le64_t l_le;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering uint64_t l;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering char *k;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (remaining < e - p + 1 + sizeof(uint64_t) + 1) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering log_debug("Failed to parse message, ignoring.");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering break;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering memcpy(&l_le, e + 1, sizeof(uint64_t));
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering l = le64toh(l_le);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
505b6a61c22d5565e9308045c7b9bf79f7d0517eLennart Poettering if (l > DATA_SIZE_MAX) {
fa1c4b518ec7d8ec2d647213ee651cde4d6c9d7eZbigniew Jędrzejewski-Szmek log_debug("Received binary data block of %"PRIu64" bytes is too large, ignoring.", l);
505b6a61c22d5565e9308045c7b9bf79f7d0517eLennart Poettering break;
505b6a61c22d5565e9308045c7b9bf79f7d0517eLennart Poettering }
505b6a61c22d5565e9308045c7b9bf79f7d0517eLennart Poettering
505b6a61c22d5565e9308045c7b9bf79f7d0517eLennart Poettering if ((uint64_t) remaining < e - p + 1 + sizeof(uint64_t) + l + 1 ||
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering e[1+sizeof(uint64_t)+l] != '\n') {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering log_debug("Failed to parse message, ignoring.");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering break;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering k = malloc((e - p) + 1 + l);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (!k) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering log_oom();
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering break;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering memcpy(k, p, e - p);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering k[e - p] = '=';
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering memcpy(k + (e - p) + 1, e + 1 + sizeof(uint64_t), l);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
d18d46ecea80a7f07415edb9264af6a254fd70bbZbigniew Jędrzejewski-Szmek if (valid_user_field(p, e - p, false)) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering iovec[n].iov_base = k;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering iovec[n].iov_len = (e - p) + 1 + l;
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek entry_size += iovec[n].iov_len;
a174f94d529c7ae9be589867308b669ec9b4dcc0Lennart Poettering n++;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering } else
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering free(k);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering remaining -= (e - p) + 1 + sizeof(uint64_t) + l + 1;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering p = e + 1 + sizeof(uint64_t) + l + 1;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (n <= 0)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering goto finish;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering tn = n++;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering IOVEC_SET_STRING(iovec[tn], "_TRANSPORT=journal");
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek entry_size += strlen("_TRANSPORT=journal");
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek if (entry_size + n + 1 > ENTRY_SIZE_MAX) { /* data + separators + trailer */
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek log_debug("Entry is too big with %u properties and %zu bytes, ignoring.",
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek n, entry_size);
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek goto finish;
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (message) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (s->forward_to_syslog)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering server_forward_syslog(s, priority, identifier, message, ucred, tv);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (s->forward_to_kmsg)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering server_forward_kmsg(s, priority, identifier, message, ucred);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (s->forward_to_console)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering server_forward_console(s, priority, identifier, message, ucred);
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen if (s->forward_to_wall)
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen server_forward_wall(s, priority, identifier, message, ucred);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority, object_pid);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poetteringfinish:
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering for (j = 0; j < n; j++) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (j == tn)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering continue;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (iovec[j].iov_base < buffer ||
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering (const uint8_t*) iovec[j].iov_base >= (const uint8_t*) buffer + buffer_size)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering free(iovec[j].iov_base);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering free(iovec);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering free(identifier);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering free(message);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering}
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poetteringvoid server_process_native_file(
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering Server *s,
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering int fd,
3b3154df7e2773332bb814e167187367a0ccae4aLennart Poettering const struct ucred *ucred,
3b3154df7e2773332bb814e167187367a0ccae4aLennart Poettering const struct timeval *tv,
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering const char *label, size_t label_len) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering struct stat st;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering bool sealed;
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering int r;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering /* Data is in the passed fd, since it didn't fit in a
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering * datagram. */
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering assert(s);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering assert(fd >= 0);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering /* If it's a memfd, check if it is sealed. If so, we can just
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering * use map it and use it, and do not need to copy the data
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering * out. */
73843b52585d42cc1a970a1c664818ece6942e9eLennart Poettering sealed = memfd_get_sealed(fd) > 0;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering if (!sealed && (!ucred || ucred->uid != 0)) {
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering _cleanup_free_ char *sl = NULL, *k = NULL;
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering const char *e;
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering /* If this is not a sealed memfd, and the peer is unknown or
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering * unprivileged, then verify the path. */
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering if (asprintf(&sl, "/proc/self/fd/%i", fd) < 0) {
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering log_oom();
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering return;
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering }
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering r = readlink_malloc(sl, &k);
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering if (r < 0) {
709f6e46a35ec492b70eb92943d82a8d838ce918Michal Schmidt log_error_errno(r, "readlink(%s) failed: %m", sl);
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering return;
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering }
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering e = path_startswith(k, "/dev/shm/");
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering if (!e)
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering e = path_startswith(k, "/tmp/");
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering if (!e)
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering e = path_startswith(k, "/var/tmp/");
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering if (!e) {
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering log_error("Received file outside of allowed directories. Refusing.");
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering return;
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering }
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering
ae6c3cc009a21df4b51851fb8fe3fde0b7d6d8f0Lennart Poettering if (!filename_is_valid(e)) {
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering log_error("Received file in subdirectory of allowed directories. Refusing.");
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering return;
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering }
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering }
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (fstat(fd, &st) < 0) {
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt log_error_errno(errno, "Failed to stat passed file, ignoring: %m");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (!S_ISREG(st.st_mode)) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering log_error("File passed is not regular. Ignoring.");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (st.st_size <= 0)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (st.st_size > ENTRY_SIZE_MAX) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering log_error("File passed too large. Ignoring.");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering if (sealed) {
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering void *p;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering size_t ps;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering /* The file is sealed, we can just map it and use it. */
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering ps = PAGE_ALIGN(st.st_size);
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering p = mmap(NULL, ps, PROT_READ, MAP_PRIVATE, fd, 0);
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering if (p == MAP_FAILED) {
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt log_error_errno(errno, "Failed to map memfd, ignoring: %m");
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering return;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering }
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering server_process_native_message(s, p, st.st_size, ucred, tv, label, label_len);
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering assert_se(munmap(p, ps) >= 0);
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering } else {
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering _cleanup_free_ void *p = NULL;
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering struct statvfs vfs;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering ssize_t n;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering if (fstatvfs(fd, &vfs) < 0) {
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering log_error_errno(errno, "Failed to stat file system of passed file, ignoring: %m");
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering return;
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering }
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering /* Refuse operating on file systems that have
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering * mandatory locking enabled, see:
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering *
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering * https://github.com/systemd/systemd/issues/1822
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering */
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering if (vfs.f_flag & ST_MANDLOCK) {
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering log_error("Received file descriptor from file system with mandatory locking enable, refusing.");
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering return;
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering }
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering /* Make the fd non-blocking. On regular files this has
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering * the effect of bypassing mandatory locking. Of
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering * course, this should normally not be necessary given
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering * the check above, but let's better be safe than
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering * sorry, after all NFS is pretty confusing regarding
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering * file system flags, and we better don't trust it,
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering * and so is SMB. */
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering r = fd_nonblock(fd, true);
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering if (r < 0) {
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering log_error_errno(r, "Failed to make fd non-blocking, ignoring: %m");
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering return;
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering }
1e603a482f57edb1fb863dbf23b868cf5854e004Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering /* The file is not sealed, we can't map the file here, since
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering * clients might then truncate it and trigger a SIGBUS for
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering * us. So let's stupidly read it */
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering p = malloc(st.st_size);
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering if (!p) {
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering log_oom();
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering return;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering }
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering n = pread(fd, p, st.st_size, 0);
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering if (n < 0)
c3753458fc30f35b7c2d2c5d5873198cd18131d8Michal Schmidt log_error_errno(errno, "Failed to read file, ignoring: %m");
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering else if (n > 0)
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering server_process_native_message(s, p, n, ucred, tv, label, label_len);
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering}
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poetteringint server_open_native_socket(Server*s) {
3b3154df7e2773332bb814e167187367a0ccae4aLennart Poettering static const int one = 1;
3b3154df7e2773332bb814e167187367a0ccae4aLennart Poettering int r;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering assert(s);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (s->native_fd < 0) {
f7a5bb2842037fa27dbc99d92c3fee7fe1bbbc2aZbigniew Jędrzejewski-Szmek union sockaddr_union sa = {
f7a5bb2842037fa27dbc99d92c3fee7fe1bbbc2aZbigniew Jędrzejewski-Szmek .un.sun_family = AF_UNIX,
f7a5bb2842037fa27dbc99d92c3fee7fe1bbbc2aZbigniew Jędrzejewski-Szmek .un.sun_path = "/run/systemd/journal/socket",
f7a5bb2842037fa27dbc99d92c3fee7fe1bbbc2aZbigniew Jędrzejewski-Szmek };
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering s->native_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt if (s->native_fd < 0)
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt return log_error_errno(errno, "socket() failed: %m");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering unlink(sa.un.sun_path);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering r = bind(s->native_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt if (r < 0)
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
4a61c3e51e96a747c30598d78ee3a24e7c569e9fZbigniew Jędrzejewski-Szmek (void) chmod(sa.un.sun_path, 0666);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering } else
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering fd_nonblock(s->native_fd, 1);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt if (r < 0)
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt return log_error_errno(errno, "SO_PASSCRED failed: %m");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering#ifdef HAVE_SELINUX
6355e75610a8d47fc3ba5ab8bd442172a2cfe574Lennart Poettering if (mac_selinux_have()) {
d682b3a7e7c7c2941a4d3e193f1e330dbc9fae89Lennart Poettering r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one));
d682b3a7e7c7c2941a4d3e193f1e330dbc9fae89Lennart Poettering if (r < 0)
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt log_warning_errno(errno, "SO_PASSSEC failed: %m");
d682b3a7e7c7c2941a4d3e193f1e330dbc9fae89Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering#endif
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering r = setsockopt(s->native_fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one));
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt if (r < 0)
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt return log_error_errno(errno, "SO_TIMESTAMP failed: %m");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
8531ae707d4d0203e83304d4af948b8169a5fce1Lennart Poettering r = sd_event_add_io(s->event, &s->native_event_source, s->native_fd, EPOLLIN, server_process_datagram, s);
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt if (r < 0)
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt return log_error_errno(r, "Failed to add native server fd to event loop: %m");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
48cef29504b1ffc0df9929f2d8b2af2ad74d2b4aVito Caputo r = sd_event_source_set_priority(s->native_event_source, SD_EVENT_PRIORITY_NORMAL+5);
48cef29504b1ffc0df9929f2d8b2af2ad74d2b4aVito Caputo if (r < 0)
48cef29504b1ffc0df9929f2d8b2af2ad74d2b4aVito Caputo return log_error_errno(r, "Failed to adjust native event source priority: %m");
48cef29504b1ffc0df9929f2d8b2af2ad74d2b4aVito Caputo
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return 0;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering}