blob: 8e51323043d5ff1dc3b6c4da8dad036e581c9f39 [file] [log] [blame]
Mitch Phillipse6997d52020-11-30 15:04:14 -08001/*
2 * Copyright (C) 2021 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <gtest/gtest.h>
30#include <stdio.h>
Mitch Phillips9634c362022-06-23 11:07:00 -070031#include <sys/file.h>
Mitch Phillipse6997d52020-11-30 15:04:14 -080032#include <string>
33
34#if defined(__BIONIC__)
35
Mitch Phillips9634c362022-06-23 11:07:00 -070036#include "android-base/file.h"
Mitch Phillipse6997d52020-11-30 15:04:14 -080037#include "gwp_asan/options.h"
38#include "platform/bionic/malloc.h"
Mitch Phillips9634c362022-06-23 11:07:00 -070039#include "sys/system_properties.h"
Mitch Phillipse6997d52020-11-30 15:04:14 -080040#include "utils.h"
41
Mitch Phillips9634c362022-06-23 11:07:00 -070042// basename is a mess, use gnu basename explicitly to avoid the need for string
43// mutation.
44extern "C" const char* __gnu_basename(const char* path);
Mitch Phillipse6997d52020-11-30 15:04:14 -080045
46// This file implements "torture testing" under GWP-ASan, where we sample every
47// single allocation. The upper limit for the number of GWP-ASan allocations in
48// the torture mode is is generally 40,000, so that svelte devices don't
49// explode, as this uses ~163MiB RAM (4KiB per live allocation).
50TEST(gwp_asan_integration, malloc_tests_under_torture) {
51 RunGwpAsanTest("malloc.*:-malloc.mallinfo*");
52}
53
Mitch Phillips9634c362022-06-23 11:07:00 -070054class SyspropRestorer {
55 private:
56 std::vector<std::pair<std::string, std::string>> props_to_restore_;
57 // System properties are global for a device, so the tests that mutate the
58 // GWP-ASan system properties must be run mutually exclusive. Because
59 // bionic-unit-tests is run in an isolated gtest fashion (each test is run in
60 // its own process), we have to use flocks to synchronise between tests.
61 int flock_fd_;
62
63 public:
64 SyspropRestorer() {
65 std::string path = testing::internal::GetArgvs()[0];
66 flock_fd_ = open(path.c_str(), O_RDONLY);
67 EXPECT_NE(flock_fd_, -1) << "failed to open self for a flock";
68 EXPECT_NE(flock(flock_fd_, LOCK_EX), -1) << "failed to flock myself";
69
70 const char* basename = __gnu_basename(path.c_str());
71 std::vector<std::string> props = {
72 std::string("libc.debug.gwp_asan.sample_rate.") + basename,
73 std::string("libc.debug.gwp_asan.process_sampling.") + basename,
74 std::string("libc.debug.gwp_asan.max_allocs.") + basename,
75 "libc.debug.gwp_asan.sample_rate.system_default",
76 "libc.debug.gwp_asan.sample_rate.app_default",
77 "libc.debug.gwp_asan.process_sampling.system_default",
78 "libc.debug.gwp_asan.process_sampling.app_default",
79 "libc.debug.gwp_asan.max_allocs.system_default",
80 "libc.debug.gwp_asan.max_allocs.app_default",
81 };
82
83 size_t base_props_size = props.size();
84 for (size_t i = 0; i < base_props_size; ++i) {
85 props.push_back("persist." + props[i]);
86 }
87
88 std::string reset_log;
89
90 for (const std::string& prop : props) {
91 std::string value = GetSysprop(prop);
92 props_to_restore_.emplace_back(prop, value);
93 if (!value.empty()) {
94 __system_property_set(prop.c_str(), "");
95 }
96 }
97 }
98
99 ~SyspropRestorer() {
100 for (const auto& kv : props_to_restore_) {
101 if (kv.second != GetSysprop(kv.first)) {
102 __system_property_set(kv.first.c_str(), kv.second.c_str());
103 }
104 }
105 close(flock_fd_);
106 }
107
108 static std::string GetSysprop(const std::string& name) {
109 std::string value;
110 const prop_info* pi = __system_property_find(name.c_str());
111 if (pi == nullptr) return value;
112 __system_property_read_callback(
113 pi,
114 [](void* cookie, const char* /* name */, const char* value, uint32_t /* serial */) {
115 std::string* v = static_cast<std::string*>(cookie);
116 *v = value;
117 },
118 &value);
119 return value;
120 }
121};
122
123TEST(gwp_asan_integration, DISABLED_assert_gwp_asan_enabled) {
124 std::string maps;
125 EXPECT_TRUE(android::base::ReadFileToString("/proc/self/maps", &maps));
126 EXPECT_TRUE(maps.find("GWP-ASan") != std::string::npos) << maps;
127
128 volatile int* x = new int;
129 delete x;
130 EXPECT_DEATH({ *x = 7; }, "");
131}
132
133TEST(gwp_asan_integration, DISABLED_assert_gwp_asan_disabled) {
134 std::string maps;
135 EXPECT_TRUE(android::base::ReadFileToString("/proc/self/maps", &maps));
136 EXPECT_TRUE(maps.find("GWP-ASan") == std::string::npos);
137}
138
139TEST(gwp_asan_integration, sysprops_program_specific) {
140 SyspropRestorer restorer;
141
142 std::string path = testing::internal::GetArgvs()[0];
143 const char* basename = __gnu_basename(path.c_str());
144 __system_property_set((std::string("libc.debug.gwp_asan.sample_rate.") + basename).c_str(), "1");
145 __system_property_set((std::string("libc.debug.gwp_asan.process_sampling.") + basename).c_str(),
146 "1");
147 __system_property_set((std::string("libc.debug.gwp_asan.max_allocs.") + basename).c_str(),
148 "40000");
149
150 RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
151}
152
153TEST(gwp_asan_integration, sysprops_persist_program_specific) {
154 SyspropRestorer restorer;
155
156 std::string path = testing::internal::GetArgvs()[0];
157 const char* basename = __gnu_basename(path.c_str());
158 __system_property_set(
159 (std::string("persist.libc.debug.gwp_asan.sample_rate.") + basename).c_str(), "1");
160 __system_property_set(
161 (std::string("persist.libc.debug.gwp_asan.process_sampling.") + basename).c_str(), "1");
162 __system_property_set((std::string("persist.libc.debug.gwp_asan.max_allocs.") + basename).c_str(),
163 "40000");
164
165 RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
166}
167
168TEST(gwp_asan_integration, sysprops_system) {
169 SyspropRestorer restorer;
170
171 __system_property_set("libc.debug.gwp_asan.sample_rate.system_default", "1");
172 __system_property_set("libc.debug.gwp_asan.process_sampling.system_default", "1");
173 __system_property_set("libc.debug.gwp_asan.max_allocs.system_default", "40000");
174
175 RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
176}
177
178TEST(gwp_asan_integration, sysprops_persist_system) {
179 SyspropRestorer restorer;
180
181 __system_property_set("persist.libc.debug.gwp_asan.sample_rate.system_default", "1");
182 __system_property_set("persist.libc.debug.gwp_asan.process_sampling.system_default", "1");
183 __system_property_set("persist.libc.debug.gwp_asan.max_allocs.system_default", "40000");
184
185 RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
186}
187
188TEST(gwp_asan_integration, sysprops_non_persist_overrides_persist) {
189 SyspropRestorer restorer;
190
191 __system_property_set("libc.debug.gwp_asan.sample_rate.system_default", "1");
192 __system_property_set("libc.debug.gwp_asan.process_sampling.system_default", "1");
193 __system_property_set("libc.debug.gwp_asan.max_allocs.system_default", "40000");
194
195 __system_property_set("persist.libc.debug.gwp_asan.sample_rate.system_default", "0");
196 __system_property_set("persist.libc.debug.gwp_asan.process_sampling.system_default", "0");
197 __system_property_set("persist.libc.debug.gwp_asan.max_allocs.system_default", "0");
198
199 RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
200}
201
202TEST(gwp_asan_integration, sysprops_program_specific_overrides_default) {
203 SyspropRestorer restorer;
204
205 std::string path = testing::internal::GetArgvs()[0];
206 const char* basename = __gnu_basename(path.c_str());
207 __system_property_set(
208 (std::string("persist.libc.debug.gwp_asan.sample_rate.") + basename).c_str(), "1");
209 __system_property_set(
210 (std::string("persist.libc.debug.gwp_asan.process_sampling.") + basename).c_str(), "1");
211 __system_property_set((std::string("persist.libc.debug.gwp_asan.max_allocs.") + basename).c_str(),
212 "40000");
213
214 __system_property_set("libc.debug.gwp_asan.sample_rate.system_default", "0");
215 __system_property_set("libc.debug.gwp_asan.process_sampling.system_default", "0");
216 __system_property_set("libc.debug.gwp_asan.max_allocs.system_default", "0");
217
218 RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
219}
220
221TEST(gwp_asan_integration, sysprops_can_disable) {
222 SyspropRestorer restorer;
223
224 __system_property_set("libc.debug.gwp_asan.sample_rate.system_default", "0");
225 __system_property_set("libc.debug.gwp_asan.process_sampling.system_default", "0");
226 __system_property_set("libc.debug.gwp_asan.max_allocs.system_default", "0");
227
228 RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_disabled");
229}
230
231TEST(gwp_asan_integration, env_overrides_sysprop) {
232 SyspropRestorer restorer;
233
234 __system_property_set("libc.debug.gwp_asan.sample_rate.system_default", "0");
235 __system_property_set("libc.debug.gwp_asan.process_sampling.system_default", "0");
236 __system_property_set("libc.debug.gwp_asan.max_allocs.system_default", "0");
237
238 RunGwpAsanTest("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
239}
240
Mitch Phillipse6997d52020-11-30 15:04:14 -0800241#endif // defined(__BIONIC__)