From: Gurchetan Singh Date: Tue, 1 Aug 2017 22:02:24 +0000 (-0700) Subject: minigbm: cros_gralloc: fix initialization race condition X-Git-Url: http://git.osdn.net/view?p=android-x86%2Fexternal-minigbm.git;a=commitdiff_plain;h=bcfd758b6de740e13c2cc2dc1f9374111c896448 minigbm: cros_gralloc: fix initialization race condition On Android M, since we don't hold a lock during cros_gralloc_driver::init(), another thread would sometimes access data before the driver was initialized. This would lead to dEQP crashes. We don't experience this issue on Android N since the framework has it's own layer of locks in the Gralloc1On0Adapter. This patch makes the module initialization during (*registerBuffer) and gralloc_open re-entrant. BUG=b:63511976 TEST=run cts --package com.drawelements.deqp.gles2 on veyron_tiger has no crashes Change-Id: I2b72f2f8ed5e4a5afbacb291ed8cd928beb2a3b3 Reviewed-on: https://chromium-review.googlesource.com/597015 Commit-Ready: Gurchetan Singh Tested-by: Gurchetan Singh Reviewed-by: Stéphane Marchesin Reviewed-by: Tomasz Figa --- diff --git a/cros_gralloc/gralloc0/gralloc0.cc b/cros_gralloc/gralloc0/gralloc0.cc index ec897be..e62c670 100644 --- a/cros_gralloc/gralloc0/gralloc0.cc +++ b/cros_gralloc/gralloc0/gralloc0.cc @@ -13,6 +13,8 @@ struct gralloc0_module { gralloc_module_t base; std::unique_ptr alloc; std::unique_ptr driver; + bool initialized; + std::mutex initialization_mutex; }; /* This enumeration must match the one in . @@ -128,11 +130,38 @@ static int gralloc0_close(struct hw_device_t *dev) return 0; } +static int gralloc0_init(struct gralloc0_module *mod, bool initialize_alloc) +{ + std::lock_guard lock(mod->initialization_mutex); + + if (mod->initialized) + return 0; + + mod->driver = std::make_unique(); + if (mod->driver->init()) { + cros_gralloc_error("Failed to initialize driver."); + return -ENODEV; + } + + if (initialize_alloc) { + mod->alloc = std::make_unique(); + mod->alloc->alloc = gralloc0_alloc; + mod->alloc->free = gralloc0_free; + mod->alloc->common.tag = HARDWARE_DEVICE_TAG; + mod->alloc->common.version = 0; + mod->alloc->common.module = (hw_module_t *)mod; + mod->alloc->common.close = gralloc0_close; + } + + mod->initialized = true; + return 0; +} + static int gralloc0_open(const struct hw_module_t *mod, const char *name, struct hw_device_t **dev) { auto module = (struct gralloc0_module *)mod; - if (module->alloc) { + if (module->initialized) { *dev = &module->alloc->common; return 0; } @@ -142,20 +171,8 @@ static int gralloc0_open(const struct hw_module_t *mod, const char *name, struct return -EINVAL; } - module->driver = std::make_unique(); - if (module->driver->init()) { - cros_gralloc_error("Failed to initialize driver."); - return -ENOMEM; - } - - module->alloc = std::make_unique(); - - module->alloc->alloc = gralloc0_alloc; - module->alloc->free = gralloc0_free; - module->alloc->common.tag = HARDWARE_DEVICE_TAG; - module->alloc->common.version = 0; - module->alloc->common.module = (hw_module_t *)mod; - module->alloc->common.close = gralloc0_close; + if (gralloc0_init(module, true)) + return -ENODEV; *dev = &module->alloc->common; return 0; @@ -165,13 +182,9 @@ static int gralloc0_register_buffer(struct gralloc_module_t const *module, buffe { auto mod = (struct gralloc0_module *)module; - if (!mod->driver) { - mod->driver = std::make_unique(); - if (mod->driver->init()) { - cros_gralloc_error("Failed to initialize driver."); - return -ENOMEM; - } - } + if (!mod->initialized) + if (gralloc0_init(mod, false)) + return -ENODEV; return mod->driver->retain(handle); } @@ -380,4 +393,5 @@ struct gralloc0_module HAL_MODULE_INFO_SYM = { .alloc = nullptr, .driver = nullptr, + .initialized = false, };