Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion conf/mctpd-dbus.conf
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,33 @@
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<policy context="default">
<deny send_destination="au.com.codeconstruct.MCTP1">

<allow receive_sender="au.com.codeconstruct.MCTP1"/>

<allow send_destination="au.com.codeconstruct.MCTP1"
send_interface="org.freedesktop.DBus.Propeties"
send_member="Get"/>

<allow send_destination="au.com.codeconstruct.MCTP1"
send_interface="org.freedesktop.DBus.Propeties"
send_member="GetAll"/>

<allow send_destination="au.com.codeconstruct.MCTP1"
send_interface="org.freedesktop.DBus.Introspectable"/>

<allow send_destination="au.com.codeconstruct.MCTP1"
send_interface="org.freedesktop.DBus.ObjectManager"/>
</policy>
<policy user="mctpd">
<allow own="au.com.codeconstruct.MCTP1"/>
</policy>
<policy group="mctp-admin">
<allow send_destination="au.com.codeconstruct.MCTP1"/>
</policy>
<policy user="root">
<allow own="au.com.codeconstruct.MCTP1"/>
<allow send_destination="au.com.codeconstruct.MCTP1"/>
<allow receive_sender="au.com.codeconstruct.MCTP1"/>
</policy>
</busconfig>
2 changes: 2 additions & 0 deletions conf/mctpd.service
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ After=mctp-local.target
Type=dbus
BusName=au.com.codeconstruct.MCTP1
ExecStart=/usr/sbin/mctpd
User=mctpd
AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_NET_ADMIN

[Install]
WantedBy=mctp.target
12 changes: 12 additions & 0 deletions docs/mctpd.md
Original file line number Diff line number Diff line change
Expand Up @@ -503,3 +503,15 @@ match = { path = "/devices/pci0000:00/0000:00:08.3/*" }
```

Paths have the `/sys` prefix stripped.

## Capabilities

`mctpd` requires the `CAP_NET_BIND_SERVICE` and `CAP_NET_ADMIN` capabilites to run.
If the service is not running as root these should be added to the `AmbientCapabilities` setting in the service's config.
If the target platform has the `libcap` library available,
the `mctpd` process will drop all other capabilities,
only keeping the necessary capabilities in the effective set as needed.

Because `mctpd` is must be a privileged process that is exposed to potentially hostile inputs,
it shouldn't be given more capabilities than necessary.
`mctpd` will emit a warning while starting on target platforms that do not have `libcap`.
10 changes: 8 additions & 2 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ add_project_arguments('-Wno-unused-parameter', language : 'c')

libsystemd = dependency('libsystemd', version: '>=247', required: false)

libcap = dependency('libcap', required: false)

conf = configuration_data()
conf.set10('HAVE_LINUX_MCTP_H',
cc.has_header('linux/mctp.h'),
Expand All @@ -37,6 +39,10 @@ conf.set10('MCTPD_WRITABLE_CONNECTIVITY',
get_option('unsafe-writable-connectivity'),
description: 'Allow writes to the Connectivity member of the au.com.codeconstruct.MCTP.Endpoint1 interface on endpoint objects')

conf.set10('MCTPD_MANAGE_CAPABILITIES',
libcap.found(),
description: 'Require mctpd to minimise its capabilities (emits warning on start if false)')

conf.set_quoted('MCTPD_CONF_FILE_DEFAULT',
join_paths(get_option('prefix'), get_option('sysconfdir'), 'mctpd.conf'),
description: 'Default configuration file path',
Expand Down Expand Up @@ -89,7 +95,7 @@ if libsystemd.found()
sources: [
'src/mctpd.c',
] + netlink_sources + util_sources + ops_sources,
dependencies: [libsystemd, toml_dep],
dependencies: [libsystemd, toml_dep, libcap],
install: true,
install_dir: get_option('sbindir'),
c_args: ['-DOPS_SD_EVENT=1'],
Expand All @@ -100,7 +106,7 @@ if libsystemd.found()
'src/mctpd.c',
] + test_ops_sources + netlink_sources + util_sources,
include_directories: include_directories('src'),
dependencies: [libsystemd, toml_dep],
dependencies: [libsystemd, toml_dep, libcap],
c_args: ['-DOPS_SD_EVENT=1'],
)
endif
Expand Down
53 changes: 53 additions & 0 deletions src/mctpd.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
#define _GNU_SOURCE
#include "config.h"

#if MCTPD_MANAGE_CAPABILITIES
#include <sys/capability.h>
#endif

#include <assert.h>
#include <systemd/sd-bus-vtable.h>
#include <time.h>
Expand Down Expand Up @@ -6342,13 +6346,54 @@ static int endpoint_allocate_eids(struct peer *peer)
return 0;
}

int set_cap(char *str)
{
#if MCTPD_MANAGE_CAPABILITIES
cap_t cap = cap_from_text(str);
int rc;

if (!cap) {
rc = -errno;
warnx("Failed allocating capability state: %s, %s %d", str,
strerror(-rc), rc);
return rc;
}

rc = cap_set_proc(cap);
if (rc < 0) {
rc = -errno;
warnx("Could not set capabilites: %s, %s %d", str,
strerror(-rc), rc);
return rc;
}

rc = cap_free(cap);
if (rc < 0) {
rc = -errno;
warnx("Failed freeing capability state");
return rc;
}
return 0;
#else
return 0;
#endif
}

int main(int argc, char **argv)
{
struct ctx ctxi = { 0 }, *ctx = &ctxi;
int rc;

setlinebuf(stdout);

#if !MCTPD_MANAGE_CAPABILITIES
warnx("mctpd has been compiled without capability management and will not drop capabilities");
#endif

rc = set_cap("CAP_NET_BIND_SERVICE=p CAP_NET_ADMIN=p");
if (rc < 0)
return 1;

setup_config_defaults(ctx);
setup_ctrl_cmd_defaults(ctx);

Expand Down Expand Up @@ -6390,13 +6435,21 @@ int main(int argc, char **argv)
if (rc < 0)
return 1;

rc = set_cap("CAP_NET_BIND_SERVICE=pe CAP_NET_ADMIN=p");
if (rc < 0)
return 1;

// TODO add net argument?
rc = listen_control_msg(ctx, MCTP_NET_ANY);
if (rc < 0) {
warnx("Error in listen, returned %s %d", strerror(-rc), rc);
return 1;
}

rc = set_cap("CAP_NET_ADMIN=pe");
if (rc < 0)
return 1;

// All setup must be complete by here, we might immediately
// get requests from waiting clients.
rc = request_dbus(ctx);
Expand Down
Loading