diff options
| author | 2018-03-02 12:01:51 -0800 | |
|---|---|---|
| committer | 2018-03-08 23:23:32 +0000 | |
| commit | 8f4b056427a9d2321e3aa4f21ca8ffb18b3e5ae6 (patch) | |
| tree | e4d4bd04a04a1e3fc5b210b0c02542d453b84781 /libartbase/base/safe_copy_test.cc | |
| parent | cedad4bd452f800ada0be930e801cd921319cd11 (diff) | |
Move most of runtime/base to libartbase/base
Enforce the layering that code in runtime/base should not depend on
runtime by separating it into libartbase. Some of the code in
runtime/base depends on the Runtime class, so it cannot be moved yet.
Also, some of the tests depend on CommonRuntimeTest, which itself needs
to be factored (in a subsequent CL).
Bug: 22322814
Test: make -j 50 checkbuild
make -j 50 test-art-host
Change-Id: I8b096c1e2542f829eb456b4b057c71421b77d7e2
Merged-In: c431b9dc4b23cc950eb313695258df5d89f53b22
(cherry picked from commit c431b9dc4b23cc950eb313695258df5d89f53b22)
Diffstat (limited to 'libartbase/base/safe_copy_test.cc')
| -rw-r--r-- | libartbase/base/safe_copy_test.cc | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/libartbase/base/safe_copy_test.cc b/libartbase/base/safe_copy_test.cc new file mode 100644 index 0000000000..a9ec9528a1 --- /dev/null +++ b/libartbase/base/safe_copy_test.cc @@ -0,0 +1,110 @@ +/* + * 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 "safe_copy.h" + +#include "common_runtime_test.h" + +#include <errno.h> +#include <string.h> +#include <sys/mman.h> +#include <sys/user.h> + +#include "globals.h" + +namespace art { + +#if defined(__linux__) + +TEST(SafeCopyTest, smoke) { + DCHECK_EQ(kPageSize, static_cast<decltype(kPageSize)>(PAGE_SIZE)); + + // Map four pages, mark the second one as PROT_NONE, unmap the last one. + void* map = mmap(nullptr, kPageSize * 4, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + ASSERT_NE(MAP_FAILED, map); + char* page1 = static_cast<char*>(map); + char* page2 = page1 + kPageSize; + char* page3 = page2 + kPageSize; + char* page4 = page3 + kPageSize; + ASSERT_EQ(0, mprotect(page1 + kPageSize, kPageSize, PROT_NONE)); + ASSERT_EQ(0, munmap(page4, kPageSize)); + + page1[0] = 'a'; + page1[kPageSize - 1] = 'z'; + + page3[0] = 'b'; + page3[kPageSize - 1] = 'y'; + + char buf[kPageSize]; + + // Completely valid read. + memset(buf, 0xCC, sizeof(buf)); + EXPECT_EQ(static_cast<ssize_t>(kPageSize), SafeCopy(buf, page1, kPageSize)) << strerror(errno); + EXPECT_EQ(0, memcmp(buf, page1, kPageSize)); + + // Reading into a guard page. + memset(buf, 0xCC, sizeof(buf)); + EXPECT_EQ(static_cast<ssize_t>(kPageSize - 1), SafeCopy(buf, page1 + 1, kPageSize)); + EXPECT_EQ(0, memcmp(buf, page1 + 1, kPageSize - 1)); + + // Reading from a guard page into a real page. + memset(buf, 0xCC, sizeof(buf)); + EXPECT_EQ(0, SafeCopy(buf, page2 + kPageSize - 1, kPageSize)); + + // Reading off of the end of a mapping. + memset(buf, 0xCC, sizeof(buf)); + EXPECT_EQ(static_cast<ssize_t>(kPageSize), SafeCopy(buf, page3, kPageSize * 2)); + EXPECT_EQ(0, memcmp(buf, page3, kPageSize)); + + // Completely invalid. + EXPECT_EQ(0, SafeCopy(buf, page1 + kPageSize, kPageSize)); + + // Clean up. + ASSERT_EQ(0, munmap(map, kPageSize * 3)); +} + +TEST(SafeCopyTest, alignment) { + DCHECK_EQ(kPageSize, static_cast<decltype(kPageSize)>(PAGE_SIZE)); + + // Copy the middle of a mapping to the end of another one. + void* src_map = mmap(nullptr, kPageSize * 3, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + ASSERT_NE(MAP_FAILED, src_map); + + // Add a guard page to make sure we don't write past the end of the mapping. + void* dst_map = mmap(nullptr, kPageSize * 4, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + ASSERT_NE(MAP_FAILED, dst_map); + + char* src = static_cast<char*>(src_map); + char* dst = static_cast<char*>(dst_map); + ASSERT_EQ(0, mprotect(dst + 3 * kPageSize, kPageSize, PROT_NONE)); + + src[512] = 'a'; + src[kPageSize * 3 - 512 - 1] = 'z'; + + EXPECT_EQ(static_cast<ssize_t>(kPageSize * 3 - 1024), + SafeCopy(dst + 1024, src + 512, kPageSize * 3 - 1024)); + EXPECT_EQ(0, memcmp(dst + 1024, src + 512, kPageSize * 3 - 1024)); + + ASSERT_EQ(0, munmap(src_map, kPageSize * 3)); + ASSERT_EQ(0, munmap(dst_map, kPageSize * 4)); +} + +#endif // defined(__linux__) + +} // namespace art |