blob: 0190ed39788b039f6772c4023d20698278190204 [file] [log] [blame]
Pierre Imai904ce3a2016-02-18 13:13:12 +09001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
Lorenzo Colitti93a0d642019-06-26 22:31:03 +090010 * Unless required by applicable law or agreed to in writing, software
Pierre Imai904ce3a2016-02-18 13:13:12 +090011 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
Maciej Żenczykowski9ce7e662020-05-29 00:41:22 -070018#include <arpa/inet.h>
Pierre Imai904ce3a2016-02-18 13:13:12 +090019#include <errno.h>
Maciej Żenczykowski9ce7e662020-05-29 00:41:22 -070020#include <linux/if_packet.h>
21#include <linux/if_tun.h>
22#include <net/if.h>
23#include <poll.h>
Maciej Żenczykowski7b242462020-05-13 20:53:10 -070024#include <sched.h>
Chenbo Feng66165472018-07-23 19:05:56 -070025#include <sys/capability.h>
Maciej Żenczykowski9ce7e662020-05-29 00:41:22 -070026#include <sys/ioctl.h>
27#include <sys/socket.h>
28#include <sys/types.h>
Pierre Imai904ce3a2016-02-18 13:13:12 +090029
30#include <gtest/gtest.h>
Pierre Imaibeedec32016-04-13 06:44:51 +090031
Maciej Żenczykowski438c0912022-07-15 03:47:38 -070032#include <android-base/stringprintf.h>
Maciej Żenczykowski9ce7e662020-05-29 00:41:22 -070033#include <android-base/unique_fd.h>
34
35#define LOG_TAG "NetdTest"
Maciej Żenczykowski9ce7e662020-05-29 00:41:22 -070036
Patrick Rohr70d42502021-10-12 18:24:10 +020037#include "TcUtils.h"
Maciej Żenczykowski9ce7e662020-05-29 00:41:22 -070038
39namespace android {
40namespace net {
41
42using base::unique_fd;
43
Chenbo Feng66165472018-07-23 19:05:56 -070044TEST(NetUtilsWrapperTest, TestFileCapabilities) {
45 errno = 0;
46 ASSERT_EQ(NULL, cap_get_file("/system/bin/netutils-wrapper-1.0"));
47 ASSERT_EQ(ENODATA, errno);
48}
Maciej Żenczykowski5a914822019-05-02 21:57:10 -070049
Maciej Żenczykowski02a8e172021-06-08 21:18:37 -070050// If this test fails most likely your device is lacking device/oem specific
51// selinux genfscon rules, something like .../vendor/.../genfs_contexts:
52// genfscon sysfs /devices/platform/.../net u:object_r:sysfs_net:s0
53// Easiest debugging is via:
54// adb root && sleep 1 && adb shell 'ls -Z /sys/class/net/*/mtu'
55// and look for the mislabeled item(s).
56// Everything should be 'u:object_r:sysfs_net:s0'
57//
58// Another useful command is:
59// adb root && sleep 1 && adb shell find /sys > dump.out
60// or in particular:
61// adb root && sleep 1 && adb shell find /sys | egrep '/net$'
62// which might (among other things) print out something like:
63// /sys/devices/platform/11110000.usb/11110000.dwc3/gadget/net
64// which means you need to add:
65// genfscon sysfs /devices/platform/11110000.usb/11110000.dwc3/gadget/net u:object_r:sysfs_net:s0
Maciej Żenczykowski5a914822019-05-02 21:57:10 -070066TEST(NetdSELinuxTest, CheckProperMTULabels) {
67 // Since we expect the egrep regexp to filter everything out,
68 // we thus expect no matches and thus a return code of 1
69 // NOLINTNEXTLINE(cert-env33-c)
70 ASSERT_EQ(W_EXITCODE(1, 0), system("ls -Z /sys/class/net/*/mtu | egrep -q -v "
71 "'^u:object_r:sysfs_net:s0 /sys/class/net/'"));
72}
Maciej Żenczykowski7b242462020-05-13 20:53:10 -070073
Maciej Żenczykowski438c0912022-07-15 03:47:38 -070074static void assertBpfContext(const char* const target, const char* const label) {
75 // Use 'ls' cli utility to print the selinux context of the target directory or file.
76 // egrep -q will return 0 if it matches, ie. if the selinux context is as expected
77 std::string cmd = android::base::StringPrintf("ls -dZ %s | egrep -q '^u:object_r:%s:s0 %s$'",
78 target, label, target);
79
80 // NOLINTNEXTLINE(cert-env33-c)
Maciej Żenczykowski53194142022-11-24 10:12:47 +000081 ASSERT_EQ(W_EXITCODE(0, 0), system(cmd.c_str())) << cmd << " - did not return success(0)"
82 " - is kernel missing https://android-review.googlesource.com/c/kernel/common/+/1831252"
83 " 'UPSTREAM: security: selinux: allow per-file labeling for bpffs' ?";
Maciej Żenczykowski438c0912022-07-15 03:47:38 -070084}
85
86// This test will fail if kernel is missing:
87// https://android-review.googlesource.com/c/kernel/common/+/1831252
88// UPSTREAM: security: selinux: allow per-file labeling for bpffs
89TEST(NetdSELinuxTest, CheckProperBpfLabels) {
90 assertBpfContext("/sys/fs/bpf", "fs_bpf");
91 assertBpfContext("/sys/fs/bpf/net_private", "fs_bpf_net_private");
92 assertBpfContext("/sys/fs/bpf/net_shared", "fs_bpf_net_shared");
93 assertBpfContext("/sys/fs/bpf/netd_readonly", "fs_bpf_netd_readonly");
94 assertBpfContext("/sys/fs/bpf/netd_shared", "fs_bpf_netd_shared");
Maciej Żenczykowski3a7bc3f2023-05-07 15:45:14 +000095 assertBpfContext("/sys/fs/bpf/tethering", "fs_bpf_tethering");
Maciej Żenczykowski438c0912022-07-15 03:47:38 -070096 assertBpfContext("/sys/fs/bpf/vendor", "fs_bpf_vendor");
Maciej Żenczykowski020536c2022-12-02 13:57:28 +000097 assertBpfContext("/sys/fs/bpf/loader", "fs_bpf_loader");
Maciej Żenczykowski438c0912022-07-15 03:47:38 -070098}
99
Maciej Żenczykowski7b242462020-05-13 20:53:10 -0700100// Trivial thread function that simply immediately terminates successfully.
101static int thread(void*) {
102 return 0;
103}
104
105typedef int (*thread_t)(void*);
106
107static void nsTest(int flags, bool success, thread_t newThread) {
108 // We need a minimal stack, but not clear if it will grow up or down,
109 // So allocate 2 pages and give a pointer to the middle.
Vilas Bhat26afdb22024-02-12 22:47:39 +0000110 static const size_t kPageSize = getpagesize();
111 static std::vector<char> stack(kPageSize * 2);
112
Maciej Żenczykowski7b242462020-05-13 20:53:10 -0700113 errno = 0;
114 // VFORK: if thread is successfully created, then kernel will wait for it
115 // to terminate before we resume -> hence static stack is safe to reuse.
Vilas Bhat26afdb22024-02-12 22:47:39 +0000116 int tid = clone(newThread, &stack[kPageSize], flags | CLONE_VFORK, NULL);
Maciej Żenczykowski7b242462020-05-13 20:53:10 -0700117 if (success) {
118 ASSERT_EQ(errno, 0);
119 ASSERT_GE(tid, 0);
120 } else {
121 ASSERT_EQ(errno, EINVAL);
122 ASSERT_EQ(tid, -1);
123 }
124}
125
126// Test kernel configuration option CONFIG_NAMESPACES=y
127TEST(NetdNamespaceTest, CheckMountNamespaceSupport) {
128 nsTest(CLONE_NEWNS, true, thread);
129}
130
131// Test kernel configuration option CONFIG_UTS_NS=y
132TEST(NetdNamespaceTest, CheckUTSNamespaceSupport) {
133 nsTest(CLONE_NEWUTS, true, thread);
134}
135
136// Test kernel configuration option CONFIG_NET_NS=y
137TEST(NetdNamespaceTest, CheckNetworkNamespaceSupport) {
138 nsTest(CLONE_NEWNET, true, thread);
139}
140
141// Test kernel configuration option CONFIG_USER_NS=n
142TEST(NetdNamespaceTest, /*DISABLED_*/ CheckNoUserNamespaceSupport) {
143 nsTest(CLONE_NEWUSER, false, thread);
144}
145
146// Test for all of the above
147TEST(NetdNamespaceTest, CheckFullNamespaceSupport) {
148 nsTest(CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWNET, true, thread);
149}
Maciej Żenczykowski9ce7e662020-05-29 00:41:22 -0700150
Maciej Żenczykowski9ce7e662020-05-29 00:41:22 -0700151} // namespace net
152} // namespace android