Skip to content

Swapping a filebuf with a small buffer (or disabled buffering) leads to memory corruption/invalid access and results #49282

@llvmbot

Description

@llvmbot
Bugzilla Link 49938
Version 11.0
OS All
Reporter LLVM Bugzilla Contributor
CC @mclow

Extended Description

When a filebuf with a small buffer size is used, then the internal buffer __extbuf_min_ is used instead:

__extbuf_ = __extbuf_min_;

This buffer may be filled by (e.g.) read operations. When the filebuf is then swapped with another filebuf, the contents of this buffer will be ignored and the swapped-to filebuf will use its own, unfilled internal buffer instead. See

if (__extbuf_ == __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_)
{
__extbuf_ = __rhs.__extbuf_;
__rhs.__extbuf_ = __rhs.__extbuf_min_;
}

Example code triggering the bug:

    std::filebuf buf1, buf2;
    buf1.pubsetbuf(0, 0);
    assert(buf1.open(filepath, std::ios_base::in) == &buf1);
    assert(buf2.open(filepath2, std::ios_base::in) == &buf2);
    // Peek
    assert(buf1.sgetc() == 'B');
    assert(buf2.sgetc() == 'H');
    swap(buf1, buf2);
    assert(buf2.sgetc() == 'B'); // Boom!

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugzillaIssues migrated from bugzillalibc++libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions