Skip to content

zink: fix heap-use-after-free on batch_state with sub-allocated pipe_resources

zink_bo_create can run into a heap-use-after-free when the bo is still referencing an batch_state from an older destroyed context. In order to fix this, every context gives back their batch_states to the zink, where they can be reused from for new contexts.

Cc: mesa-stable

Asan report:

==3196303==ERROR: AddressSanitizer: heap-use-after-free on address 0x63100012c860 at pc 0x7fffefec30e7 bp 0x7fffffff7f40 sp 0x7fffffff7f38
READ of size 4 at 0x63100012c860 thread T0
    #0 0x7fffefec30e6 in zink_batch_usage_exists ../src/gallium/drivers/zink/zink_batch.h:113
    #1 0x7fffefec30e6 in zink_screen_usage_check_completion ../src/gallium/drivers/zink/zink_batch.c:1056
    #2 0x7fffefec51a5 in bo_can_reclaim ../src/gallium/drivers/zink/zink_bo.c:160
    #3 0x7fffefec5234 in bo_can_reclaim_slab ../src/gallium/drivers/zink/zink_bo.c:168
    #4 0x7ffff059e43d in pb_slabs_reclaim_locked ../src/gallium/auxiliary/pipebuffer/pb_slab.c:83
    #5 0x7ffff059e9f4 in pb_slab_alloc_reclaimed ../src/gallium/auxiliary/pipebuffer/pb_slab.c:160
    #6 0x7fffefec84ce in zink_bo_create ../src/gallium/drivers/zink/zink_bo.c:627
    #7 0x7ffff03a30dc in resource_object_create ../src/gallium/drivers/zink/zink_resource.c:1290
    #8 0x7ffff03a5aaf in resource_create ../src/gallium/drivers/zink/zink_resource.c:1445
    #9 0x7ffff03a790e in zink_resource_create ../src/gallium/drivers/zink/zink_resource.c:1558
    #10 0x7ffff067d5ce in u_transfer_helper_resource_create ../src/gallium/auxiliary/util/u_transfer_helper.c:152
    #11 0x7fffef1c034b in mesa_rust::pipe::screen::PipeScreen::resource_create::h06245351196780bf ../src/gallium/frontends/rusticl/mesa/pipe/screen.rs:120
    #12 0x7fffef1c0534 in mesa_rust::pipe::screen::PipeScreen::resource_create_buffer::haacbb4b85b4fe8f3 ../src/gallium/frontends/rusticl/mesa/pipe/screen.rs:156
    #13 0x7fffef1820ad in rusticl::core::program::NirKernelBuild::create_nir_constant_buffer::h09c80ab911eb2a05 ../src/gallium/frontends/rusticl/core/program.rs:116
    #14 0x7fffef181dcf in rusticl::core::program::NirKernelBuild::new::h61496e12917681ce ../src/gallium/frontends/rusticl/core/program.rs:91
    #15 0x7fffef1830e2 in rusticl::core::program::ProgramBuild::build_nirs::h3f855f9d85648a52 ../src/gallium/frontends/rusticl/core/program.rs:174
    #16 0x7fffef1871ed in rusticl::core::program::Program::build::h0c8bf4dc9b731824 ../src/gallium/frontends/rusticl/core/program.rs:579
    #17 0x7fffef0fb032 in rusticl::api::program::build_program::h6d2f8b94e7f4eb99 ../src/gallium/frontends/rusticl/api/program.rs:288
    #18 0x7fffef0faa65 in rusticl::api::program::cl_build_program::h84a040b8d0719721 ../src/gallium/frontends/rusticl/api/program.rs:263
    #19 0x7ffff7f848d3 in clBuildProgram (/lib64/libOpenCL.so.1+0x138d3) (BuildId: 6d13714b4b1805766b80a73e39926e9751153a26)
    #20 0x2a5eda in build_program_create_kernel_helper(_cl_context*, _cl_program**, _cl_kernel**, unsigned int, char const**, char const*, char const*) /home/kherbst/git/OpenCL-CTS/test_common/harness/kernelHelpers.cpp:840
    #21 0x2a5d63 in create_single_kernel_helper(_cl_context*, _cl_program**, _cl_kernel**, unsigned int, char const**, char const*, char const*) /home/kherbst/git/OpenCL-CTS/test_common/harness/kernelHelpers.cpp:825
    #22 0x2541e6 in BuildKernels(BuildKernelInfo&, unsigned int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > (*)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*, unsigned int)) /home/kherbst/git/OpenCL-CTS/test_conformance/math_brute_force/common.cpp:575
    #23 0x27f08a in BuildKernelFn /home/kherbst/git/OpenCL-CTS/test_conformance/math_brute_force/unary_float.cpp:34
    #24 0x2b514f in ThreadPool_Do(int (*)(unsigned int, unsigned int, void*), unsigned int, void*) /home/kherbst/git/OpenCL-CTS/test_common/harness/ThreadPool.cpp:808
    #25 0x280e58 in TestFunc_Float_Float(Func const*, _MTdata*, bool) /home/kherbst/git/OpenCL-CTS/test_conformance/math_brute_force/unary_float.cpp:581
    #26 0x262ed9 in doTest /home/kherbst/git/OpenCL-CTS/test_conformance/math_brute_force/main.cpp:208
    #27 0x263063 in operator() /home/kherbst/git/OpenCL-CTS/test_conformance/math_brute_force/main.cpp:258
    #28 0x26309b in _FUN /home/kherbst/git/OpenCL-CTS/test_conformance/math_brute_force/main.cpp:258
    #29 0x2aeb0c in callSingleTestFunction(test_definition, _cl_device_id*, test_harness_config const&) /home/kherbst/git/OpenCL-CTS/test_common/harness/testHarness.cpp:939
    #30 0x2ae572 in callTestFunctions(test_definition*, unsigned char*, test_status*, int, _cl_device_id*, test_harness_config const&) /home/kherbst/git/OpenCL-CTS/test_common/harness/testHarness.cpp:818
    #31 0x2ae276 in parseAndCallCommandLineTests(int, char const**, _cl_device_id*, int, test_definition*, test_harness_config const&) /home/kherbst/git/OpenCL-CTS/test_common/harness/testHarness.cpp:730
    #32 0x2adda4 in runTestHarnessWithCheck(int, char const**, int, test_definition*, int, unsigned long, test_status (*)(_cl_device_id*)) /home/kherbst/git/OpenCL-CTS/test_common/harness/testHarness.cpp:593
    #33 0x265ce8 in main /home/kherbst/git/OpenCL-CTS/test_conformance/math_brute_force/main.cpp:335
    #34 0x7ffff7249b89 in __libc_start_call_main (/lib64/libc.so.6+0x27b89) (BuildId: f888be5f5e7d58e04cabb8c675c7ab94e77dd68c)
    #35 0x7ffff7249c4a in __libc_start_main_alias_2 (/lib64/libc.so.6+0x27c4a) (BuildId: f888be5f5e7d58e04cabb8c675c7ab94e77dd68c)
    #36 0x239264 in _start (/home/kherbst/git/OpenCL-CTS/build/test_conformance/math_brute_force/test_bruteforce+0x239264) (BuildId: d1467f6f6bf5394865895fc77a04b2f5cfe1adbe)

0x63100012c860 is located 96 bytes inside of 66992-byte region [0x63100012c800,0x63100013cdb0)
freed by thread T7 here:
    #0 0x7ffff78d7fb8 in __interceptor_free.part.0 (/usr/lib64/libasan.so.8.0.0+0xd7fb8) (BuildId: 542ad02088f38edfdba9d4bfa465b2299f512d3e)
    #1 0x7fffef232970 in unsafe_free ../src/util/ralloc.c:301
    #2 0x7fffef2325e2 in ralloc_free ../src/util/ralloc.c:264
    #3 0x7fffefeb9742 in zink_batch_state_destroy ../src/gallium/drivers/zink/zink_batch.c:320
    #4 0x7fffeff328df in zink_context_destroy ../src/gallium/drivers/zink/zink_context.c:163
    #5 0x7fffef1b6c0f in _$LT$mesa_rust..pipe..context..PipeContext$u20$as$u20$core..ops..drop..Drop$GT$::drop::h4de9ac178ba0c4a5 ../src/gallium/frontends/rusticl/mesa/pipe/context.rs:630

previously allocated by thread T0 here:
    #0 0x7ffff78d92ef in malloc (/usr/lib64/libasan.so.8.0.0+0xd92ef) (BuildId: 542ad02088f38edfdba9d4bfa465b2299f512d3e)
    #1 0x7fffef231e4c in ralloc_size ../src/util/ralloc.c:118
    #2 0x7fffef232046 in rzalloc_size ../src/util/ralloc.c:152
    #3 0x7fffefeb989f in create_batch_state ../src/gallium/drivers/zink/zink_batch.c:331
    #4 0x7fffefebb039 in get_batch_state ../src/gallium/drivers/zink/zink_batch.c:463
    #5 0x7fffefebb15d in zink_reset_batch ../src/gallium/drivers/zink/zink_batch.c:481
    #6 0x7fffefebbad8 in zink_start_batch ../src/gallium/drivers/zink/zink_batch.c:516
    #7 0x7fffeffa2499 in zink_context_create ../src/gallium/drivers/zink/zink_context.c:5452
    #8 0x7fffef1c02b9 in mesa_rust::pipe::screen::PipeScreen::create_context::h709574763dc18213 ../src/gallium/frontends/rusticl/mesa/pipe/screen.rs:108
    #9 0x280c9f in TestFunc_Float_Float(Func const*, _MTdata*, bool) /home/kherbst/git/OpenCL-CTS/test_conformance/math_brute_force/unary_float.cpp:551
    #10 0x262e3c in doTest /home/kherbst/git/OpenCL-CTS/test_conformance/math_brute_force/main.cpp:184
    #11 0x262ff3 in operator() /home/kherbst/git/OpenCL-CTS/test_conformance/math_brute_force/main.cpp:258
    #12 0x26302b in _FUN /home/kherbst/git/OpenCL-CTS/test_conformance/math_brute_force/main.cpp:258
    #13 0x2aeb0c in callSingleTestFunction(test_definition, _cl_device_id*, test_harness_config const&) /home/kherbst/git/OpenCL-CTS/test_common/harness/testHarness.cpp:939
    #14 0x2ae572 in callTestFunctions(test_definition*, unsigned char*, test_status*, int, _cl_device_id*, test_harness_config const&) /home/kherbst/git/OpenCL-CTS/test_common/harness/testHarness.cpp:818
    #15 0x2ae276 in parseAndCallCommandLineTests(int, char const**, _cl_device_id*, int, test_definition*, test_harness_config const&) /home/kherbst/git/OpenCL-CTS/test_common/harness/testHarness.cpp:730
    #16 0x2adda4 in runTestHarnessWithCheck(int, char const**, int, test_definition*, int, unsigned long, test_status (*)(_cl_device_id*)) /home/kherbst/git/OpenCL-CTS/test_common/harness/testHarness.cpp:593
    #17 0x265ce8 in main /home/kherbst/git/OpenCL-CTS/test_conformance/math_brute_force/main.cpp:335
    #18 0x7ffff7249b89 in __libc_start_call_main (/lib64/libc.so.6+0x27b89) (BuildId: f888be5f5e7d58e04cabb8c675c7ab94e77dd68c)
    #19 0x7ffff7249c4a in __libc_start_main_alias_2 (/lib64/libc.so.6+0x27c4a) (BuildId: f888be5f5e7d58e04cabb8c675c7ab94e77dd68c)
    #20 0x239264 in _start (/home/kherbst/git/OpenCL-CTS/build/test_conformance/math_brute_force/test_bruteforce+0x239264) (BuildId: d1467f6f6bf5394865895fc77a04b2f5cfe1adbe)

Thread T7 created by T0 here:
    #0 0x7ffff7848956 in pthread_create (/usr/lib64/libasan.so.8.0.0+0x48956) (BuildId: 542ad02088f38edfdba9d4bfa465b2299f512d3e)
    #1 0x7fffef1ed77e in std::sys::unix::thread::Thread::new::h2d9fc81e7101c8c8 library/std/src/sys/unix/thread.rs:87
    #2 0x280c9f in TestFunc_Float_Float(Func const*, _MTdata*, bool) /home/kherbst/git/OpenCL-CTS/test_conformance/math_brute_force/unary_float.cpp:551
    #3 0x262e3c in doTest /home/kherbst/git/OpenCL-CTS/test_conformance/math_brute_force/main.cpp:184
    #4 0x262ff3 in operator() /home/kherbst/git/OpenCL-CTS/test_conformance/math_brute_force/main.cpp:258
    #5 0x26302b in _FUN /home/kherbst/git/OpenCL-CTS/test_conformance/math_brute_force/main.cpp:258
    #6 0x2aeb0c in callSingleTestFunction(test_definition, _cl_device_id*, test_harness_config const&) /home/kherbst/git/OpenCL-CTS/test_common/harness/testHarness.cpp:939
    #7 0x2ae572 in callTestFunctions(test_definition*, unsigned char*, test_status*, int, _cl_device_id*, test_harness_config const&) /home/kherbst/git/OpenCL-CTS/test_common/harness/testHarness.cpp:818
    #8 0x2ae276 in parseAndCallCommandLineTests(int, char const**, _cl_device_id*, int, test_definition*, test_harness_config const&) /home/kherbst/git/OpenCL-CTS/test_common/harness/testHarness.cpp:730
    #9 0x2adda4 in runTestHarnessWithCheck(int, char const**, int, test_definition*, int, unsigned long, test_status (*)(_cl_device_id*)) /home/kherbst/git/OpenCL-CTS/test_common/harness/testHarness.cpp:593
    #10 0x265ce8 in main /home/kherbst/git/OpenCL-CTS/test_conformance/math_brute_force/main.cpp:335
    #11 0x7ffff7249b89 in __libc_start_call_main (/lib64/libc.so.6+0x27b89) (BuildId: f888be5f5e7d58e04cabb8c675c7ab94e77dd68c)
    #12 0x7ffff7249c4a in __libc_start_main_alias_2 (/lib64/libc.so.6+0x27c4a) (BuildId: f888be5f5e7d58e04cabb8c675c7ab94e77dd68c)
    #13 0x239264 in _start (/home/kherbst/git/OpenCL-CTS/build/test_conformance/math_brute_force/test_bruteforce+0x239264) (BuildId: d1467f6f6bf5394865895fc77a04b2f5cfe1adbe)

Merge request reports