Mir

Merge lp:~vanvugt/mir/fix-1493721 into lp:mir

Proposed by Daniel van Vugt
Status: Merged
Approved by: Alexandros Frantzis
Approved revision: no longer in the source branch.
Merged at revision: 3002
Proposed branch: lp:~vanvugt/mir/fix-1493721
Merge into: lp:mir
Diff against target: 144 lines (+71/-13)
2 files modified
src/platforms/mesa/server/kms/display_buffer.cpp (+11/-12)
tests/unit-tests/graphics/mesa/kms/test_display_buffer.cpp (+60/-1)
To merge this branch: bzr merge lp:~vanvugt/mir/fix-1493721
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Chris Halse Rogers Approve
Alan Griffiths Approve
Review via email: mp+273021@code.launchpad.net

Commit message

Fix Mir server crash when Xmir -sw connects (or any fullscreen opaque
software client in theory) (LP: #1493721)

The problem was the bypass logic prematurely cast native buffer objects
into GBM buffer objects, without checking if that's safe.

Description of the change

.

To post a comment you must log in.
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

+ Mock::VerifyAndClearExpectations(&mock_gbm);
...
+
+ Mock::VerifyAndClearExpectations(&mock_gbm);
...
+
+ Mock::VerifyAndClearExpectations(&mock_gbm);
...
+
+ Mock::VerifyAndClearExpectations(&mock_gbm);
...
+
+ Mock::VerifyAndClearExpectations(&mock_gbm);

Something seems wrong here. mock_gbm is destroyed on test exit and its expectations validated there. Why do we need these (apparently redundant) explicit check just before test exit?

review: Needs Information
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

+ Mock::VerifyAndClearExpectations(&mock_gbm);

Something seems wrong here. mock_gbm is destroyed on test exit and its expectations validated there. Why do we need this (apparently redundant) explicit check just before test exit?

review: Needs Information
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> It was required at the time to fix apparent expectation leakage between
> successive tests. But seemingly isn't needed today.

Whatever happened I think you misinterpreted it. The test object is torn down and destructed after each test (and that verifies the expectations). Could you have been seeing a race between satisfying the expectation and the tear down and destruction of the test object?

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Torn down _and_ destructed? I thought it was only Teardown() but not destructed. Hence mock_gbm lingers between tests.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> Torn down _and_ destructed? I thought it was only Teardown() but not
> destructed. Hence mock_gbm lingers between tests.

Yes, hence it doesn't linger.

review: Approve
Revision history for this message
Chris Halse Rogers (raof) wrote :

Seems sensible.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

> [ FAILED ] AndroidInputReceiverSetup.slow_raw_input_doesnt_cause_frameskipping

Doesn't seem related to this MP.

Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/platforms/mesa/server/kms/display_buffer.cpp'
2--- src/platforms/mesa/server/kms/display_buffer.cpp 2015-10-01 08:58:30 +0000
3+++ src/platforms/mesa/server/kms/display_buffer.cpp 2015-10-07 02:52:34 +0000
4@@ -200,24 +200,23 @@
5 {
6 auto bypass_buffer = (*bypass_it)->buffer();
7 auto native = bypass_buffer->native_buffer_handle();
8- auto gbm_native = static_cast<mgm::GBMNativeBuffer*>(native.get());
9- auto bufobj = get_buffer_object(gbm_native->bo);
10- if (bufobj &&
11- native->flags & mir_buffer_flag_can_scanout &&
12+ if (native->flags & mir_buffer_flag_can_scanout &&
13 bypass_buffer->size() == geom::Size{fb_width,fb_height})
14 {
15- bypass_buf = bypass_buffer;
16- bypass_bufobj = bufobj;
17- return true;
18- }
19- else
20- {
21- bypass_buf = nullptr;
22- bypass_bufobj = nullptr;
23+ auto gbm_native =
24+ static_cast<mgm::GBMNativeBuffer*>(native.get());
25+ if (auto bufobj = get_buffer_object(gbm_native->bo))
26+ {
27+ bypass_buf = bypass_buffer;
28+ bypass_bufobj = bufobj;
29+ return true;
30+ }
31 }
32 }
33 }
34
35+ bypass_buf = nullptr;
36+ bypass_bufobj = nullptr;
37 return false;
38 }
39
40
41=== modified file 'tests/unit-tests/graphics/mesa/kms/test_display_buffer.cpp'
42--- tests/unit-tests/graphics/mesa/kms/test_display_buffer.cpp 2015-10-01 08:58:30 +0000
43+++ tests/unit-tests/graphics/mesa/kms/test_display_buffer.cpp 2015-10-07 02:52:34 +0000
44@@ -50,10 +50,15 @@
45
46 MesaDisplayBufferTest()
47 : mock_bypassable_buffer{std::make_shared<NiceMock<MockBuffer>>()}
48+ , mock_software_buffer{std::make_shared<NiceMock<MockBuffer>>()}
49 , fake_bypassable_renderable{
50 std::make_shared<FakeRenderable>(display_area)}
51+ , fake_software_renderable{
52+ std::make_shared<FakeRenderable>(display_area)}
53 , stub_gbm_native_buffer{
54 std::make_shared<StubGBMNativeBuffer>(display_area.size)}
55+ , stub_shm_native_buffer{
56+ std::make_shared<MirNativeBuffer>()}
57 , bypassable_list{fake_bypassable_renderable}
58 {
59 ON_CALL(mock_egl, eglChooseConfig(_,_,_,1,_))
60@@ -88,6 +93,15 @@
61 ON_CALL(*mock_bypassable_buffer, native_buffer_handle())
62 .WillByDefault(Return(stub_gbm_native_buffer));
63 fake_bypassable_renderable->set_buffer(mock_bypassable_buffer);
64+
65+ memset(stub_shm_native_buffer.get(), 0, sizeof(MirNativeBuffer));
66+ stub_shm_native_buffer->flags = 0; // Is not a hardware/GBM buffer
67+
68+ ON_CALL(*mock_software_buffer, size())
69+ .WillByDefault(Return(display_area.size));
70+ ON_CALL(*mock_software_buffer, native_buffer_handle())
71+ .WillByDefault(Return(stub_shm_native_buffer));
72+ fake_software_renderable->set_buffer(mock_software_buffer);
73 }
74
75 // The platform has an implicit dependency on mock_gbm etc so must be
76@@ -106,15 +120,17 @@
77 NiceMock<MockGL> mock_gl;
78 NiceMock<MockDRM> mock_drm;
79 std::shared_ptr<MockBuffer> mock_bypassable_buffer;
80+ std::shared_ptr<MockBuffer> mock_software_buffer;
81 std::shared_ptr<FakeRenderable> fake_bypassable_renderable;
82+ std::shared_ptr<FakeRenderable> fake_software_renderable;
83 std::shared_ptr<mesa::GBMNativeBuffer> stub_gbm_native_buffer;
84+ std::shared_ptr<MirNativeBuffer> stub_shm_native_buffer;
85 gbm_bo* fake_bo;
86 gbm_bo_handle fake_handle;
87 UdevEnvironment fake_devices;
88 std::shared_ptr<MockKMSOutput> mock_kms_output;
89 StubGLConfig gl_config;
90 mir::graphics::RenderableList const bypassable_list;
91-
92 };
93
94 TEST_F(MesaDisplayBufferTest, unrotated_view_area_is_untouched)
95@@ -308,6 +324,49 @@
96 EXPECT_FALSE(db.post_renderables_if_optimizable(bypassable_list));
97 }
98
99+TEST_F(MesaDisplayBufferTest, fullscreen_software_buffer_cannot_bypass)
100+{
101+ graphics::RenderableList const list{fake_software_renderable};
102+
103+ // Passes the bypass candidate test:
104+ EXPECT_EQ(fake_software_renderable->buffer()->size(), display_area.size);
105+
106+ graphics::mesa::DisplayBuffer db(
107+ create_platform(),
108+ null_display_report(),
109+ {},
110+ nullptr,
111+ display_area,
112+ mir_orientation_normal,
113+ gl_config,
114+ mock_egl.fake_egl_context);
115+
116+ EXPECT_FALSE(db.post_renderables_if_optimizable(list));
117+}
118+
119+TEST_F(MesaDisplayBufferTest, fullscreen_software_buffer_not_used_as_gbm_bo)
120+{ // Also checks it doesn't crash (LP: #1493721)
121+ graphics::RenderableList const list{fake_software_renderable};
122+
123+ // Passes the bypass candidate test:
124+ EXPECT_EQ(fake_software_renderable->buffer()->size(), display_area.size);
125+
126+ graphics::mesa::DisplayBuffer db(
127+ create_platform(),
128+ null_display_report(),
129+ {},
130+ nullptr,
131+ display_area,
132+ mir_orientation_normal,
133+ gl_config,
134+ mock_egl.fake_egl_context);
135+
136+ // If you find yourself using gbm_ functions on a Shm buffer then you're
137+ // asking for a crash (LP: #1493721) ...
138+ EXPECT_CALL(mock_gbm, gbm_bo_get_user_data(_)).Times(0);
139+ db.post_renderables_if_optimizable(list);
140+}
141+
142 TEST_F(MesaDisplayBufferTest, orientation_not_implemented_internally)
143 {
144 graphics::mesa::DisplayBuffer db(

Subscribers

People subscribed via source and target branches