Skip to content

Unbounded recursion in from_der_ causes stack overflow on nested context-specific DER input #41

@tynus3

Description

@tynus3

Hi,

I found a reachable stack-overflow DoS in simple_asn1 and would like to flag it for your evaluation.

Summary

from_der_ (src/lib.rs:341-383) decodes a sequence of TLVs. When it meets a constructed tag whose class is not Universal (i.e. Application, Context-Specific, or Private), it speculatively recurses into the body to decode it as an "explicit-tagged" wrapper:

// src/lib.rs:358-372
if class != ASN1Class::Universal {
    if constructed {
        // Try to read as explicitly tagged
        if let Ok(mut items) = from_der_(body, start_offset + index) {
            //                   ^^^^^^^^^ no depth parameter, no cap
            if items.len() == 1 {
                result.push(ASN1Block::Explicit(class, soff, tag, Box::new(items.remove(0))));
                // ...

Each nested context-specific constructed tag adds one frame to from_der_. No depth counter, no iteration cap, no configurable limit. grep -n "max_depth\|MAX_DEPTH\|recursion" src/lib.rs returns zero hits.

A payload of the form A0 02 A0 02 A0 02 … A0 00 (nested [0] context-specific constructed tags) exhausts the thread stack, triggers SIGSEGV on the guard page, and aborts the process.

I verified this on simple_asn1 0.6.4 (current as of April 2026, the latest release on crates.io, published February 12, 2026).

Verified test results

PoC built against simple_asn1 = "0.6" (resolves to 0.6.4). Run on a 256 KiB thread stack (std::thread::Builder::stack_size(256 * 1024)) for reproducible thresholds.

Depth Payload size Result
100 239 B OK
200 425 B OK
300 837 B OK
400 1,633 B stack-overflow abort (exit 134)
500 1,833 B stack-overflow abort
1000 3,833 B stack-overflow abort
20000 83,407 B stack-overflow abort

Minimum crash payload (hex)

Depth 400, 1,633 bytes. Structure is A0 82 XX XX wrapping A0 82 XX XX wrapping … A0 00 at the core. Generated by the PoC's build_nested_explicit(400) function.

Suggested fix

Add a depth counter to from_der_ and cap it.


Thanks for maintaining simple_asn1. Please let me know if anything else I should provide.

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