pytorch / pytorch/audio

forced_align (CPU) segfaults when frames * (2*targets+1) exceeds 2^31: 32-bit loop index overflow

Open
#4,208 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
2.9k
Forks
799
Avg merge
58m
Merged PRs (30d)
3

Description

🐛 Describe the bug

torchaudio.functional.forced_align (CPU) crashes the whole process with SIGSEGV when frames * (2 * target_length + 1) exceeds 2^31. This is reachable with realistic inputs: character-level CTC alignment (WhisperX-style) of a ~20-minute chunk of dense speech at 50 fps crosses the limit (we hit it in production aligning a German podcast).

Repro
# needs ~2.2 GB RAM; crashes the interpreter (run in a subprocess)
import torch, torchaudio

T, L, C = 70_000, 15_500, 30            # T*(2L+1) = 2.17e9 > 2^31
g = torch.Generator().manual_seed(0)
emission = torch.log_softmax(torch.rand((T, C), generator=g), dim=-1)
targets = torch.randint(1, C, (1, L), generator=g, dtype=torch.int32)

torchaudio.functional.forced_align(emission.unsqueeze(0), targets, blank=0)
# -> SIGSEGV / SIGBUS

Observed behaviour (torchaudio 2.11.0, macOS arm64):

T * (2L+1) targets dtype result
2.17e9 (> 2^31) int32 💥 SIGSEGV
2.17e9 (> 2^31) int64 💥 SIGSEGV (no dtype workaround)
2.10e9 (< 2^31) int32 ✅ correct result, ~8 s
Root cause

src/libtorchaudio/forced_align/cpu/compute.cpp, the backPtr_a init loop uses a 32-bit loop index against a 64-bit trip count:

auto backPtr_a = new int8_t[T * S];     // T, S are int64_t -- allocation is fine
for (int i = 0; i < T * S; i++) {       // int i overflows at 2^31 (UB)
  backPtr_a[i] = -1;
}

Once i wraps to INT_MIN, the store lands at backPtr_a - 2^31 bytes. The macOS crash report confirms this exactly: fault address = buffer base − 0x80000000, as a byte write inside forced_align_impl<float, int>:

Exception Type:    EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000892e94000
  x0/x19 (buffer): 0x0000000912e94000       <- base - fault = 0x80000000
0  libtorchaudio.abi3.so  forced_align_impl<float, int>(...) + 316
1  libtorchaudio.abi3.so  torchaudio::alignment::cpu::compute(...) + 1384

This also explains why int64 targets crash identically — the dispatch only changes target_t, not the init loop. The alphas_a init loop two lines above uses the same int i < 2 * S idiom (not practically reachable today, but the same latent pattern).

The bug is platform-independent (plain C++ signed-overflow UB); it is present in current main (c0cbdb9).

Correction (2026-08-04): an earlier version of this line said the bug went back to 2.8. It does not. #4021 (ea7855b), which introduced the raw array and the int fill loop, merged 2025-08-11 — five days after v2.8.0 shipped on 2025-08-06. v2.8.0 still carries the safe torch::Tensor backPtr = torch::empty({T, S}, torch::kInt8).fill_(-1). The affected range is 2.9.0 through 2.11.0.

Fix

One-liner: make the loop indices int64_t. PR incoming.

Versions

  • torchaudio 2.11.0 (also inspected current main, c0cbdb9)
  • torch 2.13.0
  • Python 3.12.8, macOS 26.5 (arm64, M1 Max) — but the overflow is platform-independent

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/libtorchaudio/forced_align/cpu/compute.cpp and inspect the backPtr_a and alphas_a initialization loops in forced_align_impl. Confirm the loop index types are safe for their 64-bit trip counts, then validate the reported large-input reproduction or an equivalent regression check. Done means the overflow no longer permits out-of-bounds writes for the described dimensions.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, python
Domain
machine-learning
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.