Skip to content

Unsoundness in SIF due to encoding of object allocation #152

Closed
@tobycmurray

Description

@tobycmurray

The modular product program encoding assumes that any object allocation reached in both executions produces an object reference that is low. However real allocators don’t behave that way: allocation decisions depend on what previous allocations have occurred. The following example demonstrates this potential unsoundness in current Nagini:

from nagini_contracts.contracts import *

class MyObject(object):
    pass

def sif_print_str(x: str) -> None:
    Requires(Low(x))
    Requires(LowVal(x))
    pass

def test(x: int) -> None:
    if x > 0:
      m1 = MyObject()
    m2 = MyObject()
    sif_print_str(str(m2))

Nagini verifies this correctly (using command line nagini –sif true). Yet on my machine, the first allocation always yields an object whose least significant 8 bits of the address exposed in its str is “c0” while for the second allocation these bits are reliably “60” instead.

$ python
Python 3.8.13 (default, Apr 19 2022, 00:53:22) 
[GCC 7.5.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> class MyObject(object):
...     pass
... 
>>> m1 = MyObject()
>>> m2 = MyObject()
>>> str(m1)
'<__main__.MyObject object at 0x7f214e94d4c0>'
>>> str(m2)
'<__main__.MyObject object at 0x7f214e8a5d60>'

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions