add test for /system/etc/bpf/{netd,clatd}.o using correct struct sizes
This test is required to ensure that the system is compatible with future updates of the tethering mainline module, which updates BPF .o files on device. This test must already be passing on OEM devices because otherwise the offload.o program in the Tethering mainline module would bootloop the device. Bug: 190519702 Test: atest CtsNativeNetTestCases, TreeHugger Signed-off-by: Maciej Żenczykowski <maze@google.com> Original-Change: https://android-review.googlesource.com/1756440 Merged-In: Ibaedb8fcb28591ffba1506514f2305d55712a26b Change-Id: Ibaedb8fcb28591ffba1506514f2305d55712a26b
This commit is contained in:
parent
1d934442ff
commit
cba9f66098
4 changed files with 50 additions and 2 deletions
62
tests/cts/net/native/Android.bp
Normal file
62
tests/cts/net/native/Android.bp
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
// Copyright (C) 2017 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Build the unit tests.
|
||||
|
||||
package {
|
||||
default_applicable_licenses: ["Android-Apache-2.0"],
|
||||
}
|
||||
|
||||
cc_test {
|
||||
name: "CtsNativeNetTestCases",
|
||||
|
||||
compile_multilib: "both",
|
||||
multilib: {
|
||||
lib32: {
|
||||
suffix: "32",
|
||||
},
|
||||
lib64: {
|
||||
suffix: "64",
|
||||
},
|
||||
},
|
||||
|
||||
srcs: [
|
||||
"src/BpfCompatTest.cpp",
|
||||
"src/NativeQtaguidTest.cpp",
|
||||
],
|
||||
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"liblog",
|
||||
"libutils",
|
||||
],
|
||||
|
||||
static_libs: [
|
||||
"libbpf_android",
|
||||
"libgtest",
|
||||
"libqtaguid",
|
||||
],
|
||||
|
||||
// Tag this module as a cts test artifact
|
||||
test_suites: [
|
||||
"cts",
|
||||
"general-tests",
|
||||
],
|
||||
|
||||
cflags: [
|
||||
"-Werror",
|
||||
"-Wall",
|
||||
],
|
||||
|
||||
}
|
||||
32
tests/cts/net/native/AndroidTest.xml
Normal file
32
tests/cts/net/native/AndroidTest.xml
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright 2017 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<configuration description="Config for CTS Native Network xt_qtaguid test cases">
|
||||
<option name="test-suite-tag" value="cts" />
|
||||
<option name="config-descriptor:metadata" key="component" value="networking" />
|
||||
<option name="config-descriptor:metadata" key="parameter" value="instant_app" />
|
||||
<option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
|
||||
<option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
|
||||
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
|
||||
<option name="cleanup" value="true" />
|
||||
<option name="push" value="CtsNativeNetTestCases->/data/local/tmp/CtsNativeNetTestCases" />
|
||||
<option name="append-bitness" value="true" />
|
||||
</target_preparer>
|
||||
<test class="com.android.tradefed.testtype.GTest" >
|
||||
<option name="native-test-device-path" value="/data/local/tmp" />
|
||||
<option name="module-name" value="CtsNativeNetTestCases" />
|
||||
<option name="runtime-hint" value="1m" />
|
||||
</test>
|
||||
</configuration>
|
||||
43
tests/cts/net/native/src/BpfCompatTest.cpp
Normal file
43
tests/cts/net/native/src/BpfCompatTest.cpp
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless requied by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
#define LOG_TAG "BpfCompatTest"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "libbpf_android.h"
|
||||
|
||||
using namespace android::bpf;
|
||||
|
||||
namespace android {
|
||||
|
||||
void doBpfStructSizeTest(const char *elfPath) {
|
||||
std::ifstream elfFile(elfPath, std::ios::in | std::ios::binary);
|
||||
ASSERT_TRUE(elfFile.is_open());
|
||||
|
||||
EXPECT_EQ(48, readSectionUint("size_of_bpf_map_def", elfFile, 0));
|
||||
EXPECT_EQ(28, readSectionUint("size_of_bpf_prog_def", elfFile, 0));
|
||||
}
|
||||
|
||||
TEST(BpfTest, bpfStructSizeTest) {
|
||||
doBpfStructSizeTest("/system/etc/bpf/netd.o");
|
||||
doBpfStructSizeTest("/system/etc/bpf/clatd.o");
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
130
tests/cts/net/native/src/NativeQtaguidTest.cpp
Normal file
130
tests/cts/net/native/src/NativeQtaguidTest.cpp
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <error.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <qtaguid/qtaguid.h>
|
||||
|
||||
int canAccessQtaguidFile() {
|
||||
int fd = open("/proc/net/xt_qtaguid/ctrl", O_RDONLY | O_CLOEXEC);
|
||||
close(fd);
|
||||
return fd != -1;
|
||||
}
|
||||
|
||||
#define SKIP_IF_QTAGUID_NOT_SUPPORTED() \
|
||||
do { \
|
||||
int res = canAccessQtaguidFile(); \
|
||||
ASSERT_LE(0, res); \
|
||||
if (!res) { \
|
||||
GTEST_LOG_(INFO) << "This test is skipped since kernel may not have the module\n"; \
|
||||
return; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
int getCtrlSkInfo(int tag, uid_t uid, uint64_t* sk_addr, int* ref_cnt) {
|
||||
FILE *fp;
|
||||
fp = fopen("/proc/net/xt_qtaguid/ctrl", "r");
|
||||
if (!fp)
|
||||
return -ENOENT;
|
||||
uint64_t full_tag = (uint64_t)tag << 32 | uid;
|
||||
char pattern[40];
|
||||
snprintf(pattern, sizeof(pattern), " tag=0x%" PRIx64 " (uid=%" PRIu32 ")", full_tag, uid);
|
||||
|
||||
size_t len;
|
||||
char *line_buffer = NULL;
|
||||
while(getline(&line_buffer, &len, fp) != -1) {
|
||||
if (strstr(line_buffer, pattern) == NULL)
|
||||
continue;
|
||||
int res;
|
||||
pid_t dummy_pid;
|
||||
uint64_t k_tag;
|
||||
uint32_t k_uid;
|
||||
const int TOTAL_PARAM = 5;
|
||||
res = sscanf(line_buffer, "sock=%" PRIx64 " tag=0x%" PRIx64 " (uid=%" PRIu32 ") "
|
||||
"pid=%u f_count=%u", sk_addr, &k_tag, &k_uid,
|
||||
&dummy_pid, ref_cnt);
|
||||
if (!(res == TOTAL_PARAM && k_tag == full_tag && k_uid == uid))
|
||||
return -EINVAL;
|
||||
free(line_buffer);
|
||||
return 0;
|
||||
}
|
||||
free(line_buffer);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
void checkNoSocketPointerLeaks(int family) {
|
||||
int sockfd = socket(family, SOCK_STREAM, 0);
|
||||
uid_t uid = getuid();
|
||||
int tag = arc4random();
|
||||
int ref_cnt;
|
||||
uint64_t sk_addr;
|
||||
uint64_t expect_addr = 0;
|
||||
|
||||
EXPECT_EQ(0, legacy_tagSocket(sockfd, tag, uid));
|
||||
EXPECT_EQ(0, getCtrlSkInfo(tag, uid, &sk_addr, &ref_cnt));
|
||||
EXPECT_EQ(expect_addr, sk_addr);
|
||||
close(sockfd);
|
||||
EXPECT_EQ(-ENOENT, getCtrlSkInfo(tag, uid, &sk_addr, &ref_cnt));
|
||||
}
|
||||
|
||||
TEST (NativeQtaguidTest, close_socket_without_untag) {
|
||||
SKIP_IF_QTAGUID_NOT_SUPPORTED();
|
||||
|
||||
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
uid_t uid = getuid();
|
||||
int tag = arc4random();
|
||||
int ref_cnt;
|
||||
uint64_t dummy_sk;
|
||||
EXPECT_EQ(0, legacy_tagSocket(sockfd, tag, uid));
|
||||
EXPECT_EQ(0, getCtrlSkInfo(tag, uid, &dummy_sk, &ref_cnt));
|
||||
EXPECT_EQ(2, ref_cnt);
|
||||
close(sockfd);
|
||||
EXPECT_EQ(-ENOENT, getCtrlSkInfo(tag, uid, &dummy_sk, &ref_cnt));
|
||||
}
|
||||
|
||||
TEST (NativeQtaguidTest, close_socket_without_untag_ipv6) {
|
||||
SKIP_IF_QTAGUID_NOT_SUPPORTED();
|
||||
|
||||
int sockfd = socket(AF_INET6, SOCK_STREAM, 0);
|
||||
uid_t uid = getuid();
|
||||
int tag = arc4random();
|
||||
int ref_cnt;
|
||||
uint64_t dummy_sk;
|
||||
EXPECT_EQ(0, legacy_tagSocket(sockfd, tag, uid));
|
||||
EXPECT_EQ(0, getCtrlSkInfo(tag, uid, &dummy_sk, &ref_cnt));
|
||||
EXPECT_EQ(2, ref_cnt);
|
||||
close(sockfd);
|
||||
EXPECT_EQ(-ENOENT, getCtrlSkInfo(tag, uid, &dummy_sk, &ref_cnt));
|
||||
}
|
||||
|
||||
TEST (NativeQtaguidTest, no_socket_addr_leak) {
|
||||
SKIP_IF_QTAGUID_NOT_SUPPORTED();
|
||||
|
||||
checkNoSocketPointerLeaks(AF_INET);
|
||||
checkNoSocketPointerLeaks(AF_INET6);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
Loading…
Reference in a new issue