blob: 8560f5ed3ea3a365e6a06bce6643e7db01559823 [file] [log] [blame]
Ana Krulec13be8ad2018-08-21 02:43:56 +00001#include <algorithm>
2#include <functional>
3#include <limits>
4#include <ostream>
5
6#include <gtest/gtest.h>
7
8#include <gui/ISurfaceComposer.h>
9#include <gui/LayerDebugInfo.h>
10#include <gui/Surface.h>
11#include <gui/SurfaceComposerClient.h>
12
13#include <private/android_filesystem_config.h>
14#include <private/gui/ComposerService.h>
15
16#include <ui/DisplayInfo.h>
17#include <utils/String8.h>
18
19namespace android {
20
21using Transaction = SurfaceComposerClient::Transaction;
22
23namespace {
24const String8 DISPLAY_NAME("Credentials Display Test");
25const String8 SURFACE_NAME("Test Surface Name");
Ana Krulec13be8ad2018-08-21 02:43:56 +000026const uint32_t ROTATION = 0;
27const float FRAME_SCALE = 1.0f;
28} // namespace
29
30/**
31 * This class tests the CheckCredentials method in SurfaceFlinger.
32 * Methods like EnableVsyncInjections and InjectVsync are not tested since they do not
33 * return anything meaningful.
34 */
35class CredentialsTest : public ::testing::Test {
36protected:
37 void SetUp() override {
38 // Start the tests as root.
39 seteuid(AID_ROOT);
40
41 ASSERT_NO_FATAL_FAILURE(initClient());
42 }
43
44 void TearDown() override {
45 mComposerClient->dispose();
46 mBGSurfaceControl.clear();
47 mComposerClient.clear();
48 // Finish the tests as root.
49 seteuid(AID_ROOT);
50 }
51
52 sp<IBinder> mDisplay;
53 sp<IBinder> mVirtualDisplay;
54 sp<SurfaceComposerClient> mComposerClient;
55 sp<SurfaceControl> mBGSurfaceControl;
56 sp<SurfaceControl> mVirtualSurfaceControl;
57
58 void initClient() {
59 mComposerClient = new SurfaceComposerClient;
60 ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
61 }
62
63 void setupBackgroundSurface() {
64 mDisplay = SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain);
65 DisplayInfo info;
66 SurfaceComposerClient::getDisplayInfo(mDisplay, &info);
67 const ssize_t displayWidth = info.w;
68 const ssize_t displayHeight = info.h;
69
70 // Background surface
71 mBGSurfaceControl =
72 mComposerClient->createSurface(SURFACE_NAME, displayWidth, displayHeight,
73 PIXEL_FORMAT_RGBA_8888, 0);
74 ASSERT_TRUE(mBGSurfaceControl != nullptr);
75 ASSERT_TRUE(mBGSurfaceControl->isValid());
76
77 Transaction t;
78 t.setDisplayLayerStack(mDisplay, 0);
79 ASSERT_EQ(NO_ERROR,
80 t.setLayer(mBGSurfaceControl, INT_MAX - 3).show(mBGSurfaceControl).apply());
81 }
82
83 void setupVirtualDisplay() {
84 mVirtualDisplay = SurfaceComposerClient::createDisplay(DISPLAY_NAME, true);
85 const ssize_t displayWidth = 100;
86 const ssize_t displayHeight = 100;
87
88 // Background surface
89 mVirtualSurfaceControl =
90 mComposerClient->createSurface(SURFACE_NAME, displayWidth, displayHeight,
91 PIXEL_FORMAT_RGBA_8888, 0);
92 ASSERT_TRUE(mVirtualSurfaceControl != nullptr);
93 ASSERT_TRUE(mVirtualSurfaceControl->isValid());
94
95 Transaction t;
96 t.setDisplayLayerStack(mVirtualDisplay, 0);
97 ASSERT_EQ(NO_ERROR,
98 t.setLayer(mVirtualSurfaceControl, INT_MAX - 3)
99 .show(mVirtualSurfaceControl)
100 .apply());
101 }
102
103 /**
104 * Sets UID to imitate Graphic's process.
105 */
106 void setGraphicsUID() {
107 seteuid(AID_ROOT);
108 seteuid(AID_GRAPHICS);
109 }
110
111 /**
112 * Sets UID to imitate System's process.
113 */
114 void setSystemUID() {
115 seteuid(AID_ROOT);
116 seteuid(AID_SYSTEM);
117 }
118
119 /**
120 * Sets UID to imitate a process that doesn't have any special privileges in
121 * our code.
122 */
123 void setBinUID() {
124 seteuid(AID_ROOT);
125 seteuid(AID_BIN);
126 }
127
128 /**
129 * Template function the check a condition for different types of users: root
130 * graphics, system, and non-supported user. Root, graphics, and system should
131 * always equal privilegedValue, and non-supported user should equal unprivilegedValue.
132 */
133 template <typename T>
134 void checkWithPrivileges(std::function<T()> condition, T privilegedValue, T unprivilegedValue) {
135 // Check with root.
136 seteuid(AID_ROOT);
137 ASSERT_EQ(privilegedValue, condition());
138
139 // Check as a Graphics user.
140 setGraphicsUID();
141 ASSERT_EQ(privilegedValue, condition());
142
143 // Check as a system user.
144 setSystemUID();
145 ASSERT_EQ(privilegedValue, condition());
146
147 // Check as a non-supported user.
148 setBinUID();
149 ASSERT_EQ(unprivilegedValue, condition());
150 }
151};
152
153TEST_F(CredentialsTest, ClientInitTest) {
154 // Root can init can init the client.
155 ASSERT_NO_FATAL_FAILURE(initClient());
156
157 // Graphics can init the client.
158 setGraphicsUID();
159 ASSERT_NO_FATAL_FAILURE(initClient());
160
161 // System can init the client.
162 setSystemUID();
163 ASSERT_NO_FATAL_FAILURE(initClient());
164
Robert Carrb89ea9d2018-12-10 13:01:14 -0800165 // Anyone else can init the client.
Ana Krulec13be8ad2018-08-21 02:43:56 +0000166 setBinUID();
167 mComposerClient = new SurfaceComposerClient;
Robert Carrb89ea9d2018-12-10 13:01:14 -0800168 ASSERT_NO_FATAL_FAILURE(initClient());
Ana Krulec13be8ad2018-08-21 02:43:56 +0000169}
170
171TEST_F(CredentialsTest, GetBuiltInDisplayAccessTest) {
172 std::function<bool()> condition = [=]() {
173 sp<IBinder> display(
174 SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
175 return (display != nullptr);
176 };
177 // Anyone can access display information.
178 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, true));
179}
180
181TEST_F(CredentialsTest, AllowedGetterMethodsTest) {
182 // The following methods are tested with a UID that is not root, graphics,
183 // or system, to show that anyone can access them.
184 setBinUID();
185 sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
186 ASSERT_TRUE(display != nullptr);
187
188 DisplayInfo info;
189 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayInfo(display, &info));
190
191 Vector<DisplayInfo> configs;
192 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayConfigs(display, &configs));
193
194 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveConfig(display));
195
196 ASSERT_NE(static_cast<ui::ColorMode>(BAD_VALUE),
197 SurfaceComposerClient::getActiveColorMode(display));
198}
199
200TEST_F(CredentialsTest, GetDisplayColorModesTest) {
201 sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
202 std::function<status_t()> condition = [=]() {
203 Vector<ui::ColorMode> outColorModes;
204 return SurfaceComposerClient::getDisplayColorModes(display, &outColorModes);
205 };
206 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, NO_ERROR));
207}
208
209TEST_F(CredentialsTest, SetActiveConfigTest) {
210 sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
211 std::function<status_t()> condition = [=]() {
212 return SurfaceComposerClient::setActiveConfig(display, 0);
213 };
214 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
215}
216
217TEST_F(CredentialsTest, SetActiveColorModeTest) {
218 sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
219 std::function<status_t()> condition = [=]() {
220 return SurfaceComposerClient::setActiveColorMode(display, ui::ColorMode::NATIVE);
221 };
222 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
223}
224
Ana Krulec13be8ad2018-08-21 02:43:56 +0000225TEST_F(CredentialsTest, CreateDisplayTest) {
226 std::function<bool()> condition = [=]() {
227 sp<IBinder> testDisplay = SurfaceComposerClient::createDisplay(DISPLAY_NAME, true);
228 return testDisplay.get() != nullptr;
229 };
230 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, false));
231
232 condition = [=]() {
233 sp<IBinder> testDisplay = SurfaceComposerClient::createDisplay(DISPLAY_NAME, false);
234 return testDisplay.get() != nullptr;
235 };
236 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, false));
237}
238
239TEST_F(CredentialsTest, DISABLED_DestroyDisplayTest) {
240 setupVirtualDisplay();
241
242 DisplayInfo info;
243 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayInfo(mVirtualDisplay, &info));
244 SurfaceComposerClient::destroyDisplay(mVirtualDisplay);
245 // This test currently fails. TODO(b/112002626): Find a way to properly create
246 // a display in the test environment, so that destroy display can remove it.
247 ASSERT_EQ(NAME_NOT_FOUND, SurfaceComposerClient::getDisplayInfo(mVirtualDisplay, &info));
248}
249
250TEST_F(CredentialsTest, CaptureTest) {
251 sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
252 std::function<status_t()> condition = [=]() {
253 sp<GraphicBuffer> outBuffer;
Peiyong Lin0e003c92018-09-17 11:09:51 -0700254 return ScreenshotClient::capture(display, ui::Dataspace::V0_SRGB,
255 ui::PixelFormat::RGBA_8888, Rect(), 0 /*reqWidth*/,
256 0 /*reqHeight*/, false, ROTATION, &outBuffer);
Ana Krulec13be8ad2018-08-21 02:43:56 +0000257 };
258 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
259}
260
261TEST_F(CredentialsTest, CaptureLayersTest) {
262 setupBackgroundSurface();
263 sp<GraphicBuffer> outBuffer;
264 std::function<status_t()> condition = [=]() {
265 sp<GraphicBuffer> outBuffer;
Peiyong Lin0e003c92018-09-17 11:09:51 -0700266 return ScreenshotClient::captureLayers(mBGSurfaceControl->getHandle(),
267 ui::Dataspace::V0_SRGB, ui::PixelFormat::RGBA_8888,
268 Rect(), FRAME_SCALE, &outBuffer);
Ana Krulec13be8ad2018-08-21 02:43:56 +0000269 };
270 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
271}
272
273/**
274 * The following tests are for methods accessible directly through SurfaceFlinger.
275 */
276
277/**
278 * An app can pass a buffer queue to the media server and ask the media server to decode a DRM video
279 * to that buffer queue. The media server is the buffer producer in this case. Because the app may create
280 * its own buffer queue and act as the buffer consumer, the media server wants to be careful to avoid
281 * sending decoded video frames to the app. This is where authenticateSurfaceTexture call comes in, to check
282 * the consumer of a buffer queue is SurfaceFlinger.
283 */
284TEST_F(CredentialsTest, AuthenticateSurfaceTextureTest) {
285 setupBackgroundSurface();
286 sp<IGraphicBufferProducer> producer =
287 mBGSurfaceControl->getSurface()->getIGraphicBufferProducer();
288 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
289
290 std::function<bool()> condition = [=]() { return sf->authenticateSurfaceTexture(producer); };
291 // Anyone should be able to check if the consumer of the buffer queue is SF.
292 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, true));
293}
294
295TEST_F(CredentialsTest, GetLayerDebugInfo) {
296 setupBackgroundSurface();
297 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
298
299 // Historically, only root and shell can access the getLayerDebugInfo which
300 // is called when we call dumpsys. I don't see a reason why we should change this.
301 std::vector<LayerDebugInfo> outLayers;
302 // Check with root.
303 seteuid(AID_ROOT);
304 ASSERT_EQ(NO_ERROR, sf->getLayerDebugInfo(&outLayers));
305
306 // Check as a shell.
307 seteuid(AID_SHELL);
308 ASSERT_EQ(NO_ERROR, sf->getLayerDebugInfo(&outLayers));
309
310 // Check as anyone else.
311 seteuid(AID_ROOT);
312 seteuid(AID_BIN);
313 ASSERT_EQ(PERMISSION_DENIED, sf->getLayerDebugInfo(&outLayers));
314}
315} // namespace android