diff options
author | Sergey Sharybin <sergey@blender.org> | 2021-05-11 18:53:09 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey@blender.org> | 2021-05-12 10:41:02 +0300 |
commit | 7f3436363388af9e9fe5c8578dee8997c078bb16 (patch) | |
tree | 4b4f3e73996eba88653ff6b229f8eb51c8945192 /intern/cycles/kernel/closure/alloc.h | |
parent | 0e3475a0ec9f2ccaa56eb8dd2a7358a125750805 (diff) |
Cycles X: Fix possible use of uninitialized ShaderClosure
It is possible that BSDF allocation will advance pointer in the
allocation "pool" but will return null pointer if the weight is
too small.
One artist-measurable issue this change fixes is random issues
with denoising: normal pass for denoising could have accessed
non-initialized normal of a closure.
Differential Revision: https://developer.blender.org/D11230
Diffstat (limited to 'intern/cycles/kernel/closure/alloc.h')
-rw-r--r-- | intern/cycles/kernel/closure/alloc.h | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/intern/cycles/kernel/closure/alloc.h b/intern/cycles/kernel/closure/alloc.h index 341d1e16eb1..5b74a868e72 100644 --- a/intern/cycles/kernel/closure/alloc.h +++ b/intern/cycles/kernel/closure/alloc.h @@ -57,14 +57,22 @@ ccl_device ccl_addr_space void *closure_alloc_extra(ShaderData *sd, int size) ccl_device_inline ShaderClosure *bsdf_alloc(ShaderData *sd, int size, float3 weight) { - ShaderClosure *sc = closure_alloc(sd, size, CLOSURE_NONE_ID, weight); + const float sample_weight = fabsf(average(weight)); - if (sc == NULL) - return NULL; + /* Use comparison this way to help dealing with non-finite weight: if the average is not finite + * we will not allocate new closure. */ + if (sample_weight >= CLOSURE_WEIGHT_CUTOFF) { + ShaderClosure *sc = closure_alloc(sd, size, CLOSURE_NONE_ID, weight); + if (sc == NULL) { + return NULL; + } + + sc->sample_weight = sample_weight; - float sample_weight = fabsf(average(weight)); - sc->sample_weight = sample_weight; - return (sample_weight >= CLOSURE_WEIGHT_CUTOFF) ? sc : NULL; + return sc; + } + + return NULL; } #ifdef __OSL__ @@ -73,17 +81,25 @@ ccl_device_inline ShaderClosure *bsdf_alloc_osl(ShaderData *sd, float3 weight, void *data) { - ShaderClosure *sc = closure_alloc(sd, size, CLOSURE_NONE_ID, weight); + const float sample_weight = fabsf(average(weight)); - if (!sc) - return NULL; + /* Use comparison this way to help dealing with non-finite weight: if the average is not finite + * we will not allocate new closure. */ + if (sample_weight >= CLOSURE_WEIGHT_CUTOFF) { + ShaderClosure *sc = closure_alloc(sd, size, CLOSURE_NONE_ID, weight); + if (!sc) { + return NULL; + } - memcpy((void *)sc, data, size); + memcpy((void *)sc, data, size); - float sample_weight = fabsf(average(weight)); - sc->weight = weight; - sc->sample_weight = sample_weight; - return (sample_weight >= CLOSURE_WEIGHT_CUTOFF) ? sc : NULL; + sc->weight = weight; + sc->sample_weight = sample_weight; + + return sc; + } + + return NULL; } #endif |