1 /*
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 *
10 * Unless required by applicable law or agreed to in writing, software
11 * 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 #include <sys/time.h>
18
19 #include <chrono>
20 #include <functional>
21
22 #include <android-base/test_utils.h>
23
24 #include <ScopedDisableMalloc.h>
25 #include <gtest/gtest.h>
26
27 using namespace std::chrono_literals;
28
29 namespace android {
30
31 class DisableMallocTest : public ::testing::Test {
32 protected:
alarm(std::chrono::microseconds us)33 void alarm(std::chrono::microseconds us) {
34 std::chrono::seconds s = std::chrono::duration_cast<std::chrono::seconds>(us);
35 itimerval t = itimerval();
36 t.it_value.tv_sec = s.count();
37 t.it_value.tv_usec = (us - s).count();
38 setitimer(ITIMER_REAL, &t, NULL);
39 }
40
SetUp()41 void SetUp() override {
42 // HWASan does not support malloc_disable.
43 SKIP_WITH_HWASAN;
44 }
45 };
46
TEST_F(DisableMallocTest,reenable)47 TEST_F(DisableMallocTest, reenable) {
48 ASSERT_EXIT(
49 {
50 alarm(100ms);
51 void* ptr1 = malloc(128);
52 ASSERT_NE(ptr1, nullptr);
53 free(ptr1);
54 { ScopedDisableMalloc disable_malloc; }
55 void* ptr2 = malloc(128);
56 ASSERT_NE(ptr2, nullptr);
57 free(ptr2);
58 _exit(1);
59 },
60 ::testing::ExitedWithCode(1), "");
61 }
62
TEST_F(DisableMallocTest,deadlock_allocate)63 TEST_F(DisableMallocTest, deadlock_allocate) {
64 ASSERT_DEATH(
65 {
66 void* ptr = malloc(128);
67 ASSERT_NE(ptr, nullptr);
68 free(ptr);
69 {
70 alarm(100ms);
71 ScopedDisableMalloc disable_malloc;
72 void* ptr = malloc(128);
73 ASSERT_NE(ptr, nullptr);
74 free(ptr);
75 }
76 },
77 "");
78 }
79
TEST_F(DisableMallocTest,deadlock_new)80 TEST_F(DisableMallocTest, deadlock_new) {
81 ASSERT_DEATH(
82 {
83 // C++ allows `new Foo` to be replaced with a stack allocation or merged
84 // with future `new Foo` expressions, provided certain conditions are
85 // met [expr.new/10]. None of this applies to `operator new(size_t)`.
86 void* ptr = ::operator new(1);
87 ASSERT_NE(ptr, nullptr);
88 ::operator delete(ptr);
89 {
90 alarm(100ms);
91 ScopedDisableMalloc disable_malloc;
92 void* ptr = ::operator new(1);
93 ASSERT_NE(ptr, nullptr);
94 ::operator delete(ptr);
95 }
96 },
97 "");
98 }
99
TEST_F(DisableMallocTest,deadlock_delete)100 TEST_F(DisableMallocTest, deadlock_delete) {
101 ASSERT_DEATH(
102 {
103 void* ptr = ::operator new(1);
104 ASSERT_NE(ptr, nullptr);
105 {
106 alarm(250ms);
107 ScopedDisableMalloc disable_malloc;
108 ::operator delete(ptr);
109 }
110 },
111 "");
112 }
113
TEST_F(DisableMallocTest,deadlock_free)114 TEST_F(DisableMallocTest, deadlock_free) {
115 ASSERT_DEATH(
116 {
117 void* ptr = malloc(128);
118 ASSERT_NE(ptr, nullptr);
119 {
120 alarm(100ms);
121 ScopedDisableMalloc disable_malloc;
122 free(ptr);
123 }
124 },
125 "");
126 }
127
TEST_F(DisableMallocTest,deadlock_fork)128 TEST_F(DisableMallocTest, deadlock_fork) {
129 ASSERT_DEATH({
130 {
131 alarm(100ms);
132 ScopedDisableMalloc disable_malloc;
133 fork();
134 }
135 }, "");
136 }
137
138 } // namespace android
139