def _push_new_ranges_and_versions(self, source_repo, repo, vulnerability, yaml_path, original_sha256, range_collectors, versions): """Pushes new ranges and versions.""" old_ranges = list(vulnerability.affects.ranges) del vulnerability.affects.ranges[:] for repo_url, range_collector in range_collectors.items(): for introduced, fixed in range_collector.ranges(): vulnerability.affects.ranges.add( type=vulnerability_pb2.AffectedRange.Type.GIT, repo=repo_url, introduced=introduced, fixed=fixed) has_changes = old_ranges != list(vulnerability.affects.ranges) for version in sorted(versions): if version not in vulnerability.affects.versions: has_changes = True vulnerability.affects.versions.append(version) if not has_changes: return True # Write updates, and push. vulnerability.modified.FromDatetime(osv.utcnow()) osv.vulnerability_to_yaml(vulnerability, yaml_path) repo.index.add_all() return osv.push_source_changes(repo, f'Update {vulnerability.id}', self._git_callbacks(source_repo), expected_hashes={ yaml_path: original_sha256, })
def _push_new_ranges_and_versions(self, source_repo, repo, vulnerability, yaml_path, original_sha256, range_collectors, versions): """Pushes new ranges and versions.""" has_changes = False for repo_url, range_collector in range_collectors.items(): for introduced, fixed in range_collector.ranges(): if any( # Range collectors use None, while the proto uses '' for empty # values. (affected_range.introduced or None) == introduced and ( affected_range.fixed or None) == fixed for affected_range in vulnerability.affects.ranges): # Range already exists. continue has_changes = True vulnerability.affects.ranges.add( type=vulnerability_pb2.AffectedRange.Type.GIT, repo=repo_url, introduced=introduced, fixed=fixed) for version in sorted(versions): if version not in vulnerability.affects.versions: has_changes = True vulnerability.affects.versions.append(version) if not has_changes: return True # Write updates, and push. vulnerability.modified.FromDatetime(osv.utcnow()) osv.vulnerability_to_yaml(vulnerability, yaml_path) repo.index.add_all() return osv.push_source_changes(repo, f'Update {vulnerability.id}', self._git_callbacks(source_repo), expected_hashes={ yaml_path: original_sha256, })
def _push_new_ranges_and_versions(self, source_repo, repo, vulnerability, yaml_path, added_ranges, added_versions): # Add new ranges and versions (sorted for determinism). for repo_url, introduced, fixed in sorted(added_ranges): vulnerability.affects.ranges.add( type=vulnerability_pb2.AffectedRangeNew.Type.GIT, repo=repo_url, introduced=introduced, fixed=fixed) for version in sorted(added_versions): vulnerability.affects.versions.append(version) # Write updates, and push. vulnerability.last_modified.FromDatetime(osv.utcnow()) osv.vulnerability_to_yaml(vulnerability, yaml_path) # TODO(ochang): Hash check for conflicts. repo.index.add_all() return osv.push_source_changes(repo, f'Update {vulnerability.id}', self._git_callbacks(source_repo))
def import_new_oss_fuzz_entries(self, repo, oss_fuzz_source): """Import new entries.""" exported = [] vulnerabilities_path = os.path.join( osv.repo_path(repo), oss_fuzz_source.directory_path or '') for bug in osv.Bug.query( osv.Bug.source_of_truth == osv.SourceOfTruth.INTERNAL): if bug.status != osv.BugStatus.PROCESSED: continue if not bug.public: continue source_name, _ = osv.parse_source_id(bug.source_id) if source_name != oss_fuzz_source.name: continue vulnerability_path = os.path.join(vulnerabilities_path, osv.source_path(bug)) os.makedirs(os.path.dirname(vulnerability_path), exist_ok=True) if os.path.exists(vulnerability_path): continue logging.info('Writing %s', bug.key.id()) osv.vulnerability_to_yaml(bug.to_vulnerability(), vulnerability_path) # The source of truth is now this yaml file. bug.source_of_truth = osv.SourceOfTruth.SOURCE_REPO exported.append(bug) # Commit Vulnerability changes back to the oss-fuzz source repository. repo.index.add_all() diff = repo.index.diff_to_tree(repo.head.peel().tree) if not diff: logging.info('No new entries, skipping committing.') return logging.info('Commiting and pushing new entries') if osv.push_source_changes(repo, 'Import from OSS-Fuzz', self._git_callbacks(oss_fuzz_source)): ndb.put_multi(exported)
def import_new_oss_fuzz_entries(self, repo, oss_fuzz_source): """Import new entries.""" # TODO(ochang): Make this more efficient by recording whether or not we # imported already in Datastore. vulnerabilities_path = os.path.join( osv.repo_path(repo), oss_fuzz_source.directory_path or '') for bug in osv.Bug.query(osv.Bug.status == osv.BugStatus.PROCESSED): if not bug.public: continue source_name, source_id = osv.parse_source_id(bug.source_id) if source_name != oss_fuzz_source.name: continue project_dir = os.path.join(vulnerabilities_path, bug.project) os.makedirs(project_dir, exist_ok=True) vulnerability_path = os.path.join( project_dir, source_id + VULNERABILITY_EXTENSION) if os.path.exists(vulnerability_path): continue logging.info('Writing %s', bug.key.id()) osv.vulnerability_to_yaml(bug.to_vulnerability_new(), vulnerability_path) # Commit Vulnerability changes back to the oss-fuzz source repository. repo.index.add_all() diff = repo.index.diff_to_tree(repo.head.peel().tree) if not diff: logging.info('No new entries, skipping committing.') return logging.info('Commiting and pushing new entries') osv.push_source_changes(repo, 'Import from OSS-Fuzz', self._git_callbacks(oss_fuzz_source))