Skip to content

Bug: Self-move-assignment in RE2::Set and FilteredRE2 causes use-after-destroy #615

@MarkLee131

Description

@MarkLee131

Description

The move assignment operators in RE2::Set and FilteredRE2 use a destroy-then-placement-new pattern:

RE2::Set& RE2::Set::operator=(Set&& other) {
  this->~Set();
  (void) new (this) Set(std::move(other));
  return *this;
}

This is unsafe when this == &other (self-move-assignment). The destructor runs first, which calls Decref() on internal Regexp* pointers and frees resources. Then the move constructor reads from the already-destroyed object. This is undefined behavior and can lead to double-free.

Self-move-assignment can happen through aliased references. For example:

std::vector<RE2::Set> v = ...;
v[i] = std::move(v[j]);  // if i == j

Affected Code

  • re2/set.cc:52-56 (RE2::Set::operator=(Set&&))
  • re2/filtered_re2.cc:45-48 (FilteredRE2::operator=(FilteredRE2&&))

I can open PR to submit a fix.

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