Commit message: None
CVE: CVE-2018-6033
CWE: CWE-20
Vulnerability description: Insufficient data validation in Downloads in Google Chrome prior to 64.0.3282.119 allowed a remote attacker to potentially run arbitrary code outside sandbox via a crafted Chrome Extension.

Project: Chrome

bool ChromeDownloadManagerDelegate::DetermineDownloadTarget(
    DownloadItem* download,
    const content::DownloadTargetCallback& callback) {
  if (download->GetTargetFilePath().empty() &&
      download->GetMimeType() == kPDFMimeType && !download->HasUserGesture()) {
    ReportPDFLoadStatus(PDFLoadStatus::kTriggeredNoGestureDriveByDownload);
  }

  DownloadTargetDeterminer::CompletionCallback target_determined_callback =
      base::Bind(&ChromeDownloadManagerDelegate::OnDownloadTargetDetermined,
                 weak_ptr_factory_.GetWeakPtr(),
                 download->GetId(),
                 callback);
  DownloadTargetDeterminer::Start(
      download,
      GetPlatformDownloadPath(profile_, download, PLATFORM_TARGET_PATH),
      kDefaultPlatformConflictAction, download_prefs_.get(), this,
      target_determined_callback);
  return true;
}

Project: Chrome

void ChromeDownloadManagerDelegate::DisableSafeBrowsing(DownloadItem* item) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
#if defined(FULL_SAFE_BROWSING)
  SafeBrowsingState* state = static_cast<SafeBrowsingState*>(
      item->GetUserData(&kSafeBrowsingUserDataKey));
  if (!state) {
    state = new SafeBrowsingState();
    item->SetUserData(&kSafeBrowsingUserDataKey, base::WrapUnique(state));
  }
  state->CompleteDownload();
#endif
}

Project: Chrome

void OnAcquireFileAccessPermissionDone(
    const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter,
    const GURL& url,
    const std::string& request_method,
    CanDownloadCallback can_download_cb,
    bool granted) {
  if (granted) {
    CheckCanDownload(web_contents_getter, url, request_method,
                     std::move(can_download_cb));
  } else {
    std::move(can_download_cb).Run(false, false);
  }
}

Project: Chrome

void ChromeDownloadManagerDelegate::OpenDownload(DownloadItem* download) {
  DCHECK_EQ(DownloadItem::COMPLETE, download->GetState());
  DCHECK(!download->GetTargetFilePath().empty());
  if (!download->CanOpenDownload())
    return;

  MaybeSendDangerousDownloadOpenedReport(download,
                                         false /* show_download_in_folder */);

  if (!DownloadItemModel(download).ShouldPreferOpeningInBrowser()) {
    RecordDownloadOpenMethod(DOWNLOAD_OPEN_METHOD_DEFAULT_PLATFORM);
    OpenDownloadUsingPlatformHandler(download);
    return;
  }

#if !defined(OS_ANDROID)
  content::WebContents* web_contents = download->GetWebContents();
  Browser* browser =
      web_contents ? chrome::FindBrowserWithWebContents(web_contents) : NULL;
  std::unique_ptr<chrome::ScopedTabbedBrowserDisplayer> browser_displayer;
  if (!browser ||
      !browser->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP)) {
    browser_displayer.reset(new chrome::ScopedTabbedBrowserDisplayer(profile_));
    browser = browser_displayer->browser();
  }
  content::OpenURLParams params(
      net::FilePathToFileURL(download->GetTargetFilePath()),
      content::Referrer(), WindowOpenDisposition::NEW_FOREGROUND_TAB,
      ui::PAGE_TRANSITION_LINK, false);

  if (download->GetMimeType() == "application/x-x509-user-cert")
    chrome::ShowSettingsSubPage(browser, "certificates");
  else
    browser->OpenURL(params);

  RecordDownloadOpenMethod(DOWNLOAD_OPEN_METHOD_DEFAULT_BROWSER);
#else
  NOTREACHED();
 #endif
 }

Project: Chrome

void DownloadItemImpl::AddObserver(Observer* observer) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  observers_.AddObserver(observer);
}

Project: Chrome

void DeleteDownloadedFileDone(
    base::WeakPtr<DownloadItemImpl> item,
    const base::Callback<void(bool)>& callback,
    bool success) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (success && item.get())
    item->OnDownloadedFileRemoved();
  callback.Run(success);
}

Project: Chrome

DownloadItemImpl::DestinationInfo::DestinationInfo(
    TargetDisposition target_disposition)
    : target_disposition(target_disposition) {}

Project: Chrome

DownloadItem::TargetDisposition DownloadItemImpl::GetTargetDisposition() const {
  return destination_info_.target_disposition;
}

Project: Chrome

void DownloadItemImpl::ResumeInterruptedDownload(
    ResumptionRequestSource source) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (state_ != INTERRUPTED_INTERNAL)
    return;

  DCHECK(!download_file_);
  weak_ptr_factory_.InvalidateWeakPtrs();

  ResumeMode mode = GetResumeMode();
  if (mode == RESUME_MODE_IMMEDIATE_RESTART ||
      mode == RESUME_MODE_USER_RESTART) {
    DCHECK(GetFullPath().empty());
    destination_info_.received_bytes = 0;
    last_modified_time_.clear();
    etag_.clear();
    destination_info_.hash.clear();
    hash_state_.reset();
    received_slices_.clear();
  }

  StoragePartition* storage_partition =
      BrowserContext::GetStoragePartitionForSite(GetBrowserContext(),
                                                 request_info_.site_url);

  net::NetworkTrafficAnnotationTag traffic_annotation =
      net::DefineNetworkTrafficAnnotation("download_manager_resume", R"(
        semantics {
          sender: "Download Manager"
          description:
            "When user resumes downloading a file, a network request is made "
            "to fetch it."
          trigger:
            "User resumes a download."
          data: "None."
          destination: WEBSITE
        }
        policy {
          cookies_allowed: YES
          cookies_store: "user"
          setting:
            "This feature cannot be disabled in settings, but it is activated "
            "by direct user action."
          chrome_policy {
            DownloadRestrictions {
              DownloadRestrictions: 3
            }
          }
        })");
  std::unique_ptr<DownloadUrlParameters> download_params(
      new DownloadUrlParameters(GetURL(),
                                storage_partition->GetURLRequestContext(),
                                traffic_annotation));
  download_params->set_file_path(GetFullPath());
  if (received_slices_.size() > 0) {
    std::vector<DownloadItem::ReceivedSlice> slices_to_download
        = FindSlicesToDownload(received_slices_);
    download_params->set_offset(slices_to_download[0].offset);
  } else {
    download_params->set_offset(GetReceivedBytes());
  }
  download_params->set_last_modified(GetLastModifiedTime());
  download_params->set_etag(GetETag());
  download_params->set_hash_of_partial_file(GetHash());
  download_params->set_hash_state(std::move(hash_state_));
  download_params->set_fetch_error_body(fetch_error_body_);

  auto* manager_delegate = GetBrowserContext()->GetDownloadManagerDelegate();
  if (manager_delegate) {
    download::InProgressCache* in_progress_cache =
        manager_delegate->GetInProgressCache();
    if (in_progress_cache) {
      base::Optional<download::DownloadEntry> entry =
          in_progress_cache->RetrieveEntry(GetGuid());
      if (entry)
        download_params->set_request_origin(entry.value().request_origin);
    }
  }

  download_params->set_referrer(
      Referrer(GetReferrerUrl(), blink::kWebReferrerPolicyAlways));

  TransitionTo(RESUMING_INTERNAL);
  RecordDownloadSource(source == ResumptionRequestSource::USER
                           ? INITIATED_BY_MANUAL_RESUMPTION
                           : INITIATED_BY_AUTOMATIC_RESUMPTION);
  delegate_->ResumeInterruptedDownload(std::move(download_params), GetId());

  if (job_)
    job_->Resume(false);
}

Project: Chrome

void DownloadItemImpl::SetFullPath(const base::FilePath& new_path) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  DVLOG(20) << __func__ << "() new_path = \"" << new_path.value() << "\" "
            << DebugString(true);
  DCHECK(!new_path.empty());

  TRACE_EVENT_INSTANT2("download", "DownloadItemRenamed",
                       TRACE_EVENT_SCOPE_THREAD, "old_filename",
                       destination_info_.current_path.AsUTF8Unsafe(),
                       "new_filename", new_path.AsUTF8Unsafe());

  destination_info_.current_path = new_path;
}

Project: Chrome

void DownloadItemImpl::ShowDownloadInShell() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  delegate_->ShowDownloadInShell(this);
}

Project: Chrome

DownloadItemImpl::~DownloadItemImpl() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  DCHECK(!download_file_.get());
  CHECK(!is_updating_observers_);

  for (auto& observer : observers_)
    observer.OnDownloadDestroyed(this);
  delegate_->AssertStateConsistent(this);
  delegate_->Detach();
}

Project: Chrome

void DownloadItemImplDelegate::UpdatePersistence(DownloadItemImpl* download) {}

Project: Chrome

DownloadItemImplDelegate::~DownloadItemImplDelegate() {
  DCHECK_EQ(0, count_);
}

Project: Chrome

DownloadManagerDelegate* DownloadManagerImpl::GetDelegate() const {
  return delegate_;
}

Project: Chrome

void DownloadManagerImpl::GetNextId(const DownloadIdCallback& callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (delegate_) {
    delegate_->GetNextId(callback);
    return;
  }
  static uint32_t next_id = content::DownloadItem::kInvalidId + 1;
  callback.Run(next_id++);
}

Project: Chrome

StoragePartitionImpl* GetStoragePartition(BrowserContext* context,
                                          int render_process_id,
                                          int render_frame_id) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  SiteInstance* site_instance = nullptr;
  if (render_process_id >= 0) {
    RenderFrameHost* render_frame_host_ =
        RenderFrameHost::FromID(render_process_id, render_frame_id);
    if (render_frame_host_)
      site_instance = render_frame_host_->GetSiteInstance();
  }
  return static_cast<StoragePartitionImpl*>(
      BrowserContext::GetStoragePartition(context, site_instance));
}

Project: Chrome

void DownloadManagerImpl::OnFileExistenceChecked(uint32_t download_id,
                                                 bool result) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (!result) {  // File does not exist.
    if (base::ContainsKey(downloads_, download_id))
      downloads_[download_id]->OnDownloadedFileRemoved();
  }
}

Project: Chrome

DownloadManagerDelegate::ApplicationClientIdForFileScanning() const {
  return std::string();
}