Fix use-after-free of std::list iterator in FormFiller::UndoAutofill [chromium/src : main]

0 views
Skip to first unread message

Jihad Hanna (Gerrit)

unread,
Apr 9, 2026, 8:40:47 AM (4 days ago) Apr 9
to Gianmarco Picarella, Julia Sobiech, chromium...@chromium.org, browser-comp...@chromium.org
Attention needed from Christoph Schwering and Gianmarco Picarella

Jihad Hanna added 1 comment

File components/autofill/core/browser/filling/form_autofill_history.cc
Line 101, Patchset 2 (Latest): size_ -= fill_operation->erase(field_id);
Jihad Hanna . unresolved

This would still crash if we call it after calling the erase below

Open in Gerrit

Related details

Attention is currently required from:
  • Christoph Schwering
  • Gianmarco Picarella
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: Ic95dee48fa3ef8d2e3688880a3e49a6a37e4442b
Gerrit-Change-Number: 7743400
Gerrit-PatchSet: 2
Gerrit-Owner: Gianmarco Picarella <pica...@google.com>
Gerrit-Reviewer: Christoph Schwering <schw...@google.com>
Gerrit-Reviewer: Jihad Hanna <jihad...@google.com>
Gerrit-CC: Julia Sobiech <jsob...@google.com>
Gerrit-Attention: Gianmarco Picarella <pica...@google.com>
Gerrit-Attention: Christoph Schwering <schw...@google.com>
Gerrit-Comment-Date: Thu, 09 Apr 2026 12:40:34 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
satisfied_requirement
unsatisfied_requirement
open
diffy

Gianmarco Picarella (Gerrit)

unread,
Apr 9, 2026, 9:41:36 AM (4 days ago) Apr 9
to Jihad Hanna, Julia Sobiech, chromium...@chromium.org, browser-comp...@chromium.org
Attention needed from Christoph Schwering and Jihad Hanna

Gianmarco Picarella added 1 comment

File components/autofill/core/browser/filling/form_autofill_history.cc
Line 101, Patchset 2 (Latest): size_ -= fill_operation->erase(field_id);
Jihad Hanna . unresolved

This would still crash if we call it after calling the erase below

Gianmarco Picarella

True, I am wondering what could be the best approach for this case.

What if we use a boolean to inform the caller that the passed iterator got invalidated?

Open in Gerrit

Related details

Attention is currently required from:
  • Christoph Schwering
  • Jihad Hanna
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: Ic95dee48fa3ef8d2e3688880a3e49a6a37e4442b
Gerrit-Change-Number: 7743400
Gerrit-PatchSet: 2
Gerrit-Owner: Gianmarco Picarella <pica...@google.com>
Gerrit-Reviewer: Christoph Schwering <schw...@google.com>
Gerrit-Reviewer: Jihad Hanna <jihad...@google.com>
Gerrit-CC: Julia Sobiech <jsob...@google.com>
Gerrit-Attention: Jihad Hanna <jihad...@google.com>
Gerrit-Attention: Christoph Schwering <schw...@google.com>
Gerrit-Comment-Date: Thu, 09 Apr 2026 13:41:23 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Jihad Hanna <jihad...@google.com>
satisfied_requirement
unsatisfied_requirement
open
diffy

Jihad Hanna (Gerrit)

unread,
5:23 AM (3 hours ago) 5:23 AM
to Gianmarco Picarella, Julia Sobiech, chromium...@chromium.org, browser-comp...@chromium.org
Attention needed from Christoph Schwering and Gianmarco Picarella

Jihad Hanna added 1 comment

File components/autofill/core/browser/filling/form_autofill_history.cc
Line 101, Patchset 2 (Latest): size_ -= fill_operation->erase(field_id);
Jihad Hanna . unresolved

This would still crash if we call it after calling the erase below

Gianmarco Picarella

True, I am wondering what could be the best approach for this case.

What if we use a boolean to inform the caller that the passed iterator got invalidated?

Jihad Hanna

What about changing the function to `EraseFieldFillingEntries(base::flat_set<FieldGlobaId>)`? We would then call erase only at the end.

Open in Gerrit

Related details

Attention is currently required from:
  • Christoph Schwering
  • Gianmarco Picarella
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: Ic95dee48fa3ef8d2e3688880a3e49a6a37e4442b
Gerrit-Change-Number: 7743400
Gerrit-PatchSet: 2
Gerrit-Owner: Gianmarco Picarella <pica...@google.com>
Gerrit-Reviewer: Christoph Schwering <schw...@google.com>
Gerrit-Reviewer: Jihad Hanna <jihad...@google.com>
Gerrit-CC: Julia Sobiech <jsob...@google.com>
Gerrit-Attention: Gianmarco Picarella <pica...@google.com>
Gerrit-Attention: Christoph Schwering <schw...@google.com>
Gerrit-Comment-Date: Mon, 13 Apr 2026 09:23:35 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Gianmarco Picarella <pica...@google.com>
Comment-In-Reply-To: Jihad Hanna <jihad...@google.com>
satisfied_requirement
unsatisfied_requirement
open
diffy

Gianmarco Picarella (Gerrit)

unread,
6:02 AM (2 hours ago) 6:02 AM
to Jihad Hanna, Julia Sobiech, chromium...@chromium.org, browser-comp...@chromium.org
Attention needed from Christoph Schwering and Jihad Hanna

Gianmarco Picarella added 1 comment

File components/autofill/core/browser/filling/form_autofill_history.cc
Line 101, Patchset 2: size_ -= fill_operation->erase(field_id);
Jihad Hanna . unresolved

This would still crash if we call it after calling the erase below

Gianmarco Picarella

True, I am wondering what could be the best approach for this case.

What if we use a boolean to inform the caller that the passed iterator got invalidated?

Jihad Hanna

What about changing the function to `EraseFieldFillingEntries(base::flat_set<FieldGlobaId>)`? We would then call erase only at the end.

Gianmarco Picarella

Yes, I agree!

Open in Gerrit

Related details

Attention is currently required from:
  • Christoph Schwering
  • Jihad Hanna
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: Ic95dee48fa3ef8d2e3688880a3e49a6a37e4442b
Gerrit-Change-Number: 7743400
Gerrit-PatchSet: 2
Gerrit-Owner: Gianmarco Picarella <pica...@google.com>
Gerrit-Reviewer: Christoph Schwering <schw...@google.com>
Gerrit-Reviewer: Jihad Hanna <jihad...@google.com>
Gerrit-CC: Julia Sobiech <jsob...@google.com>
Gerrit-Attention: Jihad Hanna <jihad...@google.com>
Gerrit-Attention: Christoph Schwering <schw...@google.com>
Gerrit-Comment-Date: Mon, 13 Apr 2026 10:02:37 +0000
satisfied_requirement
unsatisfied_requirement
open
diffy

Jihad Hanna (Gerrit)

unread,
6:18 AM (2 hours ago) 6:18 AM
to Gianmarco Picarella, Julia Sobiech, chromium...@chromium.org, browser-comp...@chromium.org
Attention needed from Christoph Schwering and Gianmarco Picarella

Jihad Hanna voted and added 9 comments

Votes added by Jihad Hanna

Code-Review+1

9 comments

Patchset-level comments
File-level comment, Patchset 3 (Latest):
Jihad Hanna . resolved

Thanks for solving this!

File components/autofill/core/browser/filling/form_autofill_history.cc
Line 101, Patchset 2: size_ -= fill_operation->erase(field_id);
Jihad Hanna . resolved

This would still crash if we call it after calling the erase below

Gianmarco Picarella

True, I am wondering what could be the best approach for this case.

What if we use a boolean to inform the caller that the passed iterator got invalidated?

Jihad Hanna

What about changing the function to `EraseFieldFillingEntries(base::flat_set<FieldGlobaId>)`? We would then call erase only at the end.

Gianmarco Picarella

Yes, I agree!

Jihad Hanna

Thank you :)

Line 105, Patchset 3 (Latest): if (entry_iter->empty()) {
history_.erase(entry_iter);
}
Jihad Hanna . unresolved

I understand that the fact that the set imposes uniqueness resolves the bug at hand, but I'd rather we move this outside the loop and till the end.

File components/autofill/core/browser/filling/form_filler.cc
Line 834, Patchset 3 (Latest): // Multiple fields within a single form may have the same FieldGlobalId. To
Jihad Hanna . unresolved

backticks

Line 834, Patchset 3 (Latest): // Multiple fields within a single form may have the same FieldGlobalId. To
Jihad Hanna . unresolved
Line 837, Patchset 3 (Latest): // FormAutofillHistory::AddFormFillingEntry(...) silently collapses fields
Jihad Hanna . unresolved

backticks

Line 837, Patchset 3 (Latest): // FormAutofillHistory::AddFormFillingEntry(...) silently collapses fields
Jihad Hanna . unresolved

remove

Line 834, Patchset 3 (Latest): // Multiple fields within a single form may have the same FieldGlobalId. To
// prevent redundant deletion attempts from the autofill history, we filter
// for unique IDs before processing the list. This is needed because
// FormAutofillHistory::AddFormFillingEntry(...) silently collapses fields
// with duplicate FieldGlobalId.
Jihad Hanna . unresolved

I think this comment is confusing, the problem we're after is UAF caused by deleting the entry then accessing it again using duplicate IDs.

Line 838, Patchset 3 (Latest): // with duplicate FieldGlobalId.
Jihad Hanna . unresolved

backticks

Open in Gerrit

Related details

Attention is currently required from:
  • Christoph Schwering
  • Gianmarco Picarella
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: Ic95dee48fa3ef8d2e3688880a3e49a6a37e4442b
Gerrit-Change-Number: 7743400
Gerrit-PatchSet: 3
Gerrit-Owner: Gianmarco Picarella <pica...@google.com>
Gerrit-Reviewer: Christoph Schwering <schw...@google.com>
Gerrit-Reviewer: Jihad Hanna <jihad...@google.com>
Gerrit-CC: Julia Sobiech <jsob...@google.com>
Gerrit-Attention: Gianmarco Picarella <pica...@google.com>
Gerrit-Attention: Christoph Schwering <schw...@google.com>
Gerrit-Comment-Date: Mon, 13 Apr 2026 10:18:12 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: Yes
satisfied_requirement
unsatisfied_requirement
open
diffy

Gianmarco Picarella (Gerrit)

unread,
7:22 AM (1 hour ago) 7:22 AM
to Jihad Hanna, Julia Sobiech, chromium...@chromium.org, browser-comp...@chromium.org
Attention needed from Christoph Schwering and Jihad Hanna

Gianmarco Picarella added 7 comments

File components/autofill/core/browser/filling/form_autofill_history.cc
Line 105, Patchset 3: if (entry_iter->empty()) {
history_.erase(entry_iter);
}
Jihad Hanna . unresolved

I understand that the fact that the set imposes uniqueness resolves the bug at hand, but I'd rather we move this outside the loop and till the end.

Gianmarco Picarella

Okay!

File components/autofill/core/browser/filling/form_filler.cc
Line 834, Patchset 3: // Multiple fields within a single form may have the same FieldGlobalId. To
Jihad Hanna . resolved

(see crbug.com/41496988)

Gianmarco Picarella

Done

Line 834, Patchset 3: // Multiple fields within a single form may have the same FieldGlobalId. To
Jihad Hanna . resolved

backticks

Gianmarco Picarella

Done

Line 837, Patchset 3: // FormAutofillHistory::AddFormFillingEntry(...) silently collapses fields
Jihad Hanna . resolved

remove

Gianmarco Picarella

Done

Line 837, Patchset 3: // FormAutofillHistory::AddFormFillingEntry(...) silently collapses fields
Jihad Hanna . resolved

backticks

Gianmarco Picarella

Done

Line 834, Patchset 3: // Multiple fields within a single form may have the same FieldGlobalId. To

// prevent redundant deletion attempts from the autofill history, we filter
// for unique IDs before processing the list. This is needed because
// FormAutofillHistory::AddFormFillingEntry(...) silently collapses fields
// with duplicate FieldGlobalId.
Jihad Hanna . unresolved

I think this comment is confusing, the problem we're after is UAF caused by deleting the entry then accessing it again using duplicate IDs.

Gianmarco Picarella

Does it look clear now?

Line 838, Patchset 3: // with duplicate FieldGlobalId.
Jihad Hanna . resolved

backticks

Gianmarco Picarella

Done

Open in Gerrit

Related details

Attention is currently required from:
  • Christoph Schwering
  • Jihad Hanna
Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: Ic95dee48fa3ef8d2e3688880a3e49a6a37e4442b
    Gerrit-Change-Number: 7743400
    Gerrit-PatchSet: 4
    Gerrit-Owner: Gianmarco Picarella <pica...@google.com>
    Gerrit-Reviewer: Christoph Schwering <schw...@google.com>
    Gerrit-Reviewer: Jihad Hanna <jihad...@google.com>
    Gerrit-CC: Julia Sobiech <jsob...@google.com>
    Gerrit-Attention: Jihad Hanna <jihad...@google.com>
    Gerrit-Attention: Christoph Schwering <schw...@google.com>
    Gerrit-Comment-Date: Mon, 13 Apr 2026 11:22:39 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Jihad Hanna <jihad...@google.com>
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Christoph Schwering (Gerrit)

    unread,
    7:45 AM (1 hour ago) 7:45 AM
    to Gianmarco Picarella, Jihad Hanna, Julia Sobiech, chromium...@chromium.org, browser-comp...@chromium.org
    Attention needed from Gianmarco Picarella and Jihad Hanna

    Christoph Schwering added 4 comments

    File components/autofill/core/browser/filling/form_autofill_history.h
    Line 109, Patchset 3: void EraseFieldFillingEntries(const base::flat_set<FieldGlobalId>& fields_id);
    Christoph Schwering . unresolved

    nit: `field_ids`?

    File components/autofill/core/browser/filling/form_autofill_history.cc
    Line 105, Patchset 3: if (entry_iter->empty()) {
    history_.erase(entry_iter);
    }
    Jihad Hanna . unresolved

    I understand that the fact that the set imposes uniqueness resolves the bug at hand, but I'd rather we move this outside the loop and till the end.

    Gianmarco Picarella

    Okay!

    Christoph Schwering

    For both the PS3 and PS4 version I don't see yet why it works:

    PS3: Why is `CHECK(entry_iter != history_.end());` guaranteed? It depends on the caller, doesn't it?

    PS4: What prevents us from having duplicates in `operations` and thus double frees?

    Shouldn't we just do `std::erase_if(history_, [](const FormFillingEntry& entry){ return entry.empty(); });`?

    File components/autofill/core/browser/filling/form_filler.cc
    Line 837, Patchset 3: // FormAutofillHistory::AddFormFillingEntry(...) silently collapses fields
    Jihad Hanna . resolved

    remove

    Gianmarco Picarella

    Done

    Christoph Schwering

    Btw I'm not aware of a rule to put every code in backticks. I think it often just adds noise.

    Line 837, Patchset 4 (Latest): // `FieldGlobalId` is encountered, causing an usage-after-free crash. This
    Christoph Schwering . unresolved

    nit: remove, because the crash is not guaranteed (I think) and among the better outcomes.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Gianmarco Picarella
    • Jihad Hanna
    Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: Ic95dee48fa3ef8d2e3688880a3e49a6a37e4442b
    Gerrit-Change-Number: 7743400
    Gerrit-PatchSet: 4
    Gerrit-Owner: Gianmarco Picarella <pica...@google.com>
    Gerrit-Reviewer: Christoph Schwering <schw...@google.com>
    Gerrit-Reviewer: Jihad Hanna <jihad...@google.com>
    Gerrit-CC: Julia Sobiech <jsob...@google.com>
    Gerrit-Attention: Gianmarco Picarella <pica...@google.com>
    Gerrit-Attention: Jihad Hanna <jihad...@google.com>
    Gerrit-Comment-Date: Mon, 13 Apr 2026 11:44:55 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy
    Reply all
    Reply to author
    Forward
    0 new messages