mruby-io: fix buffer overflow in io#ungetc; fix #6647

io_unget_data had two issues that caused crashes with repeated ungetc:

1. Integer underflow in buffer size check: "len > MRB_IO_BUF_SIZE - buf->len"
   could underflow when buf->len was large, bypassing reallocation

2. Short overflow: buf->len could exceed SHRT_MAX after multiple ungetc
   calls, causing integer overflow when cast to short

Fixed by checking buf->len + len against both MRB_IO_BUF_SIZE and
SHRT_MAX before buffer operations.

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2025-10-22 14:04:14 +09:00
parent c21604eea6
commit 01ab2ffc29
+4 -1
View File
@@ -1688,7 +1688,10 @@ io_unget_data(mrb_state *mrb, struct mrb_io *fptr, const char *ptr, mrb_int len)
if (len > SHRT_MAX) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "string too long to ungetc");
}
if (len > MRB_IO_BUF_SIZE - buf->len) {
if (buf->len + len > SHRT_MAX) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "total ungetc buffer exceeds maximum size");
}
if (buf->len + len > MRB_IO_BUF_SIZE) {
fptr->buf = (struct mrb_io_buf*)mrb_realloc(mrb, buf, sizeof(struct mrb_io_buf)+buf->len+len-MRB_IO_BUF_SIZE);
buf = fptr->buf;
}