@@ -12,33 +12,44 @@ flowchart TB
12
12
subgraph p0 ["piglit_drm_create_dma_buf()"]
13
13
p.a["drv->create(w, h, fourcc, src_data, drm_buf)"]
14
14
p.b["drv->export(drm_buf)"]
15
+ subgraph p1 ["create_and_destroy_texture()"]
16
+ p.c["egl_image_for_dma_buf_fd<br>(buf, fd, fourcc, img)"]
17
+ p.d["texture_for_egl_image(img, texture)"]
18
+ p.e["eglDestroyImageKHR(display, img)"]
19
+ p.f["glDeleteTextures(1, &texture)"]
20
+ p.g["glFinish()"]
21
+ end
15
22
end
16
23
end
17
24
subgraph t1 [Thread 1]
18
25
subgraph lo11 [Loop 1]
19
26
t1.a["eglCreateContext()"]
20
27
t1.b["eglMakeCurrent()"]
21
- t1.c["egl_image_for_dma_buf_fd<br>(buf, fd, fourcc, img)"]
22
- t1.d["texture_for_egl_image(img, texture)"]
23
- t1.e["eglDestroyImageKHR(display, img)"]
24
- t1.f["glDeleteTextures(1, &texture)"]
25
- t1.g["glFinish()"]
28
+ subgraph lo111 ["create_and_destroy_texture()"]
29
+ t1.c["egl_image_for_dma_buf_fd<br>(buf, fd, fourcc, img)"]
30
+ t1.d["texture_for_egl_image(img, texture)"]
31
+ t1.e["eglDestroyImageKHR(display, img)"]
32
+ t1.f["glDeleteTextures(1, &texture)"]
33
+ t1.g["glFinish()"]
34
+ end
26
35
end
27
36
end
28
37
29
38
subgraph t2 [Thread 2]
30
39
subgraph lo21 [Loop 1]
31
40
t2.a["eglCreateContext()"]
32
41
t2.b["eglMakeCurrent()"]
33
- t2.c["egl_image_for_dma_buf_fd<br>(buf, fd, fourcc, img)"]
34
- t2.d["texture_for_egl_image(img, texture)"]
35
- t2.e["eglDestroyImageKHR(display, img)"]
36
- t2.f["glDeleteTextures(1, &texture)"]
37
- t2.g["glFinish()"]
42
+ subgraph lo211 ["create_and_destroy_texture()"]
43
+ t2.c["egl_image_for_dma_buf_fd<br>(buf, fd, fourcc, img)"]
44
+ t2.d["texture_for_egl_image(img, texture)"]
45
+ t2.e["eglDestroyImageKHR(display, img)"]
46
+ t2.f["glDeleteTextures(1, &texture)"]
47
+ t2.g["glFinish()"]
48
+ end
38
49
end
39
50
end
40
51
41
- p.a --> p.b
52
+ p.a --> p.b --> p.c --> p.d --> p.e --> p.f --> p.g
42
53
43
54
t1.a --> t1.b --> t1.c --> t1.d --> t1.e --> t1.f --> t1.g
44
55
t2.a --> t2.b --> t2.c --> t2.d --> t2.e --> t2.f --> t2.g
@@ -68,6 +79,16 @@ flowchart TB
68
79
69
80
FD 是文件描述符,而 bo handles 在内核态和用户态各自维护有一份,分别是 ** GEM bo handles** 和 ** Userspace bo handles** , 在 mesa 的实现里,这两个集合是 1:1 映射关系, 当一个 gem bo handle 被导入, 如果对应的 userspace bo handle(实际上就是 drmPrimeFDToHandle() 返回的整数)已经存在,mesa 驱动仅仅是将这个 userspace bo handle 的引用计数加 1. 这就有可能导致 bo_destroy 函数和 bo_import() 函数发生竞争 (race), 从而导致 UAF, 这个 Piglit 用例就是专门测试这种场景的。
70
81
82
+ ## FAQ
83
+
84
+ ### Q: 两个线程先后对同一个 FD 调用 ` drmPrimeFDToHandle() ` ,返回给各自线程的 handle ,是同一个值吗?
85
+
86
+ A: 因为是同一个 FD, 所以它底层的或者说内核的 drm_gem_object 也是同一个,返回的 handle 是同一个值,这也正是 ext_image_dma_buf_import/refcount-multithread 这个用例要构建的场景。
87
+
88
+ ### Q: ` drmPrimeFDToHandle() ` /` drmPrimeHandleToFD() ` 会影响 drm_gem_object 的引用计数吗?
89
+
90
+ A: 不会
91
+
71
92
# [ Waffle] ( https://gitlab.freedesktop.org/mesa/waffle )
72
93
73
94
[ Waffle /wa: fl / 动听而无意义的话] ( https://gitlab.freedesktop.org/mesa/waffle ) 是一个跨平台的在运行时动态地选择一个 OpenGL API.piglit 用它来创建 EGLContext, 最终会创建 Galliumm pipe_context. 此外 apitrace, Dante (open source DOOM 3) 也使用 waffle
0 commit comments