Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
3facd87
Added initial apk poc integration
fernandofloresg Apr 27, 2026
7403fc1
Modified engine to execute apks with different names
fernandofloresg Apr 30, 2026
6c82b62
Merge remote-tracking branch 'origin/master' into enhancement/5057602…
fernandofloresg Jun 11, 2026
b355352
Fix Android engine fuzzers permission denied by running adb root at i…
fernandofloresg Jun 19, 2026
e311369
Skip USB operations and reset on Android emulators to prevent lsusb w…
fernandofloresg Jun 19, 2026
3cb7ef7
Return early from download_trusty_symbols_if_needed if the device is …
fernandofloresg Jun 19, 2026
07d6bbb
Refactor Android APK runner to support standard v2 (base APK + dynami…
fernandofloresg Jun 22, 2026
2ee4899
Refactor Android APK runner to support standard v2 (base APK + dynami…
fernandofloresg Jun 22, 2026
d867083
Fix base_apk_path lookup in Android runner to search recursively
fernandofloresg Jun 22, 2026
e4dbe01
Fix base_apk_path lookup in Android runner to search recursively
fernandofloresg Jun 22, 2026
0a35af4
Adds support for --no-streaming flag in Android ASan jobs (#5332)
IvanBM18 Jun 18, 2026
e8a3902
Optimize Android emulator runs by inverting backwards fastboot checks…
fernandofloresg Jun 23, 2026
b79ba62
Optimize Android emulator runs by inverting backwards fastboot checks…
fernandofloresg Jun 23, 2026
fe46306
Skip Region Load Checking in `is_remote_task` (#5331)
javanlacerda Jun 19, 2026
8e2828f
Migrate Android Build API usage to V4 OnePlatform under feature flag
hunsche Jun 16, 2026
e6cd75c
refactor: reformat logging calls and add V4 API migration guide
hunsche Jun 16, 2026
d971f33
Format, add todo, fix lint
dylanjew Jun 23, 2026
1ac8e82
Merge remote-tracking branch 'origin/dev' into enhancement/505760246/…
fernandofloresg Jun 26, 2026
34ed1ed
Support dynamic fuzzer-specific APK lookups ({fuzzer_name}-debug.apk)…
fernandofloresg Jun 26, 2026
4e6f900
Simplify Android runner selection to use standard AndroidApkLibFuzzer…
fernandofloresg Jun 26, 2026
4004302
Fix Android APK runner selection by dynamically resolving fuzzer-spec…
fernandofloresg Jun 26, 2026
29d31bc
Add FORCE_FUZZ_TARGET environment override support to fuzz_task.py to…
fernandofloresg Jun 26, 2026
0cbc784
Revert FORCE_FUZZ_TARGET developer override in fuzz_task.py to keep p…
fernandofloresg Jun 26, 2026
c6bcf3f
Log fuzzer run output and logcat in libfuzzer.py to make full executi…
fernandofloresg Jun 26, 2026
aaac306
Implement native fuzzer stdout capture using StdoutFile redirection a…
fernandofloresg Jun 26, 2026
a4bd4c7
Add dedicated logs.info for fuzzer native C++ stdout in libfuzzer.py
fernandofloresg Jun 26, 2026
a756d63
Change device stdout redirect file path to the root of the app's priv…
fernandofloresg Jun 26, 2026
74feaa1
Pre-create app cache directory and set wide permissions on device bef…
fernandofloresg Jun 26, 2026
e3e5508
Remove root=True to avoid su root compatibility errors on emulator, a…
fernandofloresg Jun 26, 2026
faffa2b
Use canonical absolute path /data/user/0/ instead of symlinked /data/…
fernandofloresg Jun 26, 2026
c3a3c7c
Dynamically construct StdoutFile key using resolved runner name to av…
fernandofloresg Jun 27, 2026
cacff4e
Document Remote Swarming Development and Validation Workflow in AGENT…
fernandofloresg Jun 27, 2026
b2565cc
Pass both legacy and dynamic StdoutFile intent keys to ensure compati…
fernandofloresg Jun 27, 2026
238b09a
Implement full Android C++ dependency resolution and execution flow
fernandofloresg Jun 27, 2026
c441487
Add fallback for stripped libraries in Android dependency resolution
fernandofloresg Jun 27, 2026
e6fe8c2
Add NativeUnitTestActivity extra to am instrument command
fernandofloresg Jun 27, 2026
ca8d3d9
Reorder am instrument arguments to put CommandLineFlags at the end
fernandofloresg Jun 27, 2026
6947115
Add debug logging for adb command and output
fernandofloresg Jun 27, 2026
be73cd4
Add NativeTestActivity extras to am instrument command
fernandofloresg Jun 27, 2026
422f0fe
Force ASan wrapper to run via setprop
fernandofloresg Jun 27, 2026
f16a4ea
Add debug prints for wrap.sh path
fernandofloresg Jun 27, 2026
d6420d0
Upgrade wrap.sh path debug prints to deep inspection
fernandofloresg Jun 27, 2026
ea796ef
Add wrap.sh manual extraction workaround
fernandofloresg Jun 27, 2026
c1b98dd
Run wrap.sh manual extraction and setprop as root (su 0)
fernandofloresg Jun 27, 2026
f2e1e21
Use su 0 -c syntax for root commands
fernandofloresg Jun 27, 2026
9c619ea
Implement two-step wrap.sh extraction and correct setprop path
fernandofloresg Jun 27, 2026
906c8cb
Temporarily disable SELinux during wrap.sh setup
fernandofloresg Jun 27, 2026
fb64f24
Add diagnostics and dynamic owner-elevation fallback to wrap.sh setup
fernandofloresg Jun 27, 2026
6ce07aa
Use cp with world-writable source and add mount/write diagnostics
fernandofloresg Jun 27, 2026
ee9d641
Fix Datastore PermissionDenied on uworker by injecting custom binary …
fernandofloresg Jun 27, 2026
46396b7
Implement signed URL download for custom binaries to avoid GCS 403 on…
fernandofloresg Jun 27, 2026
fd93bd8
Bypass incremental-fs write restriction by extracting wrap.sh to /dat…
fernandofloresg Jun 27, 2026
8798020
Extract ASan runtime to /data/local/tmp along with wrap.sh to fix fai…
fernandofloresg Jun 27, 2026
3116ef5
Bypass system symbols download on uworker to avoid 403 Datastore errors
fernandofloresg Jun 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,55 @@ python butler.py format

This will format the changed code in your current branch.
It's possible to get into a state where linting and formatting contradict each other. In this case, STOP, the human will fix it.

## Remote Swarming Development & Validation Workflow

This section outlines the step-by-step cycle for developing, deploying, launching, and verifying changes on remote Swarming bots.

### Step 1: Local Development & Formatting
Make your code changes in your feature branch. Always run formatting and linting locally before committing:
```bash
pipenv run python butler.py format
pipenv run python butler.py lint
```

### Step 2: Push & Deploy to Remote `dev`
For changes to run on remote Swarming bots, they must be committed, merged, and pushed to the remote **`dev`** branch:
1. Commit and push your feature branch:
```bash
git add <modified_files>
git commit -m "Your description"
git push origin <your-feature-branch>
```
2. Merge into `dev` and push:
```bash
git checkout dev
git pull origin dev
git merge <your-feature-branch>
git push origin dev
git checkout <your-feature-branch>
```
3. **⚠️ Crucial Rebuild Wait Time**: After pushing to `dev`, you **MUST wait 25 to 30 minutes** before triggering any Swarming tasks. This gives the remote Google Cloud Storage (GCS) builder enough time to pull your new commit, compile the binaries, and package them into the deployment ZIP bundle (`linux-3.zip`) fetched by the bots.

### Step 3: Preprocess & Launch the Swarming Task
Once the deployment package has finished rebuilding on GCS:
1. Trigger the preprocess pipeline and launch a new Swarming task:
```bash
python3 scratch/preprocess_and_launch.py
```
2. Note the generated **Swarming Task ID** (e.g. `791f445b26114a10`) and the task URL printed in the stdout.

### Step 4: Live Monitoring & Log Retrieval
1. **Live Monitor**: Open `scratch/monitor_swarming_task.py`, update `task_id` with your new Task ID, and run the script to stream the live console output:
```bash
python3 scratch/monitor_swarming_task.py
```
2. **Download High-Resolution Logs**: Once the task terminates:
* Look at the live monitor output to identify the **assigned Bot Name** (e.g. `lin-192-g582`) and the final state (`COMPLETED` or `BOT_DIED`).
* Open `scratch/read_logs.py`, update the `bot_name` and adjust the time filter window (e.g. `timestamp >= "YYYY-MM-DDTHH:MM:SSZ"`), then run:
```bash
pipenv run python scratch/read_logs.py
```
* This downloads all high-resolution Stackdriver bot and logcat streams into `scratch/bot_logs.txt`.
3. **Analyze**: Inspect `scratch/bot_logs.txt` using grep/editors to verify your changes (such as JNI prints or fuzzer loop outputs).

20 changes: 11 additions & 9 deletions src/clusterfuzz/_internal/batch/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,8 @@ def is_remote_task(command: str, job_name: str) -> bool:
"""
try:
_get_specs_from_config(
[remote_task_types.RemoteTask(command, job_name, None)])
[remote_task_types.RemoteTask(command, job_name, None)],
should_check_regions=False)
return True
except ValueError:
return False
Expand Down Expand Up @@ -300,15 +301,15 @@ def _get_config_names(batch_tasks: List[remote_task_types.RemoteTask]):
return config_map


def _get_subconfig(batch_config, instance_spec):
def _get_subconfig(batch_config, instance_spec, should_check_regions=True):
all_subconfigs = batch_config.get('subconfigs', {})
instance_subconfigs = instance_spec['subconfigs']

queue_check_regions = batch_config.get('queue_check_regions')
if not queue_check_regions:
logs.info(
'Skipping batch load check because queue_check_regions is not configured.'
)
if not should_check_regions or not queue_check_regions:
logs.info('Skipping batch load check. '
f'should_check_regions: {should_check_regions}, '
f'queue_check_regions: {queue_check_regions}')
weighted_subconfigs = [
WeightedSubconfig(subconfig['name'], subconfig['weight'])
for subconfig in instance_subconfigs
Expand Down Expand Up @@ -343,8 +344,8 @@ def _get_subconfig(batch_config, instance_spec):
return all_subconfigs[chosen_name]


def _get_specs_from_config(
batch_tasks: List[remote_task_types.RemoteTask]) -> Dict:
def _get_specs_from_config(batch_tasks: List[remote_task_types.RemoteTask],
should_check_regions: bool = True) -> Dict:
"""Gets the configured specifications for a batch workload."""
if not batch_tasks:
return {}
Expand Down Expand Up @@ -382,7 +383,8 @@ def _get_specs_from_config(
# This saves us time and reduces fragementation, e.g. every linux fuzz task
# run in this call will run in the same zone.
if config_name not in subconfig_map:
subconfig = _get_subconfig(batch_config, instance_spec)
subconfig = _get_subconfig(batch_config, instance_spec,
should_check_regions)
subconfig_map[config_name] = subconfig

should_retry = instance_spec.get('retry', False)
Expand Down
4 changes: 3 additions & 1 deletion src/clusterfuzz/_internal/bot/fuzzers/engine_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,9 @@ def find_fuzzer_path(build_directory, fuzzer_name):
for root, _, files in shell.walk(build_directory):
for filename in files:
if (legacy_name_prefix + filename == fuzzer_name or
filename == fuzzer_filename):
filename == fuzzer_filename or
(filename.endswith('.apk') and fuzzer_name in filename) or
filename.endswith('.apk')):
return os.path.join(root, filename)

# This is an expected case when doing regression testing with old builds
Expand Down
Loading
Loading