Skip to content

BufferOverflowException in AdbProtocol.generateOpen with long destination strings #25

@YUNDATAFw

Description

@YUNDATAFw

Acknowledgement

Many thanks to Muntashir Akon and all contributors for continuously maintaining libadb-android—an indispensable bridge for Android developers!

Repository: MuntashirAkon/libadb-android


Summary

The static method io.github.muntashirakon.adb.AdbProtocol.generateOpen under-allocates the ByteBuffer, causing java.nio.BufferOverflowException when the destination string (typically a shell command containing Chinese or other multi-byte characters) exceeds 104 ASCII-equivalent bytes. After the exception the connection becomes unusable.


Stack trace

[异常信息:java.nio.BufferOverflowException: null
at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:164)
at java.nio.ByteBuffer.put(ByteBuffer.java:732)
at io.github.muntashirakon.adb.AdbProtocol.generateOpen(AdbProtocol.java:296)
at io.github.muntashirakon.adb.AdbConnection.open(AdbConnection.java:512)
at io.github.muntashirakon.adb.AbsAdbConnectionManager.openStream(AbsAdbConnectionManager.java:414)
at com.AdbService.AdbToolSingleton.lambda$executeNonInteractive$29$com-AdbService-AdbToolSingleton(AdbToolSingleton.java:464)
at com.AdbService.AdbToolSingleton$$ExternalSyntheticLambda49.run(Unknown Source:8)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
]


Root cause

// inside AdbProtocol.java
ByteBuffer bbuf = ByteBuffer.allocate(destination.length() + 1);

Only len + 1 bytes are reserved, but generateMessage(A_OPEN, ...) prepends a 24-byte header.

Required space = 24 + payload + 1.

Whenever destination.length() >= 104 the write overflows.


Minimal reproduction (verbal)

  1. Add the official library and establish a normal ADB connection.

  2. Build a shell command whose total length exceeds 104 bytes, e.g. copying an APK whose path contains long Chinese file names.

  3. Send the command via AbsAdbConnectionManager.openStream(destination);

    when the byte length of destination is ≥ 104, the internal buffer is too small and BufferOverflowException is thrown immediately.

  4. Disconnect and reconnect, then issue the same-length command again—the problem always reproduces and all subsequent streams fail.


Suggested fix

Allocate the complete buffer in one shot:

ByteBuffer bbuf = ByteBuffer.allocate(24 + destination.length() + 1);
bbuf.put(StringCompat.getBytes(destination, StandardCharsets.UTF_8));
bbuf.put((byte) 0);
bbuf.flip();
return generateMessage(A_OPEN, localId, 0, bbuf.array());

Environment

  • Library version: 3.1.1 and earlier
  • Trigger: destination length ≥ 104 bytes (100 % reproducible)

This bug really affects usability.
I hope you can fix it as soon as possible, thank you. ( ╹▽╹ )

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions