Skip to content

fix: guard non-string JSON type fields before strcmp in C API driver#165

Open
ramakrishnap-nv wants to merge 1 commit into
mainfrom
fix/c-api-driver-json-null-deref
Open

fix: guard non-string JSON type fields before strcmp in C API driver#165
ramakrishnap-nv wants to merge 1 commit into
mainfrom
fix/c-api-driver-json-null-deref

Conversation

@ramakrishnap-nv

Copy link
Copy Markdown
Collaborator

Summary

parse_cuopt_json() in benchmark_apis/c_api_driver/cuopt_json_to_c_api.c read JSON array
elements via cJSON's valuestring and passed them straight to strcmp(). cJSON sets
valuestring to NULL for non-string nodes (numbers, bools, null, arrays, objects), so a
non-string element produced strcmp(NULL, ...) — a NULL-pointer dereference that crashes the
driver (SIGSEGV; UBSan nonnull violation) on untrusted cuOpt-JSON input.

Two sinks were affected:

  • variable_types[] parsing loop (strcmp(type_str, "I"))
  • constraint_bounds.types[] fallback (strcmp(type, "L"|"G"|"E"))

Fix

Guard both sinks with cJSON_IsString() + a NULL check before each strcmp, falling back to
the existing default (CONTINUOUS variable / unconstrained row) for non-string entries. This
matches the cJSON_IsString(...) ? ... : NULL pattern already used in parse_numeric_value().

Reproducer

{
  "csr_constraint_matrix": {"offsets": [0, 1], "indices": [0], "values": [1.0]},
  "objective_data": {"coefficients": [1.0], "offset": 0.0},
  "variable_bounds": {"lower_bounds": [0.0], "upper_bounds": [0.0]},
  "maximize": false,
  "variable_types": [123]
}

A non-string constraint_bounds.types element (e.g. "types": [123]) triggers the same crash
on the G/E branches.

Verification

Built the translation unit under ASan + UBSan (real parser, stubbed solver). Both a
number-valued variable_types element and a number-valued constraint_bounds.types element
crashed with a SEGV in strcmp before the fix and parse cleanly after.

Found via fuzzing; robustness / availability hardening (not a production solver path).

🤖 Generated with Claude Code

parse_cuopt_json() read variable_types[] and the constraint_bounds.types[]
fallback via cJSON valuestring and passed the result straight to strcmp().
cJSON sets valuestring to NULL for non-string nodes (numbers, bools, null,
arrays, objects), so a non-string element produced strcmp(NULL, ...), which
dereferences a NULL pointer and crashes (SIGSEGV; UBSan nonnull violation)
on untrusted cuOpt-JSON input.

Guard both sinks with cJSON_IsString() plus a NULL check before each strcmp,
falling back to the default (CONTINUOUS variable / unconstrained row) for
non-string entries.

Verified under ASan/UBSan: both a number-valued variable_types element and a
number-valued constraint_bounds.types element crashed before the fix and parse
cleanly after.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Ramakrishna Prabhu <ramakrishnap@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant