[gbinder] Expose transaction code macros, add binder error status codes. JB#61891

Useful for implementation of DUMP and other internal transactions (except
for the silly ones). Also define proper status codes and translate the
existing ones as the current GBINDER_STATUS_FAILED is not recognized.
This commit is contained in:
Andrew Branson
2024-04-05 12:06:29 +02:00
parent 29718f921f
commit 5e8e7df60d
7 changed files with 81 additions and 34 deletions

View File

@@ -167,14 +167,47 @@ GBinderLocalReply*
#define GBINDER_TX_FLAG_ONEWAY (0x01)
/* Other possible errors added from system/core/libutils/include/utils/Errors.h
* Legacy GBINDER_STATUS values preserved, but translated over the wire.
*/
typedef enum gbinder_status {
GBINDER_STATUS_OK = 0,
GBINDER_STATUS_FAILED,
GBINDER_STATUS_DEAD_OBJECT
GBINDER_STATUS_FAILED, /* maps to UNKNOWN_ERROR */
GBINDER_STATUS_DEAD_OBJECT,
GBINDER_STATUS_UNKNOWN_ERROR = (-2147483647-1), // INT32_MIN
GBINDER_STATUS_NO_MEMORY = -ENOMEM,
GBINDER_STATUS_INVALID_OPERATION = -ENOSYS,
GBINDER_STATUS_BAD_VALUE = -EINVAL,
GBINDER_STATUS_BAD_TYPE = (GBINDER_STATUS_UNKNOWN_ERROR + 1),
GBINDER_STATUS_NAME_NOT_FOUND = -ENOENT,
GBINDER_STATUS_PERMISSION_DENIED = -EPERM,
GBINDER_STATUS_NO_INIT = -ENODEV,
GBINDER_STATUS_ALREADY_EXISTS = -EEXIST,
GBINDER_STATUS_FAILED_TRANSACTION = (GBINDER_STATUS_UNKNOWN_ERROR + 2),
#if !defined(_WIN32)
GBINDER_STATUS_BAD_INDEX = -EOVERFLOW,
GBINDER_STATUS_NOT_ENOUGH_DATA = -ENODATA,
GBINDER_STATUS_WOULD_BLOCK = -EWOULDBLOCK,
GBINDER_STATUS_TIMED_OUT = -ETIMEDOUT,
GBINDER_STATUS_UNKNOWN_TRANSACTION = -EBADMSG,
#else
GBINDER_STATUS_BAD_INDEX = -E2BIG,
GBINDER_STATUS_NOT_ENOUGH_DATA = (GBINDER_STATUS_UNKNOWN_ERROR + 3),
GBINDER_STATUS_WOULD_BLOCK = (GBINDER_STATUS_UNKNOWN_ERROR + 4),
GBINDER_STATUS_TIMED_OUT = (GBINDER_STATUS_UNKNOWN_ERROR + 5),
GBINDER_STATUS_UNKNOWN_TRANSACTION = (GBINDER_STATUS_UNKNOWN_ERROR + 6),
#endif
GBINDER_STATUS_FDS_NOT_ALLOWED = (GBINDER_STATUS_UNKNOWN_ERROR + 7),
GBINDER_STATUS_UNEXPECTED_NULL = (GBINDER_STATUS_UNKNOWN_ERROR + 8),
} GBINDER_STATUS;
/* Utility macros for generating internal binder transaction codes
* such as DUMP and INTERFACE
*/
#define GBINDER_FOURCC(c1,c2,c3,c4) \
(((c1) << 24) | ((c2) << 16) | ((c3) << 8) | (c4))
#define GBINDER_AIDL_TRANSACTION(c2,c3,c4) GBINDER_FOURCC('_',c2,c3,c4)
#define GBINDER_HIDL_TRANSACTION(c2,c3,c4) GBINDER_FOURCC(0x0f,c2,c3,c4)
#define GBINDER_FIRST_CALL_TRANSACTION (0x00000001)

View File

@@ -454,10 +454,23 @@ gbinder_driver_reply_status(
memcpy(buf, code, sizeof(*code));
ptr += sizeof(*code);
/* Translate legacy gbinder_status codes to recognizable values */
gint32 mapped_status;
switch (status) {
case GBINDER_STATUS_FAILED:
mapped_status = GBINDER_STATUS_UNKNOWN_ERROR;
break;
case GBINDER_STATUS_DEAD_OBJECT:
mapped_status = -EPIPE;
break;
default:
mapped_status = status;
break;
}
/* Data */
ptr += io->encode_status_reply(ptr, &status);
ptr += io->encode_status_reply(ptr, &mapped_status);
GVERBOSE("< BC_REPLY (%d)", status);
GVERBOSE("< BC_REPLY (%d)", mapped_status);
memset(&write, 0, sizeof(write));
write.ptr = (uintptr_t)buf;
write.size = ptr - buf;
@@ -835,15 +848,19 @@ gbinder_driver_txstatus(
*/
switch (tx.status) {
case (-EAGAIN):
case GBINDER_STATUS_FAILED:
case GBINDER_STATUS_DEAD_OBJECT:
txstatus = (-EFAULT);
GWARN("Replacing tx status %d with %d", tx.status, txstatus);
case GBINDER_STATUS_UNKNOWN_ERROR:
txstatus = GBINDER_STATUS_FAILED;
break;
case -EPIPE:
txstatus = GBINDER_STATUS_DEAD_OBJECT;
break;
default:
txstatus = tx.status;
break;
}
if (txstatus != tx.status) {
GWARN("Replacing tx status %d with %d", tx.status, txstatus);
}
} else {
gbinder_driver_handle_command(self, context, cmd, data);
}

View File

@@ -109,7 +109,7 @@ gbinder_rpc_protocol_aidl_read_rpc_header(
guint32 txcode,
char** iface)
{
if (txcode > GBINDER_TRANSACTION(0,0,0)) {
if (txcode > GBINDER_AIDL_TRANSACTION(0,0,0)) {
/* Internal transaction e.g. GBINDER_DUMP_TRANSACTION etc. */
*iface = NULL;
} else if (gbinder_reader_read_int32(reader, NULL)) {
@@ -156,7 +156,7 @@ gbinder_rpc_protocol_aidl2_read_rpc_header(
guint32 txcode,
char** iface)
{
if (txcode > GBINDER_TRANSACTION(0,0,0)) {
if (txcode > GBINDER_AIDL_TRANSACTION(0,0,0)) {
/* Internal transaction e.g. GBINDER_DUMP_TRANSACTION etc. */
*iface = NULL;
} else if (gbinder_reader_read_int32(reader, NULL) /* flags */ &&
@@ -199,7 +199,7 @@ gbinder_rpc_protocol_aidl3_read_rpc_header(
guint32 txcode,
char** iface)
{
if (txcode > GBINDER_TRANSACTION(0,0,0)) {
if (txcode > GBINDER_AIDL_TRANSACTION(0,0,0)) {
*iface = NULL;
} else if (gbinder_reader_read_int32(reader, NULL) /* flags */ &&
gbinder_reader_read_int32(reader, NULL) /* work source */ &&

View File

@@ -54,25 +54,24 @@ typedef struct gbinder_ipc_sync_api GBinderIpcSyncApi;
#define GBINDER_INTERNAL G_GNUC_INTERNAL
#define GBINDER_DESTRUCTOR __attribute__((destructor))
#define GBINDER_TRANSACTION(c2,c3,c4) GBINDER_FOURCC('_',c2,c3,c4)
#define GBINDER_PING_TRANSACTION GBINDER_TRANSACTION('P','N','G')
#define GBINDER_DUMP_TRANSACTION GBINDER_TRANSACTION('D','M','P')
#define GBINDER_SHELL_COMMAND_TRANSACTION GBINDER_TRANSACTION('C','M','D')
#define GBINDER_INTERFACE_TRANSACTION GBINDER_TRANSACTION('N','T','F')
#define GBINDER_SYSPROPS_TRANSACTION GBINDER_TRANSACTION('S','P','R')
/* Internal transactions from frameworks/native/libs/binder/include/binder/IBinder.h */
#define GBINDER_PING_TRANSACTION GBINDER_AIDL_TRANSACTION('P','N','G')
#define GBINDER_DUMP_TRANSACTION GBINDER_AIDL_TRANSACTION('D','M','P')
#define GBINDER_SHELL_COMMAND_TRANSACTION GBINDER_AIDL_TRANSACTION('C','M','D')
#define GBINDER_INTERFACE_TRANSACTION GBINDER_AIDL_TRANSACTION('N','T','F')
#define GBINDER_SYSPROPS_TRANSACTION GBINDER_AIDL_TRANSACTION('S','P','R')
/* platform/system/tools/hidl/Interface.cpp */
#define HIDL_FOURCC(c2,c3,c4) GBINDER_FOURCC(0x0f,c2,c3,c4)
#define HIDL_PING_TRANSACTION HIDL_FOURCC('P','N','G')
#define HIDL_DESCRIPTOR_CHAIN_TRANSACTION HIDL_FOURCC('C','H','N')
#define HIDL_GET_DESCRIPTOR_TRANSACTION HIDL_FOURCC('D','S','C')
#define HIDL_SYSPROPS_CHANGED_TRANSACTION HIDL_FOURCC('S','Y','S')
#define HIDL_LINK_TO_DEATH_TRANSACTION HIDL_FOURCC('L','T','D')
#define HIDL_UNLINK_TO_DEATH_TRANSACTION HIDL_FOURCC('U','T','D')
#define HIDL_SET_HAL_INSTRUMENTATION_TRANSACTION HIDL_FOURCC('I','N','T')
#define HIDL_GET_REF_INFO_TRANSACTION HIDL_FOURCC('R','E','F')
#define HIDL_DEBUG_TRANSACTION HIDL_FOURCC('D','B','G')
#define HIDL_HASH_CHAIN_TRANSACTION HIDL_FOURCC('H','S','H')
#define HIDL_PING_TRANSACTION GBINDER_HIDL_TRANSACTION('P','N','G')
#define HIDL_DESCRIPTOR_CHAIN_TRANSACTION GBINDER_HIDL_TRANSACTION('C','H','N')
#define HIDL_GET_DESCRIPTOR_TRANSACTION GBINDER_HIDL_TRANSACTION('D','S','C')
#define HIDL_SYSPROPS_CHANGED_TRANSACTION GBINDER_HIDL_TRANSACTION('S','Y','S')
#define HIDL_LINK_TO_DEATH_TRANSACTION GBINDER_HIDL_TRANSACTION('L','T','D')
#define HIDL_UNLINK_TO_DEATH_TRANSACTION GBINDER_HIDL_TRANSACTION('U','T','D')
#define HIDL_SET_HAL_INSTRUMENTATION_TRANSACTION GBINDER_HIDL_TRANSACTION('I','N','T')
#define HIDL_GET_REF_INFO_TRANSACTION GBINDER_HIDL_TRANSACTION('R','E','F')
#define HIDL_DEBUG_TRANSACTION GBINDER_HIDL_TRANSACTION('D','B','G')
#define HIDL_HASH_CHAIN_TRANSACTION GBINDER_HIDL_TRANSACTION('H','S','H')
/* As a special case, ServiceManager's handle is zero */
#define GBINDER_SERVICEMANAGER_HANDLE (0)

View File

@@ -44,8 +44,7 @@
#define DEFAULT_DEVICE GBINDER_DEFAULT_BINDER
#define GBINDER_TRANSACTION(c2,c3,c4) GBINDER_FOURCC('_',c2,c3,c4)
#define GBINDER_INTERFACE_TRANSACTION GBINDER_TRANSACTION('N','T','F')
#define GBINDER_INTERFACE_TRANSACTION GBINDER_AIDL_TRANSACTION('N','T','F')
static const char pname[] = "binder-call";

View File

@@ -43,8 +43,7 @@
#define DEV_DEFAULT GBINDER_DEFAULT_BINDER
#define GBINDER_TRANSACTION(c2,c3,c4) GBINDER_FOURCC('_',c2,c3,c4)
#define GBINDER_DUMP_TRANSACTION GBINDER_TRANSACTION('D','M','P')
#define GBINDER_DUMP_TRANSACTION GBINDER_AIDL_TRANSACTION('D','M','P')
typedef struct app_options {
char* dev;

View File

@@ -346,7 +346,7 @@ test_sync_reply_error(
g_assert(!gbinder_ipc_sync_main.sync_reply(ipc,handle,code,req,&status));
g_assert_cmpint(status, == ,expected_status);
/* GBINDER_STATUS_FAILED gets replaced with -EFAULT */
/* Should return GBINDER_STATUS_FAILED */
test_binder_ignore_dead_object(fd);
test_binder_br_noop(fd, TX_THREAD);
test_binder_br_transaction_complete(fd, TX_THREAD);
@@ -354,7 +354,7 @@ test_sync_reply_error(
test_binder_br_reply_status(fd, TX_THREAD, unexpected_status);
g_assert(!gbinder_ipc_sync_main.sync_reply(ipc,handle,code,req,&status));
g_assert_cmpint(status, == ,-EFAULT);
g_assert_cmpint(status, == , GBINDER_STATUS_FAILED);
gbinder_local_request_unref(req);
gbinder_ipc_unref(ipc);