Skip to content

Unwind Issue: How to make a loop inductive? #8353

Closed
@QinyuanWu

Description

@QinyuanWu

I'm verifying the SymCrypt library and I'm running into unwinding failure for the SymCryptWipeAsm function, which is a simple loop that sets the buffer to 0, but because the loop iteration depends on cbData, I believe CBMC want to unwind it to the max value of cbData(under the proof constrain of 1024). I'm trying to specify invariants to make this loop inductive so that CBMC only unwinds once. I've also tried using __CPROVER_ensures with __CPROVER_forall as specified in this documentation, but I got a parsing error from goto-cc.
Harness(SymCryptWipeAsm is implemented here to overwrite the assembly version):

#include <stdlib.h>
#include "symcrypt.h"

SYMCRYPT_ENVIRONMENT_LINUX_USERMODE

void harness(void)
{
    SIZE_T cbData; // unconstrained value
    PBYTE pbData;
    BYTE abResult[SYMCRYPT_SHA256_RESULT_SIZE];

    __CPROVER_assume(cbData <= 1024);
    pbData = malloc( cbData );

    __CPROVER_assume(pbData != NULL);

    SymCryptSha256( pbData, cbData, abResult );

    free(pbData);
}

VOID
SYMCRYPT_CALL
SymCryptWipeAsm( _Out_writes_bytes_( cbData ) PVOID pbData, SIZE_T cbData )
{
    volatile BYTE * p = (volatile BYTE *) pbData;
    SIZE_T i;

    __CPROVER_assume( pbData != NULL );
    __CPROVER_assume( __CPROVER_w_ok( pbData, cbData ) );

    for( i=0; i<cbData; i++ )
    __CPROVER_loop_invariant( 0 <= i && i < cbData )
    __CPROVER_decreases( cbData - i )
    {
        p[i] = 0;
    }

/* What I've also tried but got parsing error:
    for( i=0; i<cbData; i++ )
    __CPROVER_ensures(__CPROVER_forall {
    SIZE_T i;
    (0 <= i && i < SIZE_MAX) ==>
      p[i]==0
  })
    {
        p[i] = 0;
    }
*/

}

Related source files:
PROJECT_SOURCES += $(SRCDIR)/lib/sha256.c
PROJECT_SOURCES += $(SRCDIR)/lib/env_linuxUserMode.c
PROJECT_SOURCES += $(SRCDIR)/lib/libmain.c
PROJECT_SOURCES += $(SRCDIR)/lib/sha256Par.c
image

CBMC version: 5.95.1
Operating system: WSL
What behaviour did you expect: The loop become inductive and CBMC unwind once
What happened instead: unwinding failure for unwind --32
Please let me know if you need more information and I appreciate the help!

Metadata

Metadata

Assignees

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