[Security Issue] rbs_string_strip_whitespace reads past empty ranges
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 85/100
Direzione di ricerca
Inizia in src/string.c, da rbs_string_strip_whitespace, e analizza i suoi chiamanti nel parsing di integer-literal e delle annotazioni. Esegui l’harness di AddressSanitizer fornito, quindi test/rbs/type_parsing_test.rb; il lavoro è completato quando gli intervalli vuoti non causano più una lettura out-of-bounds e i test elencati hanno esito positivo.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
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.
- Lingua principale
- Ruby
- Stelle
- 2.2k
- Fork
- 256
- Merge medio
- 7g 1h
- PR unite (30g)
- 35
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di ruby/rbs
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 78/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 35/100
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 35/100
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
-
bug
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 90/100
riscv/riscv-unified-db#2626 ·
-
Component: GLib
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
-
ds-drift
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
we-promise/sure#3693 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
simp/pupmod-simp-simp#395 ·