Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2022-04-27 16:59:18 +0300
committerClément Foucault <foucault.clem@gmail.com>2022-04-27 17:01:41 +0300
commit478eb3a0e6edeb84caacbc294a5f331b497a5e21 (patch)
tree65180ce68abc56fb8a389c07083b00d184595ccb
parentc01e33d6caf64812bf24cf52609b7115c78fa01b (diff)
GPUCodegen: Keep copy of attribute name in the GPUCodegenCreateInfo
This is to avoid use after free when the `GPUPass` gets compiled after the original `GPUMaterial` used to create it was freed. The issue was introduced by rBfa3bd17ae873
-rw-r--r--source/blender/gpu/intern/gpu_codegen.cc15
1 files changed, 14 insertions, 1 deletions
diff --git a/source/blender/gpu/intern/gpu_codegen.cc b/source/blender/gpu/intern/gpu_codegen.cc
index 1f929c4fcd0..540f87cfc46 100644
--- a/source/blender/gpu/intern/gpu_codegen.cc
+++ b/source/blender/gpu/intern/gpu_codegen.cc
@@ -47,8 +47,16 @@
using namespace blender::gpu::shader;
+/**
+ * IMPORTANT: Never add external reference. The GPUMaterial used to create the GPUPass (and its
+ * GPUCodegenCreateInfo) can be free before actually compiling. This happens if there is an update
+ * before deferred compilation happens and the GPUPass gets picked up by another GPUMaterial
+ * (because of GPUPass reuse).
+ */
struct GPUCodegenCreateInfo : ShaderCreateInfo {
struct NameBuffer {
+ /** Duplicate attribute names to avoid reference the GPUNodeGraph directly. */
+ char attr_names[16][GPU_MAX_SAFE_ATTR_NAME + 1];
char var_names[16][8];
};
@@ -290,9 +298,14 @@ void GPUCodegen::generate_attribs()
int slot = 15;
LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph.attributes) {
+ if (slot == -1) {
+ BLI_assert_msg(0, "Too many attributes");
+ break;
+ }
+ STRNCPY(info.name_buffer->attr_names[slot], attr->name);
SNPRINTF(info.name_buffer->var_names[slot], "v%d", attr->id);
- blender::StringRefNull attr_name = attr->input_name;
+ blender::StringRefNull attr_name = info.name_buffer->attr_names[slot];
blender::StringRefNull var_name = info.name_buffer->var_names[slot];
eGPUType input_type, iface_type;