Skip to content

Commit 0ad825a

Browse files
Drop CAP_NET_BIND_SERVICE after binding mctpd
Signed-off-by: James Lee <james@codeconstruct.com.au>
1 parent f1f6733 commit 0ad825a

2 files changed

Lines changed: 56 additions & 10 deletions

File tree

meson.build

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ add_project_arguments('-Wno-unused-parameter', language : 'c')
1616

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

19+
libcap = dependency('libcap', version: '>=2.77', required: false)
20+
1921
conf = configuration_data()
2022
conf.set10('HAVE_LINUX_MCTP_H',
2123
cc.has_header('linux/mctp.h'),
@@ -84,12 +86,12 @@ executable('mctp-client',
8486
install: true
8587
)
8688

87-
if libsystemd.found()
89+
if libsystemd.found() and libcap.found()
8890
executable('mctpd',
8991
sources: [
9092
'src/mctpd.c',
9193
] + netlink_sources + util_sources + ops_sources,
92-
dependencies: [libsystemd, toml_dep],
94+
dependencies: [libsystemd, toml_dep, libcap],
9395
install: true,
9496
install_dir: get_option('sbindir'),
9597
c_args: ['-DOPS_SD_EVENT=1'],
@@ -100,7 +102,7 @@ if libsystemd.found()
100102
'src/mctpd.c',
101103
] + test_ops_sources + netlink_sources + util_sources,
102104
include_directories: include_directories('src'),
103-
dependencies: [libsystemd, toml_dep],
105+
dependencies: [libsystemd, toml_dep, libcap],
104106
c_args: ['-DOPS_SD_EVENT=1'],
105107
)
106108
endif
@@ -154,7 +156,7 @@ if tests
154156
sh = find_program('sh')
155157
test_args = [ '-c', script, '--' ]
156158

157-
if libsystemd.found()
159+
if libsystemd.found() and libcap.found()
158160
dbus_run_session = find_program('dbus-run-session')
159161

160162
test('test-mctpd', dbus_run_session,

src/mctpd.c

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
* Copyright (c) 2021 Google
77
*/
88

9+
#include "linux/capability.h"
10+
#include <stddef.h>
911
#define _GNU_SOURCE
1012
#include "config.h"
1113

@@ -14,6 +16,7 @@
1416
#include <time.h>
1517

1618
#include <sys/socket.h>
19+
#include <sys/capability.h>
1720
#include <arpa/inet.h>
1821
#include <stdint.h>
1922
#include <stdio.h>
@@ -1441,14 +1444,19 @@ static int cb_listen_control_msg(sd_event_source *s, int sd, uint32_t revents,
14411444

14421445
static int listen_control_msg(struct ctx *ctx, uint32_t net)
14431446
{
1447+
cap_flag_t dropped_sets[] = { CAP_EFFECTIVE, CAP_INHERITABLE,
1448+
CAP_PERMITTED };
1449+
cap_value_t dropped_capability[] = { CAP_NET_BIND_SERVICE };
14441450
struct sockaddr_mctp addr = { 0 };
14451451
int rc, sd = -1, val;
1452+
char *failed;
1453+
cap_t cap;
1454+
size_t i;
14461455

14471456
sd = mctp_ops.mctp.socket();
14481457
if (sd < 0) {
1449-
rc = -errno;
1450-
warn("%s: socket() failed", __func__);
1451-
goto out;
1458+
failed = "socket()";
1459+
goto warn_out;
14521460
}
14531461

14541462
addr.smctp_family = AF_MCTP;
@@ -1459,9 +1467,35 @@ static int listen_control_msg(struct ctx *ctx, uint32_t net)
14591467

14601468
rc = mctp_ops.mctp.bind(sd, (struct sockaddr *)&addr, sizeof(addr));
14611469
if (rc < 0) {
1462-
rc = -errno;
1463-
warn("%s: bind() failed", __func__);
1464-
goto out;
1470+
failed = "bind()";
1471+
goto warn_out;
1472+
}
1473+
1474+
cap = cap_get_proc();
1475+
if (!cap) {
1476+
failed = "cap_get_proc()";
1477+
goto warn_out;
1478+
}
1479+
1480+
for (i = 0; i < ARRAY_SIZE(dropped_sets); i++) {
1481+
rc = cap_set_flag(cap, dropped_sets[i], 1, dropped_capability,
1482+
CAP_CLEAR);
1483+
if (rc < 0) {
1484+
failed = "cap_clear_flag()";
1485+
goto cap_out;
1486+
}
1487+
}
1488+
1489+
rc = cap_set_proc(cap);
1490+
if (rc < 0) {
1491+
failed = "cap_set_proc()";
1492+
goto cap_out;
1493+
}
1494+
1495+
cap_free(cap);
1496+
if (rc < 0) {
1497+
failed = "cap_free()";
1498+
goto warn_out;
14651499
}
14661500

14671501
val = 1;
@@ -1476,6 +1510,16 @@ static int listen_control_msg(struct ctx *ctx, uint32_t net)
14761510
rc = sd_event_add_io(ctx->event, NULL, sd, EPOLLIN,
14771511
cb_listen_control_msg, ctx);
14781512
return rc;
1513+
1514+
cap_out:
1515+
rc = -errno;
1516+
warn("%s: %s failed", __func__, failed);
1517+
cap_free(cap);
1518+
goto out;
1519+
1520+
warn_out:
1521+
rc = -errno;
1522+
warn("%s: %s failed", __func__, failed);
14791523
out:
14801524
if (rc < 0) {
14811525
close(sd);

0 commit comments

Comments
 (0)