Skip to content

OpenSBI sbi_ecall_get_extensions_str() can overrun caller buffers when the extension list is longer than the destination #416

@neosys007

Description

@neosys007

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions