Skip to content

CBMC May Struggle with sscanf and strcmp Handling in Symbolic Execution? #8602

Open
@zhoulaifu

Description

@zhoulaifu

Dear CBMC Team,

Thank you for your incredible work on CBMC, which has been invaluable for our verification tasks. I am writing to kindly inquire if there might be a limitation or bug in CBMC 6.4.1 on Mac OS that prevents it from correctly handling sscanf and strcmp with symbolic strings. I’ve encountered unexpected counterexamples in my tests, and I’d greatly appreciate your guidance or confirmation if this is a known issue.

Test Program

Below is a minimal test program I’ve created to investigate this behavior:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#define MAX_BUFFER_SIZE 20

void harness_sscanf() {
    char buffer[MAX_BUFFER_SIZE];

    // Ensure the buffer is null-terminated within bounds
    __CPROVER_assume(buffer[MAX_BUFFER_SIZE - 1] == '\0');

    // Check if input starts with "Hello"
    if (sscanf(buffer, "Hello") == 0) {
        assert(0); // Force CBMC to find an input that starts with "Hello"
    }
}

void harness_strcmp() {
    char buffer[MAX_BUFFER_SIZE]; // Symbolic input buffer

    // Ensure the buffer is null-terminated within bounds
    __CPROVER_assume(buffer[MAX_BUFFER_SIZE - 1] == '\0');
    // Constrain buffer to have at least length 2 (for "Hello") and be reasonable
    __CPROVER_assume(strlen(buffer) >= 2 && strlen(buffer) < MAX_BUFFER_SIZE - 1);

    // Check if input exactly matches "Hello" using strcmp
    if (strcmp(buffer, "Hello") != 0) {
        assert(0); // Force CBMC to find an input that exactly matches "Hello"
    }
}

void harness_simple_check() {
    char buffer[MAX_BUFFER_SIZE]; // Symbolic input buffer

    // Ensure the buffer is null-terminated within bounds
    __CPROVER_assume(buffer[MAX_BUFFER_SIZE - 1] == '\0');
    // Optional: constrain length if needed (e.g., strlen(input) < 9)
    
    if (buffer[0] == 'H' && buffer[1] == 'e' && buffer[2] == 'l' && buffer[3] == 'l' && buffer[4] == 'o') {
        assert(0); // Fail if "HI......!" pattern matches
    }
}

Commands and Counterexamples

I ran the following commands on macOS ARM64 using CBMC 6.4.1:

For harness_sscanf

cbmc test_ssncf.c --function harness_sscanf --no-standard-checks --no-built-in-assertions --unwind 6 --trace

Counterexample Produced:

buffer={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }

For harness_strcmp

cbmc test_ssncf.c --function harness_strcmp --no-standard-checks --no-built-in-assertions --unwind 6 --trace

Counterexample Produced:

buffer={ 'I', 'd', 0, 2, '`', 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }

For harness_simple_check

cbmc test_ssncf.c --function harness_simple_check --no-standard-checks --no-built-in-assertions --unwind 6 --trace

Counterexample Produced:

 buffer={ 'H', 'e', 'l', 'l', 'o', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }

Expected Behavior

For the first two harnesses, I expected CBMC to produce a counterexample where buffer = "Hello\0..." (e.g., {'H', 'e', 'l', 'l', 'o', 0, 0, ..., 0}). This would indicate that CBMC successfully found an input that:

  • For harness_sscanf, starts with "Hello" (so sscanf(buffer, "Hello") == 1).
  • For harness_strcmp, exactly matches "Hello" (so strcmp(buffer, "Hello") == 0).

Environment

  • Operating System: macOS (ARM64, Apple Silicon M3)
  • CBMC Version: 6.4.1

In sum, this issue looks like a limitation or bug in CBMC 6.4.1 on macOS ARM64 that affects its handling of sscanf and strcmp with symbolic strings. The correct behavior of harness_simple_check suggests CBMC handles direct character comparisons well, but sscanf and strcmp struggle with constraint propagation or symbolic string modeling.

Thank you very much for your time and support!

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