Skip to content

Commit 2039b81

Browse files
Fix for heap-use-after-free in GPUService.cpp am: 24a7874 am: bc5214e
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/23905808 Change-Id: I26c7c10dadc8f4eec8392130a0357e3505a5de00 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
2 parents eb76276 + bc5214e commit 2039b81

6 files changed

Lines changed: 66 additions & 4 deletions

File tree

services/gpuservice/Android.bp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ filegroup {
7070
cc_library_shared {
7171
name: "libgpuservice",
7272
defaults: ["libgpuservice_production_defaults"],
73+
export_include_dirs: ["include"],
7374
srcs: [
7475
":libgpuservice_sources",
7576
],

services/gpuservice/GpuService.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
1818

19-
#include "GpuService.h"
19+
#include "gpuservice/GpuService.h"
2020

2121
#include <android-base/stringprintf.h>
2222
#include <binder/IPCThreadState.h>
@@ -33,6 +33,7 @@
3333
#include <vkjson.h>
3434

3535
#include <thread>
36+
#include <memory>
3637

3738
namespace android {
3839

@@ -52,13 +53,16 @@ GpuService::GpuService()
5253
: mGpuMem(std::make_shared<GpuMem>()),
5354
mGpuStats(std::make_unique<GpuStats>()),
5455
mGpuMemTracer(std::make_unique<GpuMemTracer>()) {
55-
std::thread asyncInitThread([this]() {
56+
mGpuMemAsyncInitThread = std::make_unique<std::thread>([this] (){
5657
mGpuMem->initialize();
5758
mGpuMemTracer->initialize(mGpuMem);
5859
});
59-
asyncInitThread.detach();
6060
};
6161

62+
GpuService::~GpuService() {
63+
mGpuMemAsyncInitThread->join();
64+
}
65+
6266
void GpuService::setGpuStats(const std::string& driverPackageName,
6367
const std::string& driverVersionName, uint64_t driverVersionCode,
6468
int64_t driverBuildTime, const std::string& appPackageName,

services/gpuservice/GpuService.h renamed to services/gpuservice/include/gpuservice/GpuService.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <serviceutils/PriorityDumper.h>
2525

2626
#include <mutex>
27+
#include <thread>
2728
#include <vector>
2829

2930
namespace android {
@@ -37,6 +38,7 @@ class GpuService : public BnGpuService, public PriorityDumper {
3738
static const char* const SERVICE_NAME ANDROID_API;
3839

3940
GpuService() ANDROID_API;
41+
~GpuService();
4042

4143
protected:
4244
status_t shellCommand(int in, int out, int err, std::vector<String16>& args) override;
@@ -81,6 +83,7 @@ class GpuService : public BnGpuService, public PriorityDumper {
8183
std::unique_ptr<GpuMemTracer> mGpuMemTracer;
8284
std::mutex mLock;
8385
std::string mDeveloperDriverPath;
86+
std::unique_ptr<std::thread> mGpuMemAsyncInitThread;
8487
};
8588

8689
} // namespace android

services/gpuservice/main_gpuservice.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
#include <binder/IServiceManager.h>
1919
#include <binder/ProcessState.h>
2020
#include <sys/resource.h>
21-
#include "GpuService.h"
21+
#include "gpuservice/GpuService.h"
2222

2323
using namespace android;
2424

services/gpuservice/tests/unittests/Android.bp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ cc_test {
3131
"GpuMemTest.cpp",
3232
"GpuMemTracerTest.cpp",
3333
"GpuStatsTest.cpp",
34+
"GpuServiceTest.cpp",
3435
],
3536
shared_libs: [
3637
"libbase",
@@ -47,6 +48,7 @@ cc_test {
4748
"libstatslog",
4849
"libstatspull",
4950
"libutils",
51+
"libgpuservice",
5052
],
5153
static_libs: [
5254
"libgmock",
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#undef LOG_TAG
2+
#define LOG_TAG "gpuservice_unittest"
3+
4+
#include "gpuservice/GpuService.h"
5+
6+
#include <gtest/gtest.h>
7+
#include <log/log_main.h>
8+
9+
#include <chrono>
10+
#include <thread>
11+
12+
namespace android {
13+
namespace {
14+
15+
class GpuServiceTest : public testing::Test {
16+
public:
17+
GpuServiceTest() {
18+
const ::testing::TestInfo* const test_info =
19+
::testing::UnitTest::GetInstance()->current_test_info();
20+
ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
21+
}
22+
23+
~GpuServiceTest() {
24+
const ::testing::TestInfo* const test_info =
25+
::testing::UnitTest::GetInstance()->current_test_info();
26+
ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
27+
}
28+
29+
};
30+
31+
32+
/*
33+
* The behaviour before this test + fixes was UB caused by threads accessing deallocated memory.
34+
*
35+
* This test creates the service (which initializes the culprit threads),
36+
* deallocates it immediately and sleeps.
37+
*
38+
* GpuService's destructor gets called and joins the threads.
39+
* If we haven't crashed by the time the sleep time has elapsed, we're good
40+
* Let the test pass.
41+
*/
42+
TEST_F(GpuServiceTest, onInitializeShouldNotCauseUseAfterFree) {
43+
sp<GpuService> service = new GpuService();
44+
service.clear();
45+
std::this_thread::sleep_for(std::chrono::seconds(3));
46+
47+
// If we haven't crashed yet due to threads accessing freed up memory, let the test pass
48+
EXPECT_TRUE(true);
49+
}
50+
51+
} // namespace
52+
} // namespace android

0 commit comments

Comments
 (0)