Skip to content

[CRASH] Crash in dlg_onreply() (rpl = 0xffffffffffffffff) when B2B sends 408 Request Timeout after INVITE expires #3750

@fikinway

Description

@fikinway

Description

OpenSIPS 3.6.2 (x86_64) crashes consistently when running as a B2BUA using the b2b_logic and b2b_entities modules.
If an INVITE transaction remains unanswered (no 200 OK or 4xx/5xx) for about 2 minutes, OpenSIPS aborts with a segmentation fault.

The crash occurs when the B2B cleanup timer triggers a 408 Request Timeout response.


Environment

  • Version: OpenSIPS 3.6.2 (built from source)
  • Modules: tm, dialog, b2b_logic, b2b_entities, load_balancer, nathelper, proto_udp
  • OS: CentOS 7 (x86_64)
  • Build type: Release (no local patches)
  • Database: MySQL (for opensips and b2b_entities)
  • Mode: B2BUA (dual UDP sockets for internal/external SIP)
  • Core dumps: Enabled and reproducible

Steps to Reproduce

  1. Use a configuration similar to:

    loadmodule "tm.so"
    modparam("tm", "pass_provisional_replies", 1)
    
    loadmodule "b2b_entities.so"
    loadmodule "b2b_logic.so"
    modparam("b2b_logic", "cleanup_period", 60)
    modparam("b2b_logic", "b2bl_th_init_timeout", 60)
    
    route {
        if (is_method("INVITE")) {
            b2b_server_new("caller");
            if (load_balance(1, "fs")) {
                b2b_client_new("b2b-$ci", "$du");
                b2b_init_request("prepaid");
                exit;
            }
        }
    }
    
    route[b2b_logic_request] { b2b_pass_request(); }
    route[b2b_logic_reply]   { b2b_handle_reply(); }
  2. Send an INVITE through OpenSIPS where the downstream endpoint never replies (no 200/4xx/5xx).

  3. Wait approximately 120 seconds.

  4. OpenSIPS crashes when attempting to send a generated 408 Request Timeout.


Expected Behavior

OpenSIPS should gracefully generate and send a 408 Request Timeout reply and release all related B2B/transaction resources.


Actual Behavior

OpenSIPS crashes with a segmentation fault in dlg_onreply() when processing the 408 timeout callback.


Backtrace

#0  context_put_int (type=CONTEXT_GLOBAL, data=1, pos=4, ctx=<optimized out>)
#1  dlg_onreply (t=0x7f1c507ac350, type=<optimized out>, param=<optimized out>)
    rpl = 0xffffffffffffffff
#2  run_any_trans_callbacks (code=408, rpl=0x7f1c507d89f8, req=0x7f1c507dddf8, trans=0x7f1c507ac350, type=64)
#3  run_trans_callbacks_locked (...)
#4  _reply_light (...)
#5  _reply_with_body (...)
#6  t_reply_with_body (...)
#7  _b2b_send_reply (dlg=?, rpl_data=?)
#8  term_entity (entity=?, key=?, hash_index=?)
#9  b2bl_clean (ticks=?, param=?)
#10 handle_timer_job ()

At frame #1, the rpl pointer is 0xffffffffffffffff, which causes dlg_onreply() to crash when it tries to access SIP context data.


Analysis

  • The crash occurs in the b2bl_clean()_b2b_send_reply()t_reply_with_body() path, during a B2B-generated timeout cleanup.
  • The tm module executes transaction callbacks and invokes dlg_onreply() from the dialog module.
  • However, the rpl pointer passed to the callback is invalid (-1), likely because the transaction or SIP message was already released by B2B cleanup.
  • This suggests a use-after-free or invalid pointer race between b2b_logic and tm callback chains.

Temporary Workaround

Increase TM and B2B timeout parameters to prevent frequent triggering of the cleanup path:

modparam("tm", "fr_inv_timeout", 300)
modparam("b2b_logic", "cleanup_period", 300)
modparam("b2b_logic", "b2bl_th_init_timeout", 120)

This mitigates the issue by avoiding early 408 timeouts.


Suggested Fix Direction

  • Validate rpl pointer in dlg_onreply() before dereferencing (NULL or (void*)-1 checks).
  • Ensure b2b_logic does not call t_reply_with_body() after the transaction is destroyed.
  • Possibly synchronize between b2b_logic cleanup and tm callback execution.

Attachments

  • Core dump (available on request)
  • Tested version: OpenSIPS 3.6.2

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