fix-invalid-end-iterator-usage-in-CookieMonster.patch 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. From 53478caee862624fc6d73516f8d64253854b146f Mon Sep 17 00:00:00 2001
  2. From: Piotr Tworek <ptworek@vewd.com>
  3. Date: Mon, 31 Aug 2020 21:03:58 +0000
  4. Subject: [PATCH] Fix invalid "end" iterator usage in CookieMonster.
  5. Commit 229623d76e8baf714c8569c9f4efc5de266cef8b has introduced the following
  6. code in cookie_monster.cc.
  7. // If this is the first cookie in |cookies_| with this key, increment the
  8. // |num_keys_| counter.
  9. bool different_prev =
  10. inserted == cookies_.begin() || std::prev(inserted)->first != key;
  11. bool different_next =
  12. inserted == cookies_.end() || std::next(inserted)->first != key;
  13. if (different_prev && different_next)
  14. ++num_keys_;
  15. The "inserted" iterator is something that has been returned from
  16. std::multimap::insert. At first glance it looks reasonable. The code
  17. tries to determine if there are already similar elements with the same
  18. key in the map. Unfortunately the expression calculating the value of
  19. different_next can potentially use the end iterator to the map. The
  20. "inserted == cookies_.end()" part of the expression will always evaluate
  21. to false since the newly inserted element has to be in the map and
  22. cookies_.end() points to the first element outside the map. If the
  23. inserted happens to be the last element in the map the second part of
  24. the expression will grab the end iterator by calling std::next(inserted)
  25. and then will try to use it leading to invalid memory access.
  26. Given the fact that cookies_ is a std::multimap we should not even need
  27. to calculate the value of different_next. It should always be true.
  28. "If the container has elements with equivalent key, inserts at the
  29. upper bound of that range.(since C++11)"
  30. See: https://en.cppreference.com/w/cpp/container/multimap/insert
  31. Bug: 1120240
  32. Change-Id: I8928c294ac4daf72349a2331b31b017c1d015da0
  33. Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2368872
  34. Reviewed-by: Maksim Orlovich <morlovich@chromium.org>
  35. Commit-Queue: Piotr Tworek <ptworek@vewd.com>
  36. Cr-Commit-Position: refs/heads/master@{#803260}
  37. ---
  38. net/cookies/cookie_monster.cc | 13 +++++++++----
  39. 1 file changed, 9 insertions(+), 4 deletions(-)
  40. diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc
  41. index 265deed0e52..140b61a81dc 100644
  42. --- a/net/cookies/cookie_monster.cc
  43. +++ b/net/cookies/cookie_monster.cc
  44. @@ -1151,9 +1151,14 @@ CookieMonster::CookieMap::iterator CookieMonster::InternalInsertCookie(
  45. // |num_keys_| counter.
  46. bool different_prev =
  47. inserted == cookies_.begin() || std::prev(inserted)->first != key;
  48. - bool different_next =
  49. - inserted == cookies_.end() || std::next(inserted)->first != key;
  50. - if (different_prev && different_next)
  51. + // According to std::multiqueue documentation:
  52. + // "If the container has elements with equivalent key, inserts at the upper
  53. + // bound of that range. (since C++11)"
  54. + // This means that "inserted" iterator either points to the last element in
  55. + // the map, or the element succeeding it has to have different key.
  56. + DCHECK(std::next(inserted) == cookies_.end() ||
  57. + std::next(inserted)->first != key);
  58. + if (different_prev)
  59. ++num_keys_;
  60. return inserted;
  61. @@ -1381,7 +1386,7 @@ void CookieMonster::InternalDeleteCookie(CookieMap::iterator it,
  62. bool different_prev =
  63. it == cookies_.begin() || std::prev(it)->first != it->first;
  64. bool different_next =
  65. - it == cookies_.end() || std::next(it)->first != it->first;
  66. + std::next(it) == cookies_.end() || std::next(it)->first != it->first;
  67. if (different_prev && different_next)
  68. --num_keys_;