mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Fix uninitialized variable in io_gets causing segmentation fault
This patch fixs a critical segmentation fault in `io_gets` function caused by an uninitialized limit variable.
This bug may specifically heppen when:
- MicroRuby with task scheduler, which I'm implementing, enabled
## Root Cause Analysis
When `io_gets` is called without arguments (argc=0), the local variable `limit` remains uninitialized on the stack.
I guess that this uninitialized memory often contains leftover heap addresses from previous stack frames.
### The problematic flow:
1. `mrb_get_args(mrb, "|o?i?", &rs, &rs_given, &limit, &limit_given)` with 0 arguments
2. `limit_given = FALSE` but limit contains garbage heap address
3. Looks like later processing truncates this address, creating invalid pointer 0xffff0000
4. This value gets pushed onto VM stack during string operations
5. Garbage collector attempts to mark 0xffff0000 as valid object pointer
6. SIGSEGV in mrb_gc_mark() at gc.c:748
```
Program received signal SIGSEGV, Segmentation fault.
0x00005c8bebffa95c in mrb_gc_mark (mrb=0x5c8bec2836c8 <heap_pool+728>, obj=0xffff0000)
at .../gc.c:748
748 if (!is_white(obj)) return;
#1 mark_context_stack (mrb=0x5c8bec2836c8 <heap_pool+728>, c=0x5c8bec2b4a50 <heap_pool+202336>)
at .../gc.c:555
555 mrb_gc_mark(mrb, mrb_basic_ptr(v));
```
## Solution
I couldn't figure out the exact mechanism of the issue. Anyway, initializing the limit variable to zero could prevent invalid garbage stack memory:
```c
mrb_int limit = 0; // Explicit initialization
```
## Files Changed
- mrbgems/picoruby-mruby/lib/mruby/mrbgems/mruby-io/src/io.c
This commit is contained in:
@@ -2072,7 +2072,7 @@ io_gets(mrb_state *mrb, mrb_value io)
|
||||
{
|
||||
mrb_value rs = mrb_nil_value();
|
||||
mrb_bool rs_given = FALSE; /* newline break */
|
||||
mrb_int limit;
|
||||
mrb_int limit = 0;
|
||||
mrb_bool limit_given = FALSE; /* no limit */
|
||||
struct mrb_io *fptr = io_get_read_fptr(mrb, io);
|
||||
struct mrb_io_buf *buf = fptr->buf;
|
||||
|
||||
Reference in New Issue
Block a user