mirror of https://github.com/google/oss-fuzz.git
96 lines
3.6 KiB
Python
96 lines
3.6 KiB
Python
# Copyright 2019 Google LLC
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
"""Module to build a image from a specific commit, branch or pull request
|
|
|
|
This module is allows each of the OSS Fuzz projects fuzzers to be built
|
|
from a specific point in time. This feature can be used for implementations
|
|
like continuious integration fuzzing and bisection to find errors
|
|
"""
|
|
import os
|
|
import collections
|
|
import logging
|
|
import re
|
|
|
|
import helper
|
|
import utils
|
|
|
|
BuildData = collections.namedtuple(
|
|
'BuildData', ['project_name', 'engine', 'sanitizer', 'architecture'])
|
|
|
|
|
|
def build_fuzzers_from_commit(commit, build_repo_manager, build_data):
|
|
"""Builds a OSS-Fuzz fuzzer at a specific commit SHA.
|
|
|
|
Args:
|
|
commit: The commit SHA to build the fuzzers at.
|
|
build_repo_manager: The OSS-Fuzz project's repo manager to be built at.
|
|
build_data: A struct containing project build information.
|
|
Returns:
|
|
0 on successful build or error code on failure.
|
|
"""
|
|
build_repo_manager.checkout_commit(commit)
|
|
return helper.build_fuzzers_impl(project_name=build_data.project_name,
|
|
clean=True,
|
|
engine=build_data.engine,
|
|
sanitizer=build_data.sanitizer,
|
|
architecture=build_data.architecture,
|
|
env_to_add=None,
|
|
source_path=build_repo_manager.repo_dir,
|
|
mount_location=os.path.join(
|
|
'/src', build_repo_manager.repo_name))
|
|
|
|
|
|
def detect_main_repo(project_name, repo_name=None, commit=None):
|
|
"""Checks a docker image for the main repo of an OSS-Fuzz project.
|
|
|
|
Note: The default is to use the repo name to detect the main repo.
|
|
|
|
Args:
|
|
project_name: The name of the oss-fuzz project.
|
|
repo_name: The name of the main repo in an OSS-Fuzz project.
|
|
commit: A commit SHA that is associated with the main repo.
|
|
src_dir: The location of the projects source on the docker image.
|
|
|
|
Returns:
|
|
The repo's origin, the repo's path.
|
|
"""
|
|
|
|
if not repo_name and not commit:
|
|
logging.error(
|
|
'Error: can not detect main repo without a repo_name or a commit.')
|
|
return None, None
|
|
if repo_name and commit:
|
|
logging.info(
|
|
'Both repo name and commit specific. Using repo name for detection.')
|
|
|
|
# Change to oss-fuzz main directory so helper.py runs correctly.
|
|
utils.chdir_to_root()
|
|
if not helper.build_image_impl(project_name):
|
|
logging.error('Error: building %s image failed.', project_name)
|
|
return None, None
|
|
docker_image_name = 'gcr.io/oss-fuzz/' + project_name
|
|
command_to_run = [
|
|
'docker', 'run', '--rm', '-t', docker_image_name, 'python3',
|
|
os.path.join('/opt', 'cifuzz', 'detect_repo.py')
|
|
]
|
|
if repo_name:
|
|
command_to_run.extend(['--repo_name', repo_name])
|
|
else:
|
|
command_to_run.extend(['--example_commit', commit])
|
|
out, _, _ = utils.execute(command_to_run)
|
|
match = re.search(r'\bDetected repo: ([^ ]+) ([^ ]+)', out.rstrip())
|
|
if match and match.group(1) and match.group(2):
|
|
return match.group(1), match.group(2)
|
|
return None, None
|