From: David Michael Date: Fri, 25 Oct 2024 14:45:44 +0000 (-0400) Subject: socket: support setting ownership of message queues X-Git-Tag: v257-rc1~124 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3eec82f6b31b22e1d9fe60ff47e1e6193fd4bb36;p=thirdparty%2Fsystemd.git socket: support setting ownership of message queues This applies the existing SocketUser=/SocketGroup= options to units defining a POSIX message queue, bringing them in line with UNIX sockets and FIFOs. They are set on the file descriptor rather than a file system path because the /dev/mqueue path interface is an optional mount unit. --- diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml index e9fd39bf7f2..bbcd7f051a3 100644 --- a/man/systemd.socket.xml +++ b/man/systemd.socket.xml @@ -375,7 +375,7 @@ SocketGroup= Takes a UNIX user/group name. When specified, all AF_UNIX - sockets and FIFO nodes in the file system are owned by the specified user and group. If unset (the + sockets, FIFO nodes, and message queues are owned by the specified user and group. If unset (the default), the nodes are owned by the root user/group (if run in system context) or the invoking user/group (if run in user context). If only a user is specified but no group, then the group is derived from the user's default group. @@ -385,10 +385,9 @@ SocketMode= - If listening on a file system socket or FIFO, - this option specifies the file system access mode used when - creating the file node. Takes an access mode in octal - notation. Defaults to 0666. + If listening on a file system socket, FIFO, or message queue, this option specifies + the file system access mode used when creating the file node. Takes an access mode in octal notation. + Defaults to 0666. diff --git a/src/core/socket.c b/src/core/socket.c index 8519aefa689..fce50e28e4f 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -2024,6 +2024,14 @@ static int socket_chown(Socket *s, PidRef *ret_pid) { path = socket_address_get_path(&p->address); else if (p->type == SOCKET_FIFO) path = p->path; + else if (p->type == SOCKET_MQUEUE) { + /* Use fchown on the fd since /dev/mqueue might not be mounted. */ + if (fchown(p->fd, uid, gid) < 0) { + log_unit_error_errno(UNIT(s), errno, "Failed to fchown(): %m"); + _exit(EXIT_CHOWN); + } + continue; + } if (!path) continue; diff --git a/test/units/TEST-07-PID1.mqueue-ownership.sh b/test/units/TEST-07-PID1.mqueue-ownership.sh new file mode 100755 index 00000000000..19116d19d13 --- /dev/null +++ b/test/units/TEST-07-PID1.mqueue-ownership.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later +set -eux +set -o pipefail + +# Verify ownership attributes are applied to message queues + +# Select arbitrary non-default attributes to apply to the queue. +queue=/attr_q # Pick any unused queue name. +user=nobody # Choose a core system user. +group=adm # Choose a core system group. +mode=0420 # Allow the owner to read messages and anyone in the group to write. + +at_exit() { + set +e + systemctl stop mqueue-ownership.{service,socket} + rm -f /run/systemd/system/mqueue-ownership.{service,socket} + systemctl daemon-reload +} +trap at_exit EXIT + +cat << EOF > /run/systemd/system/mqueue-ownership.socket +[Unit] +Description=Create a message queue with customized ownership +[Socket] +ListenMessageQueue=/${queue#/} +RemoveOnStop=true +SocketUser=$user +SocketGroup=$group +SocketMode=$mode +EOF + +cat << 'EOF' > /run/systemd/system/mqueue-ownership.service +[Unit] +Description=Dummy service for the socket unit +Requires=%N.socket +[Service] +ExecStart=/usr/bin/true +Type=oneshot +EOF + +systemctl daemon-reload +systemctl start mqueue-ownership.socket + +systemctl start dev-mqueue.mount # Ensure this file path interface is mounted. +[[ $(stat -c '%04a %U %G' "/dev/mqueue/${queue#/}") == "$mode $user $group" ]]