Skip to content

RailLinearInterpolator::m_points may be indexed out-of-bounds by the base game #409

@malleoz

Description

@malleoz

This issue was discovered by @JohnP55 when upgrading to gcc-15, which adds asserts on std::span out-of-bounds accesses. This issue is currently known to occur on GCN Mario Circuit for ObjectKuribo.

We start by assuming the following:

  • RailLinearInterpolator::m_pointCount
  • RailLinearInterpolator::m_nextPointIdx = 1
  • RailLinearInterpolator::m_movementDirectionForward = true
  • RailLinearInterpolator::m_isOscillating = true

RailLinearInterpolator::calcNextSegment() may cause m_nextPointidx to increment to 2, even when m_pointCount is 2. Likewise, when the Goomba walks backwards, calcNextSegment may cause m_nextPointIdx to decrement to -1. m_nextPointIdx will then be used to compute m_currentDirection in RailLinearInterpolator::calcNextSegment(), hence it is possible to be indexing the span out-of-bounds (2 is beyond the size of the span, and -1 is obviously invalid).

This behavior occurs in the base game too. So, to fix this unnoticed bug, it is important to document the following:

  1. What are the observed memory reads in the base game in these scenarios?
  2. Why does this sync in Kinoko currently if we ignore the error?
  3. Are there any edge cases where this out-of-bounds access could cause desyncs if we just blindly assume what the value should be? What memory region is the base game actually reading from?
  4. What can we do to fix this properly without changing the underlying behavior?

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