Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

[Security Issue] rbs_string_strip_whitespace reads past empty ranges

オープン 初心者向け
#3,108 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
85/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
c, ruby
領域
security

調査の方向性

src/string.c の rbs_string_strip_whitespace から始め、integer-literal とアノテーションのパースにおけるその呼び出し元を確認します。付属の AddressSanitizer ハーネスを実行し、その後 test/rbs/type_parsing_test.rb を実行します。空の範囲によって out-of-bounds read が発生しなくなり、記載されたテストが通れば作業完了です。

索引モデルが issue の本文から書いたものです。

説明

Summary

rbs_string_strip_whitespace dereferences the start of a string range before checking whether the range is empty. An empty range therefore produces an out-of-bounds read under AddressSanitizer. The parser calls this helper for annotation bodies, whose grammar permits an empty body (<>).

Affected current master: 5de6ecda19eaec2bd225db301674dc650dc220c3
Affected release checked: RBS 4.2.0 (8aee3b6fa6231dbd6fefe01f2ba20e3104228a6f)

Source

The current loop condition reads *new_start before evaluating new_start < self->end:

while (isspace(*new_start) && new_start < self->end) {
    new_start++;
}

The trailing-whitespace loop uses the same unsafe evaluation order. Call sites are in integer-literal and annotation parsing.

Reproduction

This small harness invokes the helper with a valid empty half-open range at the end of a one-byte allocation:

#include <stdlib.h>
#include "rbs/string.h"

int main(void) {
    char *storage = malloc(1);
    rbs_string_t empty = rbs_string_new(storage + 1, storage + 1);
    rbs_string_t stripped = rbs_string_strip_whitespace(&empty);
    free(storage);
    return stripped.start == stripped.end ? 0 : 1;
}

Compile with AddressSanitizer against src/string.c and run it. On macOS/arm64 with Apple clang 17.0.0:

ERROR: AddressSanitizer: heap-buffer-overflow
READ of size 1
    #0 rbs_string_strip_whitespace
    #1 main
0 bytes after 1-byte region

Suggested fix

Check the range before dereferencing it, and cast through unsigned char before passing bytes to isspace:

-while (isspace(*new_start) && new_start < self->end) {
+while (new_start < self->end && isspace((unsigned char) *new_start)) {
...
-while (isspace(*new_end) && new_start < new_end) {
+while (new_start < new_end && isspace((unsigned char) *new_end)) {

With that change, the ASan harness exits successfully. The native extension compiles on Ruby 4.0.6, and test/rbs/type_parsing_test.rb passes 40 tests / 525 assertions. I have not established code-execution impact; the demonstrated failure is an out-of-bounds read on an empty parser string range.

主要言語
Ruby
スター
2.2k
フォーク
258
平均マージ
1日 4時間
マージ済み PR(30日)
52

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

ruby/rbs のほかの issue

ruby/rbs の issue をすべて見る

似ている issue

Ruby の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。