From 34535dace9f0eacd4d01c3694edfe3a37e28c35c Mon Sep 17 00:00:00 2001 From: Mariusz Zaborski Date: Sun, 3 Jan 2021 17:10:35 +0100 Subject: [PATCH] cap_net: CAPNET_CONNECT and CAPNET_CONNECTDNS are not mutually exclusive Fix the for the CAPNET_CONNECT and CAPNET_CONNECTDNS. Add test to ensure that this is possible. --- lib/libcasper/services/cap_net/cap_net.c | 18 +++++++--- .../services/cap_net/tests/net_test.c | 33 +++++++++++++++++++ 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/lib/libcasper/services/cap_net/cap_net.c b/lib/libcasper/services/cap_net/cap_net.c index a963c753494b..1d5531676268 100644 --- a/lib/libcasper/services/cap_net/cap_net.c +++ b/lib/libcasper/services/cap_net/cap_net.c @@ -1058,7 +1058,7 @@ net_connect(const nvlist_t *limits, nvlist_t *nvlin, nvlist_t *nvlout) const void *saddr; const nvlist_t *funclimit; size_t len; - bool conn, conndns; + bool conn, conndns, allowed; conn = net_allowed_mode(limits, CAPNET_CONNECT); conndns = net_allowed_mode(limits, CAPNET_CONNECTDNS); @@ -1071,12 +1071,20 @@ net_connect(const nvlist_t *limits, nvlist_t *nvlin, nvlist_t *nvlout) funclimit = dnvlist_get_nvlist(limits, LIMIT_NV_CONNECT, NULL); saddr = nvlist_get_binary(nvlin, "saddr", &len); - if (conn && !net_allowed_bsaddr(funclimit, saddr, len)) { - return (ENOTCAPABLE); - } else if (conndns && (capdnscache == NULL || - !net_allowed_bsaddr_impl(capdnscache, saddr, len))) { + allowed = false; + + if (conn && net_allowed_bsaddr(funclimit, saddr, len)) { + allowed = true; + } + if (conndns && capdnscache != NULL && + net_allowed_bsaddr_impl(capdnscache, saddr, len)) { + allowed = true; + } + + if (allowed == false) { return (ENOTCAPABLE); } + socket = dup(nvlist_get_descriptor(nvlin, "s")); if (connect(socket, saddr, len) < 0) { serrno = errno; diff --git a/lib/libcasper/services/cap_net/tests/net_test.c b/lib/libcasper/services/cap_net/tests/net_test.c index c2dce467ef3b..49cb0da44a4e 100644 --- a/lib/libcasper/services/cap_net/tests/net_test.c +++ b/lib/libcasper/services/cap_net/tests/net_test.c @@ -1068,6 +1068,38 @@ ATF_TC_BODY(capnet__limits_connect_mode, tc) cap_close(capnet); } +ATF_TC_WITHOUT_HEAD(capnet__limits_connect_dns_mode); +ATF_TC_BODY(capnet__limits_connect_dns_mode, tc) +{ + cap_channel_t *capnet; + cap_net_limit_t *limit; + + capnet = create_network_service(); + + /* LIMIT */ + limit = cap_net_limit_init(capnet, CAPNET_CONNECT | CAPNET_CONNECTDNS); + ATF_REQUIRE(limit != NULL); + ATF_REQUIRE(cap_net_limit(limit) == 0); + + /* ALLOWED */ + ATF_REQUIRE(test_connect(capnet, TEST_IPV4, 80) == 0); + + /* DISALLOWED */ + ATF_REQUIRE( + test_gethostbyname(capnet, AF_INET, TEST_DOMAIN_0) == ENOTCAPABLE); + ATF_REQUIRE(test_getnameinfo(capnet, AF_INET, TEST_IPV4) == + ENOTCAPABLE); + ATF_REQUIRE(test_gethostbyaddr(capnet, AF_INET, TEST_IPV4) == + ENOTCAPABLE); + ATF_REQUIRE(test_getaddrinfo(capnet, AF_INET, TEST_DOMAIN_0, NULL) == + ENOTCAPABLE); + ATF_REQUIRE(test_bind(capnet, TEST_BIND_IPV4) == ENOTCAPABLE); + + test_extend_mode(capnet, CAPNET_ADDR2NAME); + + cap_close(capnet); +} + ATF_TC_WITHOUT_HEAD(capnet__limits_connect); ATF_TC_BODY(capnet__limits_connect, tc) { @@ -1238,6 +1270,7 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, capnet__limits_bind); ATF_TP_ADD_TC(tp, capnet__limits_connect_mode); + ATF_TP_ADD_TC(tp, capnet__limits_connect_dns_mode); ATF_TP_ADD_TC(tp, capnet__limits_connect); ATF_TP_ADD_TC(tp, capnet__limits_connecttodns);