Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1221)

Unified Diff: net/cookies/cookie_monster.cc

Issue 1939623002: Strict Secure Cookies re-implemented to be priority aware (Closed) Base URL: https://chromium.googlesource.com/chromium/src@master
Patch Set: Rebase on ToT Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/cookies/cookie_monster.cc
diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc
index e208d332882e58ecfd09c6d0c88baa6916168a88..e87ed2c661deba34a9f374394088956f651adc40 100644
--- a/net/cookies/cookie_monster.cc
+++ b/net/cookies/cookie_monster.cc
@@ -309,6 +309,24 @@ void RunAsync(scoped_refptr<base::TaskRunner> proxy,
proxy->PostTask(FROM_HERE, base::Bind(callback, cookie, removed));
}
+bool IsCookieEligibleForEviction(CookiePriority current_priority_level,
+ bool protect_secure_cookies,
+ const CanonicalCookie* cookie) {
+ if (!cookie->IsSecure() || !protect_secure_cookies)
+ return cookie->Priority() <= current_priority_level;
+
+ // Special consideration has to be given for low-priority secure cookies since
+ // they are given lower prority than non-secure medium-priority and non-secure
+ // high-priority cookies. Thus, low-priority secure cookies may be evicted at
+ // a medium and high value of |current_priority_level|. Put another way,
+ // low-priority secure cookies are only protected when the current priority
+ // level is low.
+ if (current_priority_level == COOKIE_PRIORITY_LOW)
+ return false;
+
+ return cookie->Priority() == COOKIE_PRIORITY_LOW;
+}
Mike West 2016/05/04 08:08:19 This is clever. It wasn't at all how I'd considere
jww 2016/05/05 18:56:26 Yay! Thanks.
+
} // namespace
CookieMonster::CookieMonster(PersistentCookieStore* store,
@@ -1869,15 +1887,6 @@ size_t CookieMonster::GarbageCollect(const Time& current,
num_deleted +=
GarbageCollectExpired(current, cookies_.equal_range(key), cookie_its);
- // TODO(mkwst): Soften this.
- CookieItVector secure_cookie_its;
- if (enforce_strict_secure && cookie_its->size() > kDomainMaxCookies) {
- VLOG(kVlogGarbageCollection) << "Garbage collecting non-Secure cookies.";
- num_deleted +=
- GarbageCollectNonSecure(non_expired_cookie_its, &secure_cookie_its);
Mike West 2016/05/04 08:08:19 Nit: I think this was the only callsite to `Garbag
jww 2016/05/05 18:56:26 Done.
- cookie_its = &secure_cookie_its;
- }
-
if (cookie_its->size() > kDomainMaxCookies) {
VLOG(kVlogGarbageCollection) << "Deep Garbage Collect domain.";
size_t purge_goal =
@@ -1892,17 +1901,55 @@ size_t CookieMonster::GarbageCollect(const Time& current,
// bump the quota and remove low- and medium-priority. Then, if cookies
// _still_ need to be removed, bump the quota and remove cookies with
// any priority.
- const size_t kQuotas[3] = {kDomainCookiesQuotaLow,
- kDomainCookiesQuotaMedium,
- kDomainCookiesQuotaHigh};
+ //
+ // 1. Low-priority non-secure cookies.
+ // 2. Low-priority secure cookies.
+ // 3. Medium-priority non-secure cookies.
+ // 4. High-priority non-secure cookies.
+ // 5. Medium-priority secure cookies.
+ // 6. High-priority secure cookies.
+ const static struct {
+ CookiePriority priority;
+ size_t quota;
Mike West 2016/05/04 08:08:19 Nit: Maybe "additionalQuota"? I missed the `+=` bi
jww 2016/05/05 18:56:26 Done.
+ bool protect_secure_cookies;
+ } purge_rounds[] = {
+ // 1. Low-priority non-secure cookies.
+ {COOKIE_PRIORITY_LOW, kDomainCookiesQuotaLow, true},
+ // 2. Low-priority secure cookies.
+ {COOKIE_PRIORITY_LOW, 0U, false},
Mike West 2016/05/04 08:08:19 Tiny nit: lowercase 'u', here and below.
jww 2016/05/05 18:56:26 Done.
+ // 3. Medium-priority non-secure cookies.
+ {COOKIE_PRIORITY_MEDIUM, kDomainCookiesQuotaMedium, true},
+ // 4. High-priority non-secure cookies.
+ {COOKIE_PRIORITY_HIGH, kDomainCookiesQuotaHigh, true},
+ // 5. Medium-priority secure cookies.
+ {COOKIE_PRIORITY_MEDIUM, 0U, false},
+ // 6. High-priority secure cookies.
+ {COOKIE_PRIORITY_HIGH, 0U, false},
+ };
+
size_t quota = 0;
- for (size_t i = 0; i < arraysize(kQuotas) && purge_goal > 0; i++) {
- quota += kQuotas[i];
- size_t just_deleted = PurgeLeastRecentMatches(
- cookie_its, static_cast<CookiePriority>(i), quota, purge_goal);
- DCHECK_LE(just_deleted, purge_goal);
- purge_goal -= just_deleted;
- num_deleted += just_deleted;
+ for (size_t i = 0; i < arraysize(purge_rounds) && purge_goal > 0; i++) {
Mike West 2016/05/04 08:08:19 Nit: C++11 `for`? We'd used a regular `for` loop i
jww 2016/05/05 18:56:26 Done.
+ quota += purge_rounds[i].quota;
+ size_t just_deleted = 0u;
+
+ // Only observe the non-secure purge rounds if strict secure cookies is
+ // enabled.
+ if (!enforce_strict_secure && purge_rounds[i].protect_secure_cookies)
+ continue;
+
+ // Purge up to |purge_goal| for all cookies at the given priority. This
+ // path will always execute if strict secure cookies is disabled since
+ // |purge_goal| must be positive because of the for-loop guard. If
+ // strict secure cookies is enabled, this path will be taken only if the
+ // initial non-secure purge did not evict enough cookies.
+ if (purge_goal > 0) {
+ just_deleted = PurgeLeastRecentMatches(
+ cookie_its, purge_rounds[i].priority, quota, purge_goal,
+ purge_rounds[i].protect_secure_cookies);
+ DCHECK_LE(just_deleted, purge_goal);
+ purge_goal -= just_deleted;
+ num_deleted += just_deleted;
+ }
}
DCHECK_EQ(0U, purge_goal);
@@ -1955,12 +2002,43 @@ size_t CookieMonster::GarbageCollect(const Time& current,
size_t CookieMonster::PurgeLeastRecentMatches(CookieItVector* cookies,
CookiePriority priority,
size_t to_protect,
- size_t purge_goal) {
+ size_t purge_goal,
+ bool protect_secure_cookies) {
DCHECK(thread_checker_.CalledOnValidThread());
// Find the first protected cookie by walking down from the end of the list
// cookie list (most-recently accessed) until |to_protect| cookies that match
// |priority| are found.
+ //
+ // If |protect_secure_cookies| is true, do a first pass that counts eligible
+ // secure cookies at the specified priority as protected.
+ if (protect_secure_cookies) {
+ for (size_t i = 0; to_protect > 0 && i < cookies->size(); i++) {
+ if (!cookies->at(i)->second->IsSecure())
+ continue;
+ // 1) At low-priority, only low-priority secure cookies are protected as
+ // part of the quota.
+ // 2) At medium-priority, only medium-priority secure cookies are
+ // protected as part of the quota (low-priority secure cookies may be
+ // deleted).
+ // 3) At high-priority, medium-priority and high-priority secure cookies
+ // are protected as part of the quota (low-priority secure cookies may
+ // be deleted).
+ CookiePriority cookie_priority = cookies->at(i)->second->Priority();
+ switch (cookie_priority) {
+ case COOKIE_PRIORITY_LOW:
+ if (priority == COOKIE_PRIORITY_LOW)
+ to_protect--;
+ break;
+ case COOKIE_PRIORITY_MEDIUM:
+ case COOKIE_PRIORITY_HIGH:
+ if (cookie_priority <= priority)
+ to_protect--;
+ break;
+ }
+ }
+ }
Mike West 2016/05/04 08:08:19 Nit: This took me longer than I care to admit to w
jww 2016/05/05 18:56:26 Done.
+
size_t protection_boundary = cookies->size();
while (to_protect > 0 && protection_boundary > 0) {
protection_boundary--;
@@ -1974,7 +2052,12 @@ size_t CookieMonster::PurgeLeastRecentMatches(CookieItVector* cookies,
size_t removed = 0;
size_t current = 0;
while (removed < purge_goal && current < protection_boundary) {
- if (cookies->at(current)->second->Priority() <= priority) {
+ const CanonicalCookie* current_cookie = cookies->at(current)->second;
+ // Only delete the current cookie if the priority is less than or equal to
+ // the current level. If it is equal to the current level, and secure
+ // cookies are protected, only delete it if it is not secure.
+ if (IsCookieEligibleForEviction(priority, protect_secure_cookies,
+ current_cookie)) {
InternalDeleteCookie(cookies->at(current), true,
DELETE_COOKIE_EVICTED_DOMAIN);
cookies->erase(cookies->begin() + current);

Powered by Google App Engine
This is Rietveld 408576698