Project

General

Profile

Actions

Bug #22259

closed

Arrays sharding a buffer segfault when concatenating with each other

Bug #22259: Arrays sharding a buffer segfault when concatenating with each other

Added by chucke (Tiago Cardoso) about 21 hours ago. Updated 10 minutes ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:126480]

Description

A succession of crashes was observed on a particular workload from our app, involving recursive set operations, after upgrading it to ruby 4.0.6 . LLM was used to build a reproduction (shared in the description of the PR linked below), after which we used it as a harness to get to the actual culprit and fix it.

The crash is due to a particular behaviour of how (btw, TIL, so correct my explanation if necessary) ruby arrays share internal buffers, for optimal memory usage. Array#dup creates a separate array object, but may share (under certain conditions, i.e. does not embed) the internal C buffer, where objects are stored, with it. Certain modification operations, like Array#dup, don't forcefully "copy on write", and instead bump/dec an index on the shared buffer, as so to determine the slice of the original shared buffer it points to.

The issue happens with how other operations work, such as Array#concat, which is, internally, under certain conditions, copying the full shared buffer to the destination array buffer, without regards of which slice it is about. This is easily demonstrable by the first reproduction in the PR linked below, where the last concat operation adds a "phantom" element to the destination array. that element is, at that point, gibberish, malloc-uninitialized data, which causes the VM to crash, depending on what it does with the address found there.

This bug has been there for a while, and can be reproduced (with different faulty outcomes) since ruby 3.3 at least (didn't try further back).

PR with fix here: https://github.com/ruby/ruby/pull/18472

Actions

Also available in: PDF Atom