Skip to content

zeroize: tests::alloc::ProxyAllocator breaks test 32-bit ARM #1519

Description

@nc7s

We observed an assertion failure on armhf builds:

running 2 tests
test observe_secret_box_alloc_test ... ok
test secret_box_alloc_test ... ok

thread 'main' (265) panicked at tests/alloc.rs:20:17:
assertion `left == right` failed
  left: 4
 right: 0
stack backtrace:
panicked at tests/alloc.rs:20:17:

thread panicked while processing panic. aborting.
error: test failed, to rerun pass `--test alloc`

with a few sprinkles of eprintln!, we identified this:

tests::alloc::secret_box_alloc_test() -> b1 @ 0xf7600758, b2 @ 0xf7600800
tests::alloc::ProxyAllocator.alloc(ptr = 0xf7600800, layout = Layout { size: 160, align: 1 (1 << 0) })
tests::alloc::ProxyAllocator.alloc(ptr = 0xf78007c8, layout = Layout { size: 160, align: 1 (1 << 0) })
tests::alloc::ProxyAllocator.alloc(ptr = 0xf7800720, layout = Layout { size: 160, align: 8 (1 << 3) })
tests::alloc::ProxyAllocator.alloc(ptr = 0xf7600758, layout = Layout { size: 160, align: 8 (1 << 3) })
# all good until now
tests::alloc::ProxyAllocator.alloc(ptr = 0x1634900, layout = Layout { size: 160, align: 32 (1 << 5) })
# bummer
    byte @ 0: 4
# all 0s
    byte @ 16: 25
# all 0s
    byte @ 20: 216
    byte @ 21: 4
    byte @ 22: 99
    byte @ 23: 1
    byte @ 24: 2
# all 0s
    byte @ 32: 5
# all 0s
    byte @ 36: 168
    byte @ 37: 8
    byte @ 38: 96
    byte @ 39: 247
# all 0s
    byte @ 48: 48
# all 0s
    byte @ 56: 48
# all 0s
    byte @ 60: 25
# all 0s
    byte @ 76: 104
    byte @ 77: 15
    byte @ 78: 99
    byte @ 79: 1
# all 0s
    byte @ 88: 4
# all 0s
    byte @ 96: 1
# all 0s
    byte @ 104: 24
# all 0s
    byte @ 108: 56
    byte @ 109: 37
    byte @ 110: 99
    byte @ 111: 1
    byte @ 112: 24
# all 0s
    byte @ 124: 128
    byte @ 125: 38
    byte @ 126: 99
    byte @ 127: 1
# all 0s
    byte @ 136: 1
# all 0s
    byte @ 140: 2
# all 0s
    byte @ 144: 24
# all 0s
    byte @ 148: 144
    byte @ 149: 27
    byte @ 150: 99
    byte @ 151: 1
    byte @ 152: 24
# all 0s
    byte @ 156: 24
# all 0s

The byte pattern of the failing assert is actually the same every time, at least on the same machine.

Note that the successful ones are all in the range 0xf7600000 and 0xf7800000, while the failing one is at 0x1634900, very far away.

Also note that the failing assertion has an alignment of 32, while the two layouts checked in the test are either 1 ([u8; 160]) or 8 ([u128; 10]).

It seems that the layout.size == 160 check alone doesn't narrow it down enough to the tests, and other deallocations slipped in.

As for why it only happens on 32-bit ARM I do not know. Maybe some other allocation pattern happens to be 160 in size only on 32-bit ARM.

It might be better to compare the full Layout, rather than only the size.

For reference, ProxyAllocator was introduced in #1199.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions