From ba65ffc4623240b38f8d2c940195a8bbdeb8e6a2 Mon Sep 17 00:00:00 2001 From: Chenbo Feng Date: Fri, 16 Jun 2017 11:03:17 -0700 Subject: [PATCH] Add test to check sock addr in qtaguid ctrl file This test verifies the socket address information is not leaked by xt_qtaguid module inside the kernel. The sock_addr parsed from proc/net/xt_qtaguid/ctrl file should always be 0 Bug: 62489688 Test: in cts-tf: run cts --package android.net.native --- tests/cts/net/native/Android.mk | 2 + tests/cts/net/native/qtaguid/Android.mk | 68 ++++++++++++++ .../native/qtaguid/src/NativeQtaguidTest.cpp | 88 +++++++++++++++++++ 3 files changed, 158 insertions(+) create mode 100644 tests/cts/net/native/Android.mk create mode 100644 tests/cts/net/native/qtaguid/Android.mk create mode 100644 tests/cts/net/native/qtaguid/src/NativeQtaguidTest.cpp diff --git a/tests/cts/net/native/Android.mk b/tests/cts/net/native/Android.mk new file mode 100644 index 0000000000..8338432200 --- /dev/null +++ b/tests/cts/net/native/Android.mk @@ -0,0 +1,2 @@ +include $(call all-subdir-makefiles) + diff --git a/tests/cts/net/native/qtaguid/Android.mk b/tests/cts/net/native/qtaguid/Android.mk new file mode 100644 index 0000000000..4a09906a15 --- /dev/null +++ b/tests/cts/net/native/qtaguid/Android.mk @@ -0,0 +1,68 @@ +# 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. + +LOCAL_PATH:= $(call my-dir) + +test_executable := NativeNetTest +list_executable := $(test_executable)_list + +include $(CLEAR_VARS) +LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk + + +LOCAL_MODULE := $(test_executable) +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativetest +LOCAL_MULTILIB := both +LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32 +LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64 + +LOCAL_SRC_FILES := \ + src/NativeQtaguidTest.cpp + +LOCAL_C_INCLUDES := \ + external/gtest/include \ + +LOCAL_SHARED_LIBRARIES := \ + libutils \ + liblog \ + libcutils \ + +LOCAL_STATIC_LIBRARIES := \ + libgtest + +LOCAL_CTS_TEST_PACKAGE := android.net.native + +LOCAL_CFLAGS := -Werror -Wall + +include $(BUILD_CTS_EXECUTABLE) + +include $(CLEAR_VARS) +LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk + +LOCAL_MODULE := $(list_executable) +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + src/NativeQtaguidTest.cpp + +LOCAL_CFLAGS := \ + -DBUILD_ONLY \ + +LOCAL_SHARED_LIBRARIES := \ + liblog \ + +include $(BUILD_HOST_NATIVE_TEST) diff --git a/tests/cts/net/native/qtaguid/src/NativeQtaguidTest.cpp b/tests/cts/net/native/qtaguid/src/NativeQtaguidTest.cpp new file mode 100644 index 0000000000..0301c8187f --- /dev/null +++ b/tests/cts/net/native/qtaguid/src/NativeQtaguidTest.cpp @@ -0,0 +1,88 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + +#if !defined(BUILD_ONLY) +#include +#endif + +#if !defined(BUILD_ONLY) +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, qtaguid_tagSocket(sockfd, tag, uid)); + EXPECT_EQ(0, getCtrlSkInfo(tag, uid, &sk_addr, &ref_cnt)); + EXPECT_EQ(expect_addr, sk_addr); + EXPECT_EQ(0, qtaguid_untagSocket(sockfd)); + EXPECT_EQ(-ENOENT, getCtrlSkInfo(tag, uid, &sk_addr, &ref_cnt)); +} +#else +void checkNoSocketPointerLeaks(int family) {} +#endif + +TEST (NativeQtaguidTest, no_socket_addr_leak) { + checkNoSocketPointerLeaks(AF_INET); + checkNoSocketPointerLeaks(AF_INET6); +} + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +}