Skip to content

SIGSEGV in QuicSendBufferFill After Connection Start Failure #6166

Description

@jack2007

Describe the bug

Summary

The Basic.ConnectionCloseFromCallback test reliably crashes with SIGSEGV
when ip6-localhost cannot be resolved. Address resolution fails during
connection startup, and the subsequent stream-send cleanup dereferences a null
list entry in QuicSendBufferFill().

Affected OS

  • Windows
  • Linux
  • macOS
  • Other (specify below)

Additional OS information

No response

MsQuic version

The issue was reproduced with the official MsQuic repository at:

Branch: main
Commit: c227199009273e328895e4c44ce2118571b3d5c6
Describe: v2.5.0-481-gc22719900
Test date: 2026-07-20


### Steps taken to reproduce bug

## Reproduction Environment

```text
Operating system: Linux
Architecture: x86-64
Build type: Release with debug information
Test executable: msquictest

The host does not define an IPv6 loopback hostname in /etc/hosts. In
particular, the following names and address are absent:

::1
ip6-localhost
ip6-loopback

The host only defines the IPv4 localhost entry:

127.0.0.1 localhost

The resolver state can be confirmed with:

getent hosts localhost
getent hosts ip6-localhost

Observed results:

$ getent hosts localhost
127.0.0.1       localhost

$ getent hosts ip6-localhost
# No output; exit status 2

Reproduction Conditions

The crash requires the following conditions:

  1. ip6-localhost does not resolve on the test host.
  2. Basic.ConnectionCloseFromCallback starts a connection using the address
    selected by the test's unspecified-address path.
  3. The Linux test path selects ip6-localhost for that connection.
  4. Address resolution fails while a stream send request is pending.
  5. Connection shutdown cancels the pending stream send request.

Steps to Reproduce

  1. Check out and build MsQuic, including msquictest.

  2. Ensure that ip6-localhost does not resolve:

    getent hosts ip6-localhost

    The command must produce no address and return a nonzero status.

  3. From the directory containing msquictest, run:

    ./msquictest --gtest_filter=Basic.ConnectionCloseFromCallback

Actual Result

The test process terminates with signal 11:

Segmentation fault (core dumped)

The shell commonly reports exit status 139.

Expected Result

The connection-start failure should be reported through the normal test or API
error path. Pending stream send requests should be cancelled safely, and the
test process should not crash.

Failure Sequence

GDB shows the following sequence:

  1. The test uses ip6-localhost as the server name.
  2. CxPlatDataPathResolveAddress() fails to resolve the name.
  3. QuicConnStart() enters local connection-close processing.
  4. Stream shutdown cancels a pending send request.
  5. QuicStreamCompleteSendRequest() calls QuicSendBufferFill().
  6. QuicSendBufferFill() advances through a null list link and crashes.

Resolver state captured immediately after the resolution failure:

ServerName = "ip6-localhost"
Status = 4294967293  # -3
RemoteAddress family = 0

GDB Backtrace

#0  QuicSendBufferFill
    at src/core/send_buffer.c:155
#1  QuicStreamCompleteSendRequest
    at src/core/stream_send.c:469
#2  QuicStreamCancelRequests
    at src/core/stream_send.c:1646
#3  QuicStreamSendShutdown
    at src/core/stream_send.c:188
#4  QuicStreamShutdown
    at src/core/stream.c:585
#5  QuicStreamSetShutdown
    at src/core/stream_set.c:222
#6  QuicConnTryClose
    at src/core/connection.c:1701
#7  QuicConnCloseLocally
    at src/core/connection.c:1745
#8  QuicConnStart
    at src/core/connection.c:2001
#9  QuicConnProcessApiOperation
    at src/core/connection.c:7850
#10 QuicConnDrainOperations
    at src/core/connection.c:8111

At the crash point:

Entry = 0x0

Connection->Send.SendStreams.Flink is non-null, but the stream link reached
by the traversal has a null Flink. The crash occurs when the loop at
Entry = Entry->Flink attempts to continue the traversal.

Expected behavior

The connection-start failure should be reported through the normal test or API
error path. Pending stream send requests should be cancelled safely, and the
test process should not crash.

Actual outcome

The test process terminates with signal 11:

Segmentation fault (core dumped)

The shell commonly reports exit status 139.

Additional details

No response

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

Status
No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions