summaryrefslogtreecommitdiffhomepage
path: root/test/syscalls
diff options
context:
space:
mode:
authorKevin Krakauer <krakauer@google.com>2020-08-27 10:51:59 -0700
committerAndrei Vagin <avagin@gmail.com>2020-09-09 17:53:10 -0700
commit97d6398d435025c7ab361c36994feab2c7e2d84f (patch)
treeebdca9785e7de4d6a9148b824f0b1d6b232c4fb0 /test/syscalls
parent5588def369a09b4525842b04a43fbf146e662311 (diff)
ip6tables: (de)serialize ip6tables structs
More implementation+testing to follow. #3549. PiperOrigin-RevId: 328770160
Diffstat (limited to 'test/syscalls')
-rw-r--r--test/syscalls/linux/ip6tables.cc48
1 files changed, 48 insertions, 0 deletions
diff --git a/test/syscalls/linux/ip6tables.cc b/test/syscalls/linux/ip6tables.cc
index 685e513f8..78e1fa09d 100644
--- a/test/syscalls/linux/ip6tables.cc
+++ b/test/syscalls/linux/ip6tables.cc
@@ -34,6 +34,54 @@ constexpr size_t kEmptyStandardEntrySize =
constexpr size_t kEmptyErrorEntrySize =
sizeof(struct ip6t_entry) + sizeof(struct xt_error_target);
+TEST(IP6TablesBasic, FailSockoptNonRaw) {
+ // Even if the user has CAP_NET_RAW, they shouldn't be able to use the
+ // ip6tables sockopts with a non-raw socket.
+ SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW)));
+
+ int sock;
+ ASSERT_THAT(sock = socket(AF_INET6, SOCK_DGRAM, 0), SyscallSucceeds());
+
+ struct ipt_getinfo info = {};
+ snprintf(info.name, XT_TABLE_MAXNAMELEN, "%s", kNatTablename);
+ socklen_t info_size = sizeof(info);
+ EXPECT_THAT(getsockopt(sock, SOL_IPV6, IP6T_SO_GET_INFO, &info, &info_size),
+ SyscallFailsWithErrno(ENOPROTOOPT));
+
+ EXPECT_THAT(close(sock), SyscallSucceeds());
+}
+
+TEST(IP6TablesBasic, GetInfoErrorPrecedence) {
+ SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW)));
+
+ int sock;
+ ASSERT_THAT(sock = socket(AF_INET6, SOCK_DGRAM, 0), SyscallSucceeds());
+
+ // When using the wrong type of socket and a too-short optlen, we should get
+ // EINVAL.
+ struct ipt_getinfo info = {};
+ snprintf(info.name, XT_TABLE_MAXNAMELEN, "%s", kNatTablename);
+ socklen_t info_size = sizeof(info) - 1;
+ EXPECT_THAT(getsockopt(sock, SOL_IPV6, IP6T_SO_GET_INFO, &info, &info_size),
+ SyscallFailsWithErrno(EINVAL));
+}
+
+TEST(IP6TablesBasic, GetEntriesErrorPrecedence) {
+ SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW)));
+
+ int sock;
+ ASSERT_THAT(sock = socket(AF_INET6, SOCK_DGRAM, 0), SyscallSucceeds());
+
+ // When using the wrong type of socket and a too-short optlen, we should get
+ // EINVAL.
+ struct ip6t_get_entries entries = {};
+ socklen_t entries_size = sizeof(struct ip6t_get_entries) - 1;
+ snprintf(entries.name, XT_TABLE_MAXNAMELEN, "%s", kNatTablename);
+ EXPECT_THAT(
+ getsockopt(sock, SOL_IPV6, IP6T_SO_GET_ENTRIES, &entries, &entries_size),
+ SyscallFailsWithErrno(EINVAL));
+}
+
// This tests the initial state of a machine with empty ip6tables via
// getsockopt(IP6T_SO_GET_INFO). We don't have a guarantee that the iptables are
// empty when running in native, but we can test that gVisor has the same