Fix crash reading variable-length region reference data - #2966
Conversation
Reading a dataset whose datatype is a variable-length sequence of region references segfaulted. `conv_vlen2ndarray` allocates the background buffer for the element conversion with `emalloc` and never initializes it, and `conv_regref2pyref` treats that buffer as the existing destination value and releases it, so it decrefs whatever pointer was left on the heap. Object references never hit this: they register with `H5T_BKG_NO` and never read the buffer.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #2966 +/- ##
==========================================
+ Coverage 90.47% 90.52% +0.04%
==========================================
Files 16 16
Lines 2521 2532 +11
==========================================
+ Hits 2281 2292 +11
Misses 240 240 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Vlen regionref tests are removed until this bug is fixed, see PR h5py#2966.
|
Forgot to mention, I used |
|
I plan to merge this on September 7, unless changes are requested before then. |
|
It's September 8, so feel free to merge now if you want but just as a note, I'm finally going back to my backlog and I could review this after lunch (a couple hours from now) if that's still on the table. |
| PyBuffer_Release(&view) | ||
|
|
||
| if needs_bkg_buffer(intype.id, outtype.id): | ||
| # Zeroed for the same reason as in conv_vlen2ndarray above |
There was a problem hiding this comment.
I'd prefer the comment be copied verbatim, in case the other one ever changes or goes away and this becomes a dead ref
Let me get this straight: |
I forgot yesterday was a holiday in the US. 😁
You are not misunderstanding it, there is no such condition.
So As for where the behavior is defined: the This is also why object references never tripped on this bug: |
… after h5py#2966 was merged
Reading a dataset whose datatype is a variable-length sequence of region references segfaults:
This bug was revealed by failing CI workflows in my other PR #2964.
conv_vlen2ndarrayallocates the background buffer for the element conversion withemallocand never initializes it.conv_regref2pyreftreats that buffer as holding the existing destination value and releases it:so it decrefs whatever pointer happened to be on the heap. The gdb backtrace lands in
_Py_DECREFwith a garbageop, three frames belowconv_vlen2ndarray.Object references never hit this because they register with
H5T_BKG_NOand never read the buffer, while region references registerH5T_BKG_YES. That asymmetry is exactly whyvlen_dtype(ref_dtype)is fine andvlen_dtype(regionref_dtype)is not. MacOS escapes because its allocator hands back zeroed pages.Fix
Zero the buffer after allocating it, in both
conv_vlen2ndarrayandconv_ndarray2vlen.The second function is not causing any crash but it is the same unzeroed allocation, and garbage there would reach unwritten compound fields. Fixing one and not the other seemed worse than fixing both.