Don't allow to pass bad child into tree.__setstate__ to avoid memory corruption and crash
Hello up there. To test my module that computes diff for BTrees I was playing with manually creating BTrees with different topologies[1,2] and hit the following bug that was leading to segmentation faults: C implementation of Tree.__setstate__ allows to pass in arbitrary objects in place of children and casts child to (Bucket*) if child type is not type of the tree _without further checking that type of the child is actually Bucket_ This leads to crashes when later the code, that is accessing tree nodes, goes to leafs, accesses passed in objects assuming they are buckets with corresponding C-level Bucket structure layout, and oops dereferences e.g. Bucket->keys, or Bucket->values from memory initialized via non-Bucket C-level data. -> Fix it by allowing to pass into tree.__setstate__ only children of either tree or bucket types. Note: for tree kind the type is checked exactly, because in many places C implementation already does `if (SameType_Check(tree, X))` and assumes X is of bucket kind if that check fails. For buckets we accept tree._bucket_type subclasses as they are handled correctly and bucket type for tree.firstbucket is already verified via "isinstance". Kirill P.S. test___setstate___to_multiple_buckets is adjusted to avoid test failures because Test_Tree._makeOne() was creating tree with ._bucket_type different from _Bucket defined in that test. [1] https://lab.nexedi.com/kirr/wendelin.core/blob/28010b7/wcfs/internal/xbtree.py [2] https://lab.nexedi.com/kirr/wendelin.core/blob/28010b7/wcfs/internal/xbtree_test.py /helped-by @jamadden
Showing
Please register or sign in to comment