Commit graph

34483 commits

Author SHA1 Message Date
Mike Bradeen
f0c1c1a7b7 res_pjsip_sdp_rtp: Fix intermittent call drop on reINVITE sdp change
A reINVITE that changed the offered codec set (e.g. ulaw+alaw -> alaw
only) could lead to call teardown when a bridge write still using the
old format occurred during the re-negotiation.

This change avoids the termination by making the following changes.

First, Asterisk now holds the lock across both the tx payload update
and the channel format update so they commit atomically.

Second, when processing the sdp on the new incoming offer, merge the
new offer with the old until the negotiation is complete.

Also adds unit tests for the sdp merge

Fixes: #2059
2026-08-06 15:45:49 +00:00
Sven Kube
926a1068f2 chan_websocket: Fix NULL requestor dereference in webchan_request.
Two log statements in webchan_request() passed `requestor` straight to
ast_channel_name(), which dereferences the channel with no NULL check.
`requestor` is NULL whenever no originator channel is supplied: ARI POST
/channels/externalMedia always passes NULL, and POST /channels/create
passes NULL when `originator` is omitted.
2026-08-05 17:42:23 +00:00
Naveen Albert
f6b02c640c backtrace.c: Include stdbool.h
stdbool.h is needed now that we use the bool type directly
instead of bfd_boolean. See also 1d95b744c06974f0a00c143c6e0fc979af930908.

Resolves: #2061
2026-08-05 12:48:38 +00:00
aabolfazl
c46c9945a8 res_musiconhold: Fix mohclass reference leak on answeredonly early return.
local_ast_moh_start() returns -1 from the answeredonly check without
releasing the mohclass reference it holds, unlike every other exit path
in the function. Nothing else ever releases that reference, so
moh_class_destructor() never runs for the object. With realtime music
on hold and cachertclasses disabled, each suppressed request leaks the
class object, its monitor thread, the external application process and
two file descriptors for the lifetime of Asterisk. For static classes
the stale references prevent the class from ever being destroyed after
it is replaced by a reload.

Release the reference before returning, matching the other exit paths.

Fixes: #2051
2026-08-04 17:24:47 +00:00
Naveen Albert
5b59829015 backtrace.c: Avoid removed bfd_boolean type.
bfd_boolean has been deprecated for some time and has now been
removed in gdb, so use bool directly instead.

See: 1d95b744c0

Resolves: #2054
2026-08-04 17:03:50 +00:00
Sean Bright
73064ff3bf app_voicemail.c: Fix may-be-uninitialized error
A pointer to `new` is passed to `inboxcount(...)` which increments the
pointed-to value.
2026-08-04 15:45:33 +00:00
Mike Bradeen
2720b1025e pjproject: disable building pjsua when a sanitizer is used
Disable building the pjsua test application when any of the
SANITIZER flags are set.

Fixes: #2056
2026-08-04 13:45:27 +00:00
George Joseph
b531f71b12 SECURITY.md: Add warning about reporting multiple issues in one advisory. 2026-08-04 13:08:20 +00:00
Mehrdad Seifzadeh
8cd58fd39d chan_pjsip: Store transport info for outgoing channels
Outgoing PJSIP channels did not have transport information stored in
their session datastore when CHANNEL(pjsip,local_addr) or
CHANNEL(pjsip,remote_addr) was read. As a result, the address fields
were empty on B-leg channels even though other dialog fields such as
call-id and URIs were available.

Store the selected local transport address and destination address for
outgoing UAC session requests once the request is transmitted and the
transport information is known.

Fixes: #871
2026-08-04 12:38:41 +00:00
aabolfazl
c05ac3f232 func_strings: Fix misspelling of "occurred" in FIELDNUM documentation.
The FIELDNUM description misspelled "occurred" as "occured". This text
is user-visible: it is rendered on docs.asterisk.org and printed by
"core show function FIELDNUM".
2026-07-31 15:14:53 +00:00
Jeremy Lainé
7c60726df1 tcptls: Don't inhibit escalations for outbound client connections.
handle_tcptls_connection() marks the current thread as inhibiting
privilege escalations and as an external user interface so that
dialplan functions considered 'dangerous' (STAT, SHELL, ...) cannot be
executed on behalf of an external protocol.

This is correct for inbound (server) connections, each of which runs on
its own dedicated worker thread. However, the outbound (client) path
calls handle_tcptls_connection() synchronously on the caller's own
thread. When that caller is a channel/PBX thread, the thread-local
flags are set and never cleared, permanently tainting the dialplan
thread.

Examples:

- Calling Dial() for an outbound WebSocket and resuming dialplan
  execution with the "g" flag.
- Running ExternalIVR() then continuing dialplan executing.

Outbound connections are initiated by Asterisk itself and are not
external user interfaces, so the flags should not be set for them. Gate
the flag-setting on tcptls_session->client so it applies only to inbound
connections.

Resolves: #2038
2026-07-27 12:01:00 +00:00
Mike Bradeen
734fb592bd res_rtp_asterisk: Avoid two lock inversion deadlocks with pj project
Fixes two related instance, group lock inversion deadlocks.

When writing the RTP stream via rtp_sendto, the RTP instance was only unlocked
before being passed to pj project when the instance was un-bundled (ie video
was not bundled onto the audio stream's ICE transport.)

The first change unlocks the instance whether bundled or unbundled to avoid the
deadlock, then re-checks the bundled status upon return to know wether or not the
transport should be used.

For the second change, when an incoming RTCP NACK record was recieved, the parent
(transport) and child (instance) locks were both held before the call to rtp_sendto,
which is only able to release the child lock. Now in the un-bundled case the parent
and child will be unlocked and re-locked in the correct order via a new helper
function before and after the call to send_to.

Fixes: #1946
2026-07-27 11:56:30 +00:00
Stanislav Abramenkov
05dbd160ea jansson: Upgrade version to jansson 2.15.1
UpgradeNote: jansson has been upgraded to 2.15.1. For more
information visit jansson Github page: https://github.com/akheron/jansson/releases/tag/v2.15.1

Resolves: #2033
2026-07-27 11:55:13 +00:00
Jeremy Lainé
b31d3b1d57 file.c: Ensure opening a stream opens at most one file
The functions used to stream files eventually end up calling into
`filehelper(.., ACTION_OPEN)` which takes care of iterating over
supported extensions and opening the first existing file.

To do this, `filehelper` uses two nested loops:

- An outer loop over the supported file formats.
- An inner loop over the possible extensions for that format.

We need to break out of both loops as soon as a file was successfully
opened. Otherwise if a file exists in multiple formats (e.g `foo.wav`
and `foo.alaw`) both files will be opened successively.

Resolves: #1625
2026-07-27 11:49:02 +00:00
Joshua C. Colp
ad429910c6 pjsip: Eliminate some unique taskprocessors.
When placing outbound calls each call would get its own
taskprocessor for things related to the call. In practice this
is overkill as few things actually occur. Inbound calls on
the other hand already use one of the fixed number of
distributor taskprocessors. This also occurred for OPTIONS
requests with each AOR having its own taskprocessor.

This change moves both to using a distributor taskprocessor
instead.
2026-07-27 11:48:48 +00:00
Roel van Meer
e22687d0bd bridging: Add support for TOUCH_MIXMONITOR_OPTIONS
This channel variable can be used to override the default automixmon
options (which are 'b' or 'bB(<n>)'). If both TOUCH_MIXMONITOR_OPTIONS
and TOUCH_MIXMONITOR_BEEP are set, TOUCH_MIXMONITOR_BEEP is ignored with
a warning.
It is the responsibility of the user to configure valid options in
TOUCH_MIXMONITOR_OPTIONS.

Fixes: #1981

UserNote: The TOUCH_MIXMONITOR_OPTIONS channel variable can now be used
to configure the options used by the mixmonitor application when it is
started via automixmon. If both TOUCH_MIXMONITOR_OPTIONS and
TOUCH_MIXMONITOR_BEEP are set, TOUCH_MIXMONITOR_BEEP is ignored with
a warning.
2026-07-21 12:11:33 +00:00
George Joseph
1480af1227 res_pjsip_refer: Fix issues with Refer-Sub:false and ARI.
When an attended transfer is controlled by ARI using
PJSIP_TRANSFER_HANDLING()=ari-only, and a REFER request is received with
a Refer-Sub: false header to suppress the automatic progress
subscription, a segfault occurs in
res_pjsip_refer:refer_incoming_ari_request().

However, even if the segfault were prevented, there's another issue...
Suppressing the subscription and NOTIFYs to the referer also prevents
the ARI app from getting any progress events for the transfer which it's
controlling.

So...

* The segfault has been fixed.
* Suppressing the subscription no longer suppress the ARI events from being
sent to the controlling ARI app.
* A good amount of tracing has also been added.

Resolves: #2021
2026-07-21 12:11:16 +00:00
Mike Bradeen
ea9b48659d build: re-add pjsua test application
pjsua and it's python bindings were removed as part of PR
1854. Testing for RTT requires the pjsua application be
re-added to the third pary build process.  This applies to
the pjsua application ONLY and not the associated python
bindings.

Resolves: #2024
2026-07-15 16:18:47 +00:00
Naveen Albert
036f09c073 res_pjsip: Document 'none' option for 'dtmf_mode'.
The 'none' value can be used to disable DSP processing for DTMF
on PJSIP channels and is sometimes necessary for this reason,
and already exists in the code, but is not documented. Add it to
the documentation enum.

Resolves: #2026
2026-07-15 16:02:53 +00:00
Mike Bradeen
fb4bfb1156 Audiohooks: Allow whisper audiohooks to work without an underlying stream
Audiohook whispers work by mixing audio with the current stream of frames being
written to the hooked channel. Prior to this change if there were no audio
frames being written to the channel outside of the audiohook, then any whisper
audio has nothing to mix with and so is not heard on the hooked channel.

This change removes that requirement by creating a framehook driven timer on the
channel that creates silent frames the whispered frames can be mixed into.

The framehook is automatically added with the first attached whisper audiohook
and is removed when the last one is detached.  If there are no attached streams
being written to the channel, the timer is used to generate a default one. If
a stream is attached; the timer is ignored until the stream stops. This stop
and start is automatically triggered by the presence of a written stream and does
not require any external action.

Resolves: #1966

UserNote: There is no longer a requirement to play silence or otherwise have
a stream of audio being sent to a hooked channel for whispered frames to be
heard.
2026-07-15 15:39:56 +00:00
Ben Ford
99fe892b66 Logger: Don't discard WARNING or ERROR messages.
When the logger reaches it's threshold for messages, don't discard the
WARNING or ERROR messages up to a certain amount. If THAT threshold
reaches its maximum, start discarding the oldest non-WARNING/ERROR
messages until we only have WARNING and ERROR messages left. Everything
will be discarded after that until we have room again for more.

Also added a test that limits the queue sizes and logs many messages to
see the queues hitting their maximums and discarding the appropriate
messages.

Fixes: #1882
2026-07-13 16:49:45 +00:00
Aqeel Abbas
95b94d0ef1 func_strings: Fix syntax error in STRBETWEEN documentation example
The STRBETWEEN function documentation example was missing a closing
brace in the SendDTMF call. Corrected the syntax to ensure the
dialplan example is functional.
2026-07-13 16:00:05 +00:00
Mehrdad Seifzadeh
07884c4144 res_pjsip_registrar: Resolve AOR for identified endpoints
When an inbound REGISTER is matched to an endpoint using an
identification method such as IP, header, or request URI, the endpoint can
be identified and authenticated successfully while registrar AOR
resolution still fails.

find_registrar_aor() only resolved AOR names for username and
auth_username identify methods. A header-only endpoint therefore left
aor_name unset and failed registration with "AOR '' not found" even when
the REGISTER To URI matched one of the endpoint's configured AORs.

Resolve the REGISTER AOR from the To URI for endpoint identification
methods that do not directly provide an AOR name, while still
constraining the match to the already-identified endpoint's configured AOR
list.

Fixes: #1398
2026-07-13 15:15:39 +00:00
Thomas Guebels
ae85ad744a res_http_websocket: Unref session when it fails to establish.
Two error paths in res_http_websocket could leak an ast_websocket session by
failing to drop a reference after the session had been allocated.

The first occurs when session ID generation fails. While this is largely
theoretical, as it would require an out-of-memory condition, the session
reference should still be released correctly.

The second occurs when the ast_websocket_pre_callback session_attempted callback
returns an error. This path is reachable through ari_websockets, which
implements this callback and can legitimately fail under certain conditions.

Fixes: #2020
2026-07-09 16:50:08 +00:00
George Joseph
546749516b Bundled pjproject: Make it easier to override options in config_site.h.
Bundled pjproject uses ./third-party/pjproject/patches/config_site.h to set
many pjproject build options like PJ_IOQUEUE_MAX_HANDLES, PJSIP_MAX_URL_SIZE,
etc. Editing that file however, causes the git tree to become dirty which
is inconvenient.  So...

* Updated the Asterisk configure scripts to pass the PJPROJECT_CFLAGS variable
down to the pjproject configure scripts.  See the UserNote below for details.

* Updated ./third-party/pjproject/patches/config_site.h to allow the following
options to be overridden:
PJ_MAX_HOSTNAME, PJSIP_MAX_URL_SIZE, PJ_IOQUEUE_MAX_HANDLES.
Other options in config_site.h are not overridable because they can have a
bad effect on the overall operation of pjproject.  This may be revisited in
the future.  Options not already set in config_site.h can still be set.

* Fixed an issue where if the Linux `epoll` facility is used (which it is by
default) the default PJ_IOQUEUE_MAX_HANDLES and PJSIP_MAX_TRANSPORTS were
being left at 1024 instead of being icnreased to 5000.

* The `pjproject show buildopts` CLI command previously only showed options from
the top level `PJ` pjproject layer but now also shows many from the `PJSIP`
layer.  Many of these, such as PJSIP_MAX_TRANSPORTS, can be set using
PJPROJECT_CFLAGS provided they're not already unconditionally set in
config_site.h.

* The `pjsip dump endpt` CLI command previously required that the pjproject
log level be already set to at least 3 or no output would be produced.  The
command now does that automatically then sets it back to whatever it was.
This isn't strictly related to this PR but was just nagging me.

UserNote: Bundled pjproject: It's now possible to override some of the pjproject
build options contained in ./third-party/pjproject/patches/config_site.h by
adding PJPROJECT_CFLAGS to your Asterisk ./configure command line.  For example:
`./configure ... PJPROJECT_CFLAGS='-DPJ_OPT1=8192 -DPJ_OPT2=512'`
Any option in config_site.h that's wrapped in a `#ifndef` block can be overridden
and many of the `PJSIP` options displayed by `pjproject show buildopts` can be
set.  WARNING: Adjusting these options without understanding their effect can
cripple your Asterisk instances.  You shouldn't adjust them unless you need
to solve a specific issue.

Resolves: #2011
2026-07-07 15:57:04 +00:00
Joshua C. Colp
1fc956a48b test_performance: Add performance experimentation test module.
This is a module which is only built when TEST_FRAMEWORK is enabled
and provides CLI commands for testing performance of certain things
on the system they are invoked on. The first CLI commands added
cover the most common container usage: storage of objects with a
lookup based on a string key. These commands take various arguments
and allow you to see how they perform. There is also an "all" command
named "performance test container_key_lookup_all" that will execute
all of these container tests and pass through the given arguments,
which makes it easy to run all of the tests for given usage.

To facilitate a vector bsearch test a new AST_VECTOR_BSEARCH macro
has been added that allows more efficient searching of sorted vectors.
2026-07-07 15:38:37 +00:00
Joshua C. Colp
2158dff4b5 manager: Move away from shared linked list for events.
This change moves manager away from a shared linked list
for events to a per-session vector of pending events. This
allows early filtering of events which eliminates the need
to wake up threads for events that they have no interest in.

TCP based connections have also been moved to an alert pipe
based wakeup mechanism to reduce locking and simplify usage.

UserNote: The "manager show eventq" CLI command has been
removed as there is no longer a single event queue to display.
2026-07-07 15:36:25 +00:00
George Joseph
5eded44fee chan_websocket: Use leftover data if no frames are available when the timer fires.
When the 20ms channel timer fires but there are no frames available in
the queue, we now check for leftover data in the buffer and if there is
any, we create a frame with it and send it to the core. This resolves an
issue with the leftover data being delayed if a STOP_MEDIA_BUFFERING
command is delayed. Some existing comments were also clarified to
account for the new behavior.

Resolves: #2006
2026-07-02 18:06:31 +00:00
Mehrdad Seifzadeh
f7c50cff7c res_pjsip_session: Bound delayed BYE behind UAC INVITE
When a confirmed session is being terminated while an outgoing in-dialog
INVITE transaction is still outstanding, the BYE is delayed until the
outstanding transaction terminates.

If that INVITE has already received a provisional response and the final
response is malformed and rejected before transaction processing, the
transaction can remain outstanding and the delayed BYE can keep the
session, media state, RTP instance, and PJPROJECT pools referenced after
the channels are gone.

When a BYE is delayed behind an outstanding UAC INVITE, set a PJPROJECT
transaction timeout on that INVITE so the delayed cleanup path has a
bounded wait. If PJPROJECT terminates the dialog as a result of the
timeout, discard the delayed BYE instead of sending a duplicate BYE.

Fixes: #1965
2026-07-01 18:53:23 +00:00
Sean Bright
a12cc71282 extensions.ael.sample: Restore removed macros
Commit e8f548c1 removed AEL `macro` definition and calls from the
sample configuration file, but those do not use the deprecated/removed
`Macro` app - they use `Gosub` under the hood.
2026-06-26 15:07:17 +00:00
Alexandre Fournier
a9d33edc2e format_cap: guard against NULL src in *_from_cap helpers
ast_format_cap_append_from_cap() and ast_format_cap_replace_from_cap()
dereference 'src' (src->preference_order) without checking it for NULL.

A dummy channel allocated with ast_dummy_channel_alloc() never sets a
native-format capability, so ast_channel_nativeformats() returns NULL on
such channels. When CHANNEL(audionativeformat) / CHANNEL(videonativeformat)
is evaluated against a dummy channel (e.g. via ARI channelvars during a
Stasis VarSet event raised while app_voicemail builds the notification
email on a dummy channel), func_channel_read() passes that NULL straight
into ast_format_cap_append_from_cap(), causing a NULL dereference at
offset 0x28 and a SIGSEGV.

Guard both helpers against a NULL source. A NULL source simply means
"no formats to copy", so appending/replacing nothing is the correct
no-op behaviour. This also protects all other callers.

Fixes https://github.com/asterisk/asterisk/issues/1992

AI disclosure: this was generated using Claude Opus 4.8, tested to fix the issue. Not sure if it is the *right* way to do it.
2026-06-25 23:39:45 +00:00
ThatTotallyRealMyth
c0fc2ae54c ast_loggrabber: Install the ast_tsconvert.py script to a secure temp directory.
The ast_tsconvert.py script called by ast_loggrabber is now installed in a
temporary directory that isn't world readable or writable.

Resolves: #GHSA-xgj6-2gc5-5x9c
2026-06-25 08:21:09 -06:00
George Joseph
6f414ec771 chan_unistim.c: Prevent overrun of phone_number field.
Add a check to key_dial_page() to ensure that dialed digits won't overrun
the phone_number field.

Resolves: #GHSA-3g56-cgrh-95p5
2026-06-25 08:21:09 -06:00
Mike Bradeen
42d3552d2a ooh323c: not checking for IE minimum length
When decoding q.931 encoded calling/called number
now checking for length being less than minimum required.

Resolves: #GHSA-h5hv-jmgj-92q2
2026-06-25 08:21:09 -06:00
George Joseph
762b4c9c39 res_ari: Ensure read-only users are properly authorized via REST Over WebSocket.
The REST over WebSocket path now properly prevents non-GET methods from
being executed on inbound WebSockets.

* The query parameters from the original incoming GET request that caused the
upgrade to WebSocket are now passed to all REST requests that come from the
client. This ensures that if the client authenticated with a read-only
userid using the "api_key" query_string parameter, REST requests coming
in over the WebSocket will only be able to execute GETs on resources.
The HTTP headers were already passed to the REST requests so if the
client had authenticated via an "Authorization" it was properly handled.

* New tests have been added to test_ari.c to check that read-only users
are properly denied access to resources using non-GET methods.  Several
memory leaks were also squashed.

Resolves: #GHSA-wcvv-g26m-wx5c
2026-06-25 08:21:09 -06:00
George Joseph
f1e4762147 pjsip_message_filter: Use pj_strdup instead of pj_strassign to save local address.
The filter_on_tx_message() function was using pj_strassign() to save the pointer
of the pjproject transport local address to a local pj_str_t variable.  That
variable was ultimately used to set the Contact header's uri->host and the SDP
connection attribute's address again using pj_strassign.  pj_strassign() doesn't
copy the actual value of the pj_str_t however, it just copies the pointer so
if a connection-oriented transport is disconnected before the 200 OK with the
SDP is sent, those pointers will be invalid which can cause use-after-free
issues. To prevent this, filter_on_tx_message() now uses pj_strdup with the
tdata->pool as the backing store to save the local IP address to the local
variable.  pj_strassign() can then be used safely later on since the tdata
will be available for the life of the transaction.

Resolves: #GHSA-g8q2-p36q-94f6
2026-06-25 08:21:09 -06:00
George Joseph
5e59cbad64 ooh323c/ooq931.c: Ensure ooQ931Decode doesn't run out-of-bounds.
Several bounds checks have been edded to ooQ931Decode to prevent it from
running past the end of the data buffer when parsing information elements.

Resolves: #GHSA-746q-794h-cc7f
2026-06-25 08:21:09 -06:00
George Joseph
8f8ccaf70a ARI: Make ARI applications respect live_dangerously.
DeveloperNote: ARI applications can no longer call "dangerous" dialplan
functions like DB(), FILE(), SHELL(), CURL(), STAT(), etc. without
enabling "live_dangerously" in asterisk.conf.

Resolves: #GHSA-vrfp-mg3q-3959
2026-06-25 08:21:09 -06:00
George Joseph
536218a86b res_rtp_asterisk.c: Address 2 potential T.140 RED buffer overruns.
* Add check to red_t140_to_red() to ensure that the new primary payload
can't cause the rtp_red->len array items to wrap or cause an overrun of
the rtp_red->t140red_data buffer.

* Add check to rtp_red_buffer() to ensure that a T.140 frame to be sent
can't cause rtp_red->len array items to wrap or cause an overrun of
the rtp_red->buf_data buffer.

Resolves: #GHSA-vfhr-r9x9-c687
Resolves: #GHSA-j2mm-57pq-jh94
2026-06-25 08:21:09 -06:00
Roberto Paleari
1039bed76f res/res_pjsip_pubsub.c: Fix buffer over-read in MWI body parser
Add constraint checks to prevent unauthenticated users from crashing Asterisk
instance by sending a crafted inbound SIP NOTIFY request with "Content-Type:
application/simple-message-summary".

Resolves: #GHSA-8jw3-ccr9-xrmf
2026-06-25 08:21:09 -06:00
Mike Bradeen
87a1f43e4c manager: Use remote address in user error logging
To avoid a potential null dereference use the remote address
in error logging when there is no user or the user acl fails.

Resolves: #GHSA-3rhj-hhw7-m6fw
2026-06-25 08:21:09 -06:00
Mike Bradeen
bf0c9a9068 ooh323: Prevent potential buffer overflow in trace logging
Replace a call to vsprintf with a call to ast_vasprintf to
prevent a possible buffer overflow.

Resolves: #GHSA-x348-j6c9-77f3
2026-06-25 08:21:09 -06:00
Pengpeng Hou
59b74276f2 app_sms: Bound protocol 1 SMS unpacking to fixed-size buffers
The protocol 1 unpack helpers trusted externally controlled lengths and wrote
 them directly into fixed-size buffers in sms_t. Clamp the address, header,
 and body copies to the destination array sizes so malformed messages cannot
 overwrite adjacent state.

Resolves: #GHSA-q9fr-m7g8-6ph5
2026-06-25 08:21:09 -06:00
Milan Kyselica
12072a559f res_xmpp: Fix stack buffer overflow in namespace prefix handling
The snprintf size parameter in xmpp_action_hook() is computed from
the attacker-controlled namespace prefix length and is not bounded
by the 256-byte stack buffer size. When a remote XMPP peer sends a
stanza with a child element whose namespace prefix exceeds 249
characters, snprintf writes past the buffer boundary.

Use sizeof(attr) as the snprintf size limit and %.*s precision to
extract only the prefix portion of the element name, preserving
the original truncation behavior for valid inputs.

Resolves: #GHSA-mxgm-8c6f-5p8f
2026-06-25 08:21:09 -06:00
Milan Kyselica
7a1ffcdf38 res_pjsip_pubsub: Add width limit to sscanf in MWI NOTIFY parser
The parse_simple_message_summary() function uses sscanf with an
unbounded %s format specifier to parse the Message-Account field
from incoming SIP NOTIFY bodies into a fixed-size 512-byte stack
buffer (PJSIP_MAX_URL_SIZE). A single unauthenticated SIP NOTIFY
with a Message-Account value exceeding 512 bytes overflows the
buffer, corrupting adjacent stack data and permanently disabling
the PJSIP transport layer without crashing the process.

Add a width specifier (%511s) to limit the sscanf write to
PJSIP_MAX_URL_SIZE - 1 bytes plus the NUL terminator, matching
the destination buffer size.

Resolves: #GHSA-589g-qgf8-m6mx
2026-06-25 08:21:09 -06:00
Milan Kyselica
04aa482212 res_config_ldap: Escape LDAP filter values per RFC 4515
The LDAP realtime driver constructs search filters by directly
concatenating user-supplied values without RFC 4515 escaping.
When LDAP is used as a realtime backend for endpoint
identification, characters with special meaning in LDAP filters
(*, (, ), \) can be injected via the SIP From header username.

Add ldap_filter_escape_value() that escapes RFC 4515 special
characters to their \HH hex representation, and apply it to
non-LIKE query values. The LIKE query path preserves the existing
wildcard conversion behavior with a note for maintainers.

Resolves: #GHSA-r6c2-hwc2-j4mp
2026-06-25 08:21:09 -06:00
Milan Kyselica
88c65757b5 cel_pgsql, cel_tds: Escape eventtype field to prevent SQL injection
The eventtype column handler in cel_pgsql.c inserts
record.user_defined_name directly into the SQL query without
calling PQescapeStringConn(), while all other string fields in
the same function are properly escaped. Similarly, cel_tds.c
passes the raw user_defined_name into the SQL INSERT without
routing it through anti_injection(), while all other fields are
processed through that function.

For cel_pgsql.c, escape the eventtype value using
PQescapeStringConn(), matching the existing pattern used for all
other string fields at lines 308-331 of the same function.

For cel_tds.c, route the eventtype value through
anti_injection() consistent with how all other fields are handled
in the same function.

Resolves: #GHSA-ph27-3m5q-mj5m
2026-06-25 08:21:09 -06:00
Milan Kyselica
4b360a61d6 http: Escape error page text to prevent reflected XSS
The text parameter in ast_http_create_response() is inserted into
the HTML body without escaping, while the server name on the same
page is properly escaped via ast_xml_escape(). When res_phoneprov
passes the decoded request URI as the text of a 404 response, HTML
metacharacters in the URI are rendered by the browser.

Apply ast_xml_escape() to the text parameter before inserting it
into the HTML template, using the same function already used for
the server name.

Resolves: #GHSA-4pgv-j3mr-3rcp
2026-06-25 08:21:09 -06:00
Milan Kyselica
d4ccfd55ff codec_codec2: Only process complete Codec2 frames in decoder
The codec2_samples() function uses floor division (160 * datalen/6)
to compute expected output samples, but the decode loop condition
(x < datalen) iterates with ceiling behavior when datalen is not a
multiple of CODEC2_FRAME_LEN. This mismatch causes the loop to
decode one extra frame beyond what the framework bounds check
budgeted for, leading to an out-of-bounds write on the output buffer.

Change the loop condition to only process complete frames, matching
the floor-division behavior of codec2_samples(). This also prevents
an out-of-bounds read on the input side when fewer than
CODEC2_FRAME_LEN bytes remain.

Resolves: #GHSA-qf8j-jp7h-c5hx
2026-06-25 08:21:09 -06:00
Milan Kyselica
1cf1895499 format_ogg_speex: Add bounds check to prevent heap buffer overflow
The ogg_speex_read() function copies OGG packet data via memcpy()
without validating the packet size against the destination buffer
(BUF_SIZE = 200 bytes). A crafted .spx file with an oversized OGG
audio packet causes a heap buffer overflow that corrupts the
adjacent speex_desc structure containing libogg heap pointers,
leading to a crash (SIGSEGV) on playback.

Add a bounds check for both negative and oversized values before
the memcpy, consistent with how format_ogg_vorbis bounds its reads
via ov_read().

Resolves: #GHSA-8jhw-m2hg-vp3h
2026-06-25 08:21:09 -06:00