|
26 | 26 |
|
27 | 27 | import platform_config |
28 | 28 | import constants |
| 29 | +import re |
| 30 | +import subprocess |
29 | 31 |
|
30 | 32 | SANITIZERS = ['address', 'memory', 'undefined', 'coverage'] |
| 33 | +BASE_OS_VERSION_REGEX = re.compile(r'\s*base_os_version\s*:\s*([^\s]+)') |
31 | 34 |
|
32 | 35 | # TODO(metzman): Set these on config objects so there's one source of truth. |
33 | 36 | DEFAULT_ENGINE = 'libfuzzer' |
@@ -196,6 +199,72 @@ def is_coverage(self): |
196 | 199 | generating a coverage report.""" |
197 | 200 | return self.sanitizer == 'coverage' |
198 | 201 |
|
| 202 | + @property |
| 203 | + def base_os_version(self): |
| 204 | + """Returns the project's base OS version.""" |
| 205 | + if self.oss_fuzz_project_name: |
| 206 | + # Internal/OSS-Fuzz project. |
| 207 | + project_yaml_path = os.path.join('/opt/oss-fuzz/projects', |
| 208 | + self.oss_fuzz_project_name, |
| 209 | + 'project.yaml') |
| 210 | + else: |
| 211 | + # External project. |
| 212 | + project_yaml_path = os.path.join(self.project_src_path, |
| 213 | + self.build_integration_path, |
| 214 | + 'project.yaml') |
| 215 | + |
| 216 | + if not os.path.exists(project_yaml_path): |
| 217 | + return 'legacy' |
| 218 | + |
| 219 | + with open(project_yaml_path) as file_handle: |
| 220 | + content = file_handle.read() |
| 221 | + for line in content.splitlines(): |
| 222 | + match = BASE_OS_VERSION_REGEX.match(line) |
| 223 | + if match: |
| 224 | + return match.group(1).strip('\'"') |
| 225 | + |
| 226 | + return 'legacy' |
| 227 | + |
| 228 | + |
| 229 | +def pivot_to_ubuntu_24_04(image_suffix, script_path, check_result=True): |
| 230 | + """Pivots execution to an Ubuntu 24.04 container if needed.""" |
| 231 | + with open('/etc/os-release') as file_handle: |
| 232 | + if '24.04' not in file_handle.read(): |
| 233 | + logging.info( |
| 234 | + 'Base OS version is Ubuntu 24.04, but running in a different OS. Pivoting to Ubuntu 24.04 container.' |
| 235 | + ) |
| 236 | + env = os.environ.copy() |
| 237 | + # Ensure we don't loop indefinitely. |
| 238 | + env['CIFUZZ_PIVOTED'] = '1' |
| 239 | + command = [ |
| 240 | + 'docker', 'run', '--rm', '--privileged', '--volumes-from', |
| 241 | + os.environ.get('HOSTNAME', ''), '-e', 'CIFUZZ_PIVOTED=1' |
| 242 | + ] |
| 243 | + # Propagate environment variables. |
| 244 | + for key, value in os.environ.items(): |
| 245 | + command.extend(['-e', f'{key}={value}']) |
| 246 | + |
| 247 | + # Use the ubuntu-24-04 version of the image. |
| 248 | + command.append('--entrypoint') |
| 249 | + command.append('python3') |
| 250 | + command.append( |
| 251 | + f'gcr.io/oss-fuzz-base/clusterfuzzlite-{image_suffix}:ubuntu-24-04-v1' |
| 252 | + ) |
| 253 | + |
| 254 | + # Run the same command. |
| 255 | + command.append(script_path) |
| 256 | + |
| 257 | + if check_result: |
| 258 | + subprocess.check_call(command) |
| 259 | + return 0 |
| 260 | + else: |
| 261 | + try: |
| 262 | + subprocess.check_call(command) |
| 263 | + except subprocess.CalledProcessError as e: |
| 264 | + return e.returncode |
| 265 | + return 0 |
| 266 | + return None |
| 267 | + |
199 | 268 |
|
200 | 269 | def _get_platform_config(cfl_platform): |
201 | 270 | """Returns the CI environment object for |cfl_platform|.""" |
|
0 commit comments