Skip to content

Bug: INVALID_HANDLE - Enforce exception on error and handle == unknown state #303

@Ulrond

Description

@Ulrond

Problem/Opportunity

Discussed in #302

Originally posted by akhilbhas December 16, 2025
In Binder when ever there is exception, the out param data is not parceled or read from the parcel. This causes the out param to have values which is not expected from behavior as in provided in the specification.
Below is one of the example:

/**
     * Allocates a memory buffer from a given buffer pool.
     * 
     * The allocation will be satisfied immediately or fail if a memory buffer of the given size is not available.
     * The output handle is valid when the returned result is >= 0.
     * The handle must eventually be used in a call to `free()` to release the memory block.
     * 
     * If the allocation fails due to an out of memory condition then `binder::Status EX_SERVICE_SPECIFIC` with `HALError::OUT_OF_MEMORY`
     * is returned and the client can call `notifyWhenSpaceAvailable()` to be notified when space becomes available.
     *
     * @param[in] poolHandle    Pool handle.
     * @param[in] size          Size of the memory block allocation in bytes. Must be > 0.
     *
     * @returns long            The handle of the new buffer allocation.
     * @retval INVALID_HANDLE   The pool handle is invalid or the size is > the pool size.
     *
     * @exception binder::Status::Exception::EX_NONE for success
     * @exception binder::Status::Exception::EX_SERVICE_SPECIFIC, HALError::OUT_OF_MEMORY
     * 
     * @pre A pool handle must have been obtained from `createVideoPool()` or `createAudioPool()`.
     * 
     * @see free(), createVideoPool(), createAudioPool(), notifyWhenSpaceAvailable()
     */
    long alloc(in Pool poolHandle, in int size);

In the above case, we expect INVALID_HANDLE as output when the input is invalid. The HAL service will throw exception EX_SERVICE_SEPCIFIC and set the output param to INVALID. But the output param is not parceled hence the validation fails in VTS

We need to have clarification regarding the same in AIDL Documentation

Steps to reproduce

No response

Expected Behavior

Exception error returned for all cases.

INVALID_HANDLE is not set to the handle, and the handle is an unknown / untrusted value and should not be used.

INVALID_HANDLE should be removed from the documentation.

Actual Behavior

ok this was to cater for an edge case where, the transaction succeeded without error but there was still an invalid handle.

// Variables to hold the result
long bufferHandle = -1;
ndk::ScopedAStatus status = service->allocate(poolHandle, size, &bufferHandle);



if (!status.isOk()) {
    // Check if it's the Service Specific Exception (OUT_OF_MEMORY)
    if (status.getExceptionCode() == EX_SERVICE_SPECIFIC) {
        int32_t errorCode = status.getServiceSpecificError();
        if (errorCode == HALError::OUT_OF_MEMORY) {
            // Handle OOM: Wait for space or notify user
            service->notifyWhenSpaceAvailable();
        }
    } else {
        // Handle other binder-level transport errors
    }
} else {
    // Status is OK, but we must still check the return value for INVALID_HANDLE
    if (bufferHandle < 0) { 
        // Handle Invalid Handle logic (returned result < 0)
    } else {
        // Success! Use the handle
    }
}

But in retro spec, this makes is more difficult to challenge, and you need to also validate the handle in all cases... So let's change the behaviour and remove INVALID_HANDLE from all interfaces.

The new behaviour is that if the transaction is a success then the handle is valid, if the transition fails, then the handle is an unknown value and must be treated as such..

Notes (Optional)

No response

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

Projects

Status

Architecture Review Required

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions