[GH-ISSUE #6567] [Bug] push-adb-file reports an existing directory as the pushed file destination #3956

Closed
opened 2026-10-31 00:45:34 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @coygeek on GitHub (Oct 23, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/6567

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Evidence, artifacts, or reconstruction

Observed behavior

Source-only finding; no runtime reproduction was run. When device_path names an existing writable directory and overwrite:true, push_adb_file accepts the directory, lets ADB copy the file into it, then hashes and reports the directory path instead of the actual child file. The directory hash failure becomes success with device_sha256:null, device_digest_source:"unavailable", and overwritten:true, even when the copied child file was newly created.

Reproduction

Concrete supported request, not executed: with a connected device, local regular file /tmp/rea-example/payload.bin, existing writable device directory /data/local/tmp/rea-example, and no payload.bin child there, call push_adb_file with {"serial":"emulator-5554","local_path":"/tmp/rea-example/payload.bin","device_path":"/data/local/tmp/rea-example","overwrite":true}. Assume ordinary successful transfer and no cancellation.

The public schema admits this absolute destination and overwrite value. The existence probe uses only test -e, so an existing directory is a successful present target. The provider permits that result when overwrite is true. No later guard establishes that the destination is a file.

Expected behavior

The single-file transfer contract and returned file receipt should identify the actual delivered file and hash that file when device hashing is available. If directory destinations are unsupported, refuse them before transfer; if supported, resolve and report the actual child path and its actual replacement status.

Impact and scope

P2: callers receive successful transfer Evidence with the wrong file location, no device verification despite available sha256sum, and a false overwrite claim for a newly created child. The transfer itself can succeed and the bytes remain on the device at /data/local/tmp/rea-example/payload.bin. This affects existing directory destinations with explicit overwrite; ordinary explicit file destinations are outside this finding. Supplying the full intended child-file path avoids the misprojection by source inspection; this workaround was not run.

REA version

Current main 6bb4f4bf7d64e5d2f47479d46225a5383b57cdad. The same existence-only admission, original-path receipt, and hash-failure-to-success logic is present in tag rea-agents-6.7.0 at 27dc42d10249f0410904a75c0997842eb03b931c; the release was not executed for this finding.

Runtime and platform

NOT_ENOUGH_INFO: no real ADB/device or CLI/MCP transfer was run. This is a source-derived host-independent path/result defect. The external ADB semantics are established from pinned AOSP source.

Target and artifact context

One ordinary local regular file and an existing writable device directory whose same-name child does not yet exist. No target execution, permission bypass, connection failure, concurrent change, or capture overflow is required.

Interface

MCP

Earliest failure stage

Transport or result projection

Relevant output or evidence

Typed outcome or recovery expected

Either an explicit unsupported-directory result before mutation or a successful file receipt for /data/local/tmp/rea-example/payload.bin, with overwritten:false for the stated absent-child case and the digest check applied to that file.

Analysis or suspected cause

The provider uses existence of the caller's destination as both file replacement evidence and final file identity. ADB applies directory-destination semantics later, but the receipt continues to use the original path. The successful ADB output is not used to resolve that changed destination.

Additional context

Open and closed searches for "push_adb_file" "directory" and "push-adb-file" "destination" found related reports but no duplicate. #4574 concerns an ambiguous failed existence probe without overwrite; this case uses a clean successful probe and explicit overwrite. #5924 concerns checksum-source attribution, and #3369 concerns capture overflow. A proposed restoration check is the stated existing-directory/absent-child trigger, checking actual destination, replacement status, and digest behavior together; it was not run.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: A valid admitted request follows ordinary ADB directory semantics but produces successful Evidence identifying the directory as a file and falsely claiming an overwrite, with device verification lost.
  • Workaround status: available
  • Workaround basis: Source inspection establishes that giving the full intended child-file path avoids ADB's directory redirection and aligns the existing receipt and digest path; no device execution of the workaround was performed.
Originally created by @coygeek on GitHub (Oct 23, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/6567 ### Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area Evidence, artifacts, or reconstruction ### Observed behavior Source-only finding; no runtime reproduction was run. When `device_path` names an existing writable directory and `overwrite:true`, `push_adb_file` accepts the directory, lets ADB copy the file into it, then hashes and reports the directory path instead of the actual child file. The directory hash failure becomes success with `device_sha256:null`, `device_digest_source:"unavailable"`, and `overwritten:true`, even when the copied child file was newly created. ### Reproduction Concrete supported request, not executed: with a connected device, local regular file `/tmp/rea-example/payload.bin`, existing writable device directory `/data/local/tmp/rea-example`, and no `payload.bin` child there, call `push_adb_file` with `{"serial":"emulator-5554","local_path":"/tmp/rea-example/payload.bin","device_path":"/data/local/tmp/rea-example","overwrite":true}`. Assume ordinary successful transfer and no cancellation. The [public schema admits this absolute destination and overwrite value](https://github.com/morluto/rea/blob/6bb4f4bf7d64e5d2f47479d46225a5383b57cdad/src/domain/adb/adbDeviceAnalysis.ts#L176-L192). The [existence probe uses only test -e](https://github.com/morluto/rea/blob/6bb4f4bf7d64e5d2f47479d46225a5383b57cdad/src/adb/AdbCommand.ts#L279-L295), so an existing directory is a successful present target. The [provider permits that result when overwrite is true](https://github.com/morluto/rea/blob/6bb4f4bf7d64e5d2f47479d46225a5383b57cdad/src/adb/AdbProvider.ts#L2425-L2453). No later guard establishes that the destination is a file. ### Expected behavior The [single-file transfer contract](https://github.com/morluto/rea/blob/6bb4f4bf7d64e5d2f47479d46225a5383b57cdad/src/contracts/adb/adbToolContracts.ts#L126-L133) and returned file receipt should identify the actual delivered file and hash that file when device hashing is available. If directory destinations are unsupported, refuse them before transfer; if supported, resolve and report the actual child path and its actual replacement status. ### Impact and scope P2: callers receive successful transfer Evidence with the wrong file location, no device verification despite available `sha256sum`, and a false overwrite claim for a newly created child. The transfer itself can succeed and the bytes remain on the device at `/data/local/tmp/rea-example/payload.bin`. This affects existing directory destinations with explicit overwrite; ordinary explicit file destinations are outside this finding. Supplying the full intended child-file path avoids the misprojection by source inspection; this workaround was not run. ### REA version Current main `6bb4f4bf7d64e5d2f47479d46225a5383b57cdad`. The same existence-only admission, original-path receipt, and hash-failure-to-success logic is present in tag `rea-agents-6.7.0` at `27dc42d10249f0410904a75c0997842eb03b931c`; the release was not executed for this finding. ### Runtime and platform NOT_ENOUGH_INFO: no real ADB/device or CLI/MCP transfer was run. This is a source-derived host-independent path/result defect. The external ADB semantics are established from pinned AOSP source. ### Target and artifact context One ordinary local regular file and an existing writable device directory whose same-name child does not yet exist. No target execution, permission bypass, connection failure, concurrent change, or capture overflow is required. ### Interface MCP ### Earliest failure stage Transport or result projection ### Relevant output or evidence - Expected source: the REA single-file contract above and AOSP's [existing-directory detection](https://android.googlesource.com/platform/packages/modules/adb/+/a877adddefdf011bfb5d4045919c6df3d3727ed3/client/file_sync_client.cpp#1458) and [appending of the source basename to a directory destination](https://android.googlesource.com/platform/packages/modules/adb/+/a877adddefdf011bfb5d4045919c6df3d3727ed3/client/file_sync_client.cpp#1523). - Failure source: the [snapshot preserves the source basename](https://github.com/morluto/rea/blob/6bb4f4bf7d64e5d2f47479d46225a5383b57cdad/src/adb/AdbInputSnapshot.ts#L60-L76); [the result copies input.device_path and existence into the file receipt](https://github.com/morluto/rea/blob/6bb4f4bf7d64e5d2f47479d46225a5383b57cdad/src/adb/AdbProvider.ts#L2463-L2475); [the digest command addresses that original directory and non-cancellation failures return success](https://github.com/morluto/rea/blob/6bb4f4bf7d64e5d2f47479d46225a5383b57cdad/src/adb/AdbProvider.ts#L2487-L2521). - Evidence provenance: static. - Local verification: static-proof; runtime reproduction was not run. - Reproduction completeness: complete source-derived trigger with request admission, directory existence, ADB destination resolution, and public receipt projection established. - Release scope: [6.7.0 has the same path and existence projection](https://github.com/morluto/rea/blob/27dc42d10249f0410904a75c0997842eb03b931c/src/adb/AdbProvider.ts#L2407-L2473). ### Typed outcome or recovery expected Either an explicit unsupported-directory result before mutation or a successful file receipt for `/data/local/tmp/rea-example/payload.bin`, with `overwritten:false` for the stated absent-child case and the digest check applied to that file. ### Analysis or suspected cause The provider uses existence of the caller's destination as both file replacement evidence and final file identity. ADB applies directory-destination semantics later, but the receipt continues to use the original path. The successful ADB output is not used to resolve that changed destination. ### Additional context Open and closed searches for `"push_adb_file" "directory"` and `"push-adb-file" "destination"` found related reports but no duplicate. [#4574](https://github.com/morluto/rea/issues/4574) concerns an ambiguous failed existence probe without overwrite; this case uses a clean successful probe and explicit overwrite. [#5924](https://github.com/morluto/rea/issues/5924) concerns checksum-source attribution, and [#3369](https://github.com/morluto/rea/issues/3369) concerns capture overflow. A proposed restoration check is the stated existing-directory/absent-child trigger, checking actual destination, replacement status, and digest behavior together; it was not run. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: A valid admitted request follows ordinary ADB directory semantics but produces successful Evidence identifying the directory as a file and falsely claiming an overwrite, with device verification lost. - Workaround status: available - Workaround basis: Source inspection establishes that giving the full intended child-file path avoids ADB's directory redirection and aligns the existing receipt and digest path; no device execution of the workaround was performed.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#3956
No description provided.