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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions