-
Notifications
You must be signed in to change notification settings - Fork 665
OpenSBI sbi_ecall_get_extensions_str() can overrun caller buffers when the extension list is longer than the destination #416
Description
Title: OpenSBI sbi_ecall_get_extensions_str() can overrun caller buffers when the extension list is longer than the destination
Current upstream OpenSBI master still has a buffer-handling bug in lib/sbi/sbi_ecall.c. The helper sbi_ecall_get_extensions_str() builds a comma-separated list of SBI extension names into a caller-provided buffer, but it does not clamp the running offset before each append the way sbi_hart_get_extensions_str() already does. The code currently does this:
sbi_snprintf(exts_str + offset, exts_str_size - offset, "%s,", t->name);
offset = offset + sbi_strlen(t->name) + 1;
and afterwards it writes:
if (offset)
exts_str[offset - 1] = '�';
The problem is that offset is increased based on the nominal name length, not on the actual number of bytes that fit in the destination buffer. If the caller supplies a buffer smaller than the total concatenated extension string, offset can move past exts_str_size. At that point exts_str_size - offset becomes negative and is passed to sbi_snprintf() as a large unsigned value, and the final ext[s]_str[offset - 1] write can also step past the caller buffer. In other words, this is not just string truncation; the offset arithmetic itself is unsafe once the list grows beyond the destination size.
For comparison, sbi_hart_get_extensions_str() in lib/sbi/sbi_hart.c already performs a guard of the form:
if (offset + sbi_strlen(...) + 1 > nestr)
break;
before calling sbi_snprintf(). sbi_ecall_get_extensions_str() does not do that check today.
Expected behavior: the helper should check the remaining capacity before each append and stop safely when the caller buffer is full.
Actual behavior: the helper can keep advancing offset beyond the buffer size and then hand an invalid length to sbi_snprintf(), which can lead to an out-of-bounds write in the caller buffer.