Compare commits

...

4 Commits

Author SHA1 Message Date
Lorenz Bauer 09d0b46ab6 journal: refresh cached credentials of stdout streams
journald assumes that getsockopt(SO_PEERCRED) correctly identifies the
process on the remote end of the socket. However, this is incorrect
according to man 7 socket:

    The returned  credentials  are  those that were in effect at the
    time of the call to connect(2) or socketpair(2).

This becomes a problem when a new process inherits the stdout stream
from a parent. First, log messages from the child process will
be attributed to the parent. Second, the struct ucred used by journald
becomes invalid as soon as the parent exits. Further sendmsg calls then
fail with ENOENT. Logs for the child process then vanish from the journal.

Fix this by using recvmsg on the stdout stream, and refreshing the cached
struct ucred if SCM_CREDENTIALS indicate a new process.

Fixes #13708
2019-11-05 10:41:03 +01:00
Sebastian Wick d7d31692bf hwdb: add XKB_FIXED_MODEL to the keyboard hwdb
Chromebook keyboards have a top row which generates f1-f10 key codes but
the keys have media symbols printed on them. A simple scan code to key
code mapping to the correct media keys makes the f1-f10 inaccessible. To
properly use the keyboard a custom key code to symbol mapping in xbk is
required (a variant of the chromebook xkb model is already upstream).
Other devices have similar problems.
This commit makes it possible to specify which xkb model should be used
for a specific device by setting XKB_FIXED_MODEL.
2019-11-05 10:08:26 +01:00
Anita Zhang d36b573ef7
Merge pull request #13935 from poettering/bootctl-random-seed-mkdir
bootctl: create leading dirs when "bootctl random-seed" is called if …
2019-11-04 22:57:12 -08:00
Lennart Poettering a4a55e9ace bootctl: create leading dirs when "bootctl random-seed" is called if needed
Prompted by: #13603
2019-11-04 14:26:53 +01:00
5 changed files with 89 additions and 18 deletions

View File

@ -75,7 +75,13 @@
# XKB_FIXED_VARIANT="" # XKB_FIXED_VARIANT=""
# Examples of such devices: the Yubikey or other key-code generating # Examples of such devices: the Yubikey or other key-code generating
# devices. # devices.
#
# A device where the scan code to key code mapping is insufficient and
# requires a special key code to symbol configuration may specify that with:
# XKB_FIXED_MODEL="xkbmodel"
# Examples of such devices: Chromebooks where the top row is used for both
# media and F1-F10 keys.
# To update this file, create a new file # To update this file, create a new file
# /etc/udev/hwdb.d/70-keyboard.hwdb # /etc/udev/hwdb.d/70-keyboard.hwdb
# and add your rules there. To load the new rules execute (as root): # and add your rules there. To load the new rules execute (as root):
@ -569,21 +575,6 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHDX9494NR:pvr*
KEYBOARD_KEY_d8=!f23 # touchpad off KEYBOARD_KEY_d8=!f23 # touchpad off
KEYBOARD_KEY_d9=!f22 # touchpad on KEYBOARD_KEY_d9=!f22 # touchpad on
# Chromebook 14
# Top row keys (between ESC and power button)
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnFalco:pvr*
KEYBOARD_KEY_3b=back
KEYBOARD_KEY_3c=forward
KEYBOARD_KEY_3d=refresh
KEYBOARD_KEY_3f=switchvideomode
KEYBOARD_KEY_40=brightnessdown
KEYBOARD_KEY_41=brightnessup
KEYBOARD_KEY_42=mute
KEYBOARD_KEY_43=volumedown
KEYBOARD_KEY_44=volumeup
KEYBOARD_KEY_db=search # Same position as caps lock key on most keyboards
# KEYBOARD_KEY_3e=fullscreen, no defined key sym
# HP EliteBook 725 G2 # HP EliteBook 725 G2
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPLicrice:pvr* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPLicrice:pvr*
# HP ProBook 440 G2 # HP ProBook 440 G2
@ -1733,3 +1724,13 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadT560s
# Lenovo ThinkPad X1 Carbon 3rd Gen # Lenovo ThinkPad X1 Carbon 3rd Gen
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadX1Carbon3rd evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadX1Carbon3rd
KEYBOARD_LED_CAPSLOCK=0 KEYBOARD_LED_CAPSLOCK=0
######################### FIXED MODEL DEVICES #############################
# This section lists devices which require special handling in their key
# code to keysym mapping by setting the xkb model.
# The model must be an xkb compatible model (defined with XKB_FIXED_MODEL).
# Chromebooks
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnFalco:pvr*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnPeppy:pvr*
XKB_FIXED_MODEL="chromebook"

View File

@ -123,6 +123,7 @@ def property_grammar():
('ID_INPUT_TOUCHPAD_INTEGRATION', Or(('internal', 'external'))), ('ID_INPUT_TOUCHPAD_INTEGRATION', Or(('internal', 'external'))),
('XKB_FIXED_LAYOUT', STRING), ('XKB_FIXED_LAYOUT', STRING),
('XKB_FIXED_VARIANT', STRING), ('XKB_FIXED_VARIANT', STRING),
('XKB_FIXED_MODEL', STRING),
('KEYBOARD_LED_NUMLOCK', Literal('0')), ('KEYBOARD_LED_NUMLOCK', Literal('0')),
('KEYBOARD_LED_CAPSLOCK', Literal('0')), ('KEYBOARD_LED_CAPSLOCK', Literal('0')),
('ACCEL_MOUNT_MATRIX', mount_matrix), ('ACCEL_MOUNT_MATRIX', mount_matrix),

View File

@ -27,6 +27,7 @@
#include "fs-util.h" #include "fs-util.h"
#include "locale-util.h" #include "locale-util.h"
#include "main-func.h" #include "main-func.h"
#include "mkdir.h"
#include "pager.h" #include "pager.h"
#include "parse-util.h" #include "parse-util.h"
#include "pretty-print.h" #include "pretty-print.h"
@ -1364,6 +1365,13 @@ static int install_random_seed(const char *esp) {
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to acquire random seed: %m"); return log_error_errno(r, "Failed to acquire random seed: %m");
/* Normally create_subdirs() should already have created everything we need, but in case "bootctl
* random-seed" is called we want to just create the minimum we need for it, and not the full
* list. */
r = mkdir_parents(path, 0755);
if (r < 0)
return log_error_errno(r, "Failed to create parent directory for %s: %m", path);
r = tempfn_random(path, "bootctl", &tmp); r = tempfn_random(path, "bootctl", &tmp);
if (r < 0) if (r < 0)
return log_oom(); return log_oom();

View File

@ -487,11 +487,22 @@ static int stdout_stream_scan(StdoutStream *s, bool force_flush) {
} }
static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, void *userdata) { static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
StdoutStream *s = userdata; StdoutStream *s = userdata;
struct ucred *ucred = NULL;
struct cmsghdr *cmsg;
struct iovec iovec;
size_t limit; size_t limit;
ssize_t l; ssize_t l;
int r; int r;
struct msghdr msghdr = {
.msg_iov = &iovec,
.msg_iovlen = 1,
.msg_control = buf,
.msg_controllen = sizeof(buf),
};
assert(s); assert(s);
if ((revents|EPOLLIN|EPOLLHUP) != (EPOLLIN|EPOLLHUP)) { if ((revents|EPOLLIN|EPOLLHUP) != (EPOLLIN|EPOLLHUP)) {
@ -511,20 +522,50 @@ static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents,
* always leave room for a terminating NUL we might need to add. */ * always leave room for a terminating NUL we might need to add. */
limit = MIN(s->allocated - 1, s->server->line_max); limit = MIN(s->allocated - 1, s->server->line_max);
l = read(s->fd, s->buffer + s->length, limit - s->length); iovec = IOVEC_MAKE(s->buffer + s->length, limit - s->length);
l = recvmsg(s->fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
if (l < 0) { if (l < 0) {
if (errno == EAGAIN) if (IN_SET(errno, EINTR, EAGAIN))
return 0; return 0;
log_warning_errno(errno, "Failed to read from stream: %m"); log_warning_errno(errno, "Failed to read from stream: %m");
goto terminate; goto terminate;
} }
cmsg_close_all(&msghdr);
if (l == 0) { if (l == 0) {
stdout_stream_scan(s, true); stdout_stream_scan(s, true);
goto terminate; goto terminate;
} }
CMSG_FOREACH(cmsg, &msghdr)
if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_CREDENTIALS &&
cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
ucred = (struct ucred *)CMSG_DATA(cmsg);
break;
}
/* Invalidate the context if the pid of the sender changed.
* This happens when a forked process inherits stdout / stderr
* from a parent. In this case getpeercred returns the ucred
* of the parent, which can be invalid if the parent has exited
* in the meantime.
*/
if (ucred && ucred->pid != s->ucred.pid) {
/* force out any previously half-written lines from a
* different process, before we switch to the new ucred
* structure for everything we just added */
r = stdout_stream_scan(s, true);
if (r < 0)
goto terminate;
s->ucred = *ucred;
client_context_release(s->server, s->context);
s->context = NULL;
}
s->length += l; s->length += l;
r = stdout_stream_scan(s, false); r = stdout_stream_scan(s, false);
if (r < 0) if (r < 0)
@ -562,6 +603,10 @@ int stdout_stream_install(Server *s, int fd, StdoutStream **ret) {
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to determine peer credentials: %m"); return log_error_errno(r, "Failed to determine peer credentials: %m");
r = setsockopt_int(fd, SOL_SOCKET, SO_PASSCRED, true);
if (r < 0)
return log_error_errno(r, "SO_PASSCRED failed: %m");
if (mac_selinux_use()) { if (mac_selinux_use()) {
r = getpeersec(fd, &stream->label); r = getpeersec(fd, &stream->label);
if (r < 0 && r != -EOPNOTSUPP) if (r < 0 && r != -EOPNOTSUPP)

View File

@ -74,6 +74,22 @@ cmp /expected /output
{ journalctl -ball -b -m 2>&1 || :; } | head -1 > /output { journalctl -ball -b -m 2>&1 || :; } | head -1 > /output
cmp /expected /output cmp /expected /output
# https://github.com/systemd/systemd/issues/13708
ID=$(systemd-id128 new)
systemd-cat -t "$ID" bash -c 'echo parent; (echo child) & wait' &
PID=$!
wait %%
journalctl --sync
# We can drop this grep when https://github.com/systemd/systemd/issues/13937
# has a fix.
journalctl -b -o export -t "$ID" --output-fields=_PID | grep '^_PID=' >/output
[[ `grep -c . /output` -eq 2 ]]
grep -q "^_PID=$PID" /output
grep -vq "^_PID=$PID" /output
# Add new tests before here, the journald restarts below
# may make tests flappy.
# Don't lose streams on restart # Don't lose streams on restart
systemctl start forever-print-hola systemctl start forever-print-hola
sleep 3 sleep 3