diff --git a/interfaces/innerkits/ipc_core/BUILD.gn b/interfaces/innerkits/ipc_core/BUILD.gn index a4a93351f58cf685ff742bf645a1b8733a20cef8..3560cd7c78cc7a617ecc733a9e298726c1e40dd5 100755 --- a/interfaces/innerkits/ipc_core/BUILD.gn +++ b/interfaces/innerkits/ipc_core/BUILD.gn @@ -59,7 +59,10 @@ ohos_shared_library("ipc_core") { ":libipc_core_private_config", ] public_configs = [ "$SUBSYSTEM_DIR:ipc_util_config" ] - deps = [ "//utils/native/base:utils" ] + deps = [ + "//base/security/access_token/interfaces/innerkits/token_setproc:libtoken_setproc", + "//utils/native/base:utils", + ] external_deps = [ "dsoftbus_standard:softbus_client", diff --git a/interfaces/innerkits/ipc_core/include/ipc_object_stub.h b/interfaces/innerkits/ipc_core/include/ipc_object_stub.h index 71d78e3c8cdeaa1ba7b8b1d0831e7329274f1249..8e922a882c958df9142dafd3114fa54a339b099b 100755 --- a/interfaces/innerkits/ipc_core/include/ipc_object_stub.h +++ b/interfaces/innerkits/ipc_core/include/ipc_object_stub.h @@ -62,6 +62,10 @@ public: int GetCallingUid(); + uint32_t GetCallingTokenID(); + + uint32_t GetFirstTokenID(); + virtual int OnRemoteDump(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); virtual int32_t ProcessProto(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); diff --git a/interfaces/innerkits/ipc_core/include/ipc_skeleton.h b/interfaces/innerkits/ipc_core/include/ipc_skeleton.h index fa59b085d92c8986cb73fb9124fd4d3c58b6c380..4ea3c1a3bf9e224ffc41a3aca95f2e86989612ec 100755 --- a/interfaces/innerkits/ipc_core/include/ipc_skeleton.h +++ b/interfaces/innerkits/ipc_core/include/ipc_skeleton.h @@ -37,6 +37,10 @@ public: static pid_t GetCallingUid(); + static uint32_t GetCallingTokenID(); + + static uint32_t GetFirstTokenID(); + static std::string GetLocalDeviceID(); static std::string GetCallingDeviceID(); diff --git a/interfaces/innerkits/ipc_single/BUILD.gn b/interfaces/innerkits/ipc_single/BUILD.gn index fb126254e93c18f650801efc81a95fb24baad32c..6f93b5053cae5f477e09a8cf45b12b0a9bf975ab 100755 --- a/interfaces/innerkits/ipc_single/BUILD.gn +++ b/interfaces/innerkits/ipc_single/BUILD.gn @@ -54,7 +54,10 @@ ohos_shared_library("ipc_single") { ":libipc_single_private_config", ] public_configs = [ "$SUBSYSTEM_DIR:ipc_util_config" ] - deps = [ "//utils/native/base:utils" ] + deps = [ + "//base/security/access_token/interfaces/innerkits/token_setproc:libtoken_setproc", + "//utils/native/base:utils", + ] external_deps = [ "hitrace_native:libhitrace", diff --git a/ipc/native/src/core/source/ipc_object_stub.cpp b/ipc/native/src/core/source/ipc_object_stub.cpp index 24efaaec1fdf68f88beddc79723d99b7e8c97379..bfd539f29dd501ed9c26d98f30be899addd9441e 100755 --- a/ipc/native/src/core/source/ipc_object_stub.cpp +++ b/ipc/native/src/core/source/ipc_object_stub.cpp @@ -299,6 +299,16 @@ pid_t IPCObjectStub::GetCallingUid() return IPCSkeleton::GetCallingUid(); } +uint32_t IPCObjectStub::GetCallingTokenID() +{ + return IPCSkeleton::GetCallingTokenID(); +} + +uint32_t IPCObjectStub::GetFirstTokenID() +{ + return IPCSkeleton::GetFirstTokenID(); +} + int IPCObjectStub::GetObjectType() const { return OBJECT_TYPE_NATIVE; diff --git a/ipc/native/src/core/source/ipc_skeleton.cpp b/ipc/native/src/core/source/ipc_skeleton.cpp index 66dd3696efdd0f847ffb7a02f96d16a628e7f60f..77ededabfbb7a3bca02363d9401a3a73974fd266 100755 --- a/ipc/native/src/core/source/ipc_skeleton.cpp +++ b/ipc/native/src/core/source/ipc_skeleton.cpp @@ -16,6 +16,7 @@ #include "ipc_skeleton.h" #include "ipc_process_skeleton.h" #include "ipc_thread_skeleton.h" +#include "token_setproc.h" namespace OHOS { #ifdef CONFIG_IPC_SINGLE @@ -84,6 +85,26 @@ pid_t IPCSkeleton::GetCallingUid() return getuid(); } +uint32_t IPCSkeleton::GetCallingTokenID() +{ + IRemoteInvoker *invoker = IPCThreadSkeleton::GetActiveInvoker(); + if (invoker != nullptr) { + return invoker->GetCallerTokenID(); + } + uint64_t token = GetSelfTokenID(); + return (uint32_t)token; +} + +uint32_t IPCSkeleton::GetFirstTokenID() +{ + IRemoteInvoker *invoker = IPCThreadSkeleton::GetActiveInvoker(); + if (invoker != nullptr) { + return invoker->GetFirstTokenID(); + } + uint64_t ftoken = GetFirstCallerTokenID(); + return (uint32_t)ftoken; +} + std::string IPCSkeleton::GetLocalDeviceID() { IRemoteInvoker *invoker = IPCThreadSkeleton::GetActiveInvoker(); diff --git a/ipc/native/src/mock/include/binder_connector.h b/ipc/native/src/mock/include/binder_connector.h index 085a5b6afbf347145aac53270ff550b611b25a31..9dc8a68b1c7b48f3386c3487deafffdf413cccd2 100755 --- a/ipc/native/src/mock/include/binder_connector.h +++ b/ipc/native/src/mock/include/binder_connector.h @@ -33,6 +33,7 @@ public: int WriteBinder(unsigned long request, void *value); void ExitCurrentThread(unsigned long request); bool IsDriverAlive(); + bool IsAccessTokenSupported(); private: static BinderConnector *instance_; static std::mutex skeletonMutex; @@ -40,6 +41,8 @@ private: int driverFD_; void *vmAddr_; const std::string deviceName_; + int32_t version_; + int32_t subVersion_; }; #ifdef CONFIG_IPC_SINGLE } // namespace IPC_SINGLE diff --git a/ipc/native/src/mock/include/binder_invoker.h b/ipc/native/src/mock/include/binder_invoker.h index e2b5c5d9bb556e9c1881083e9a07bb1be1c6a4a7..70f665f55f56bce336919b805e99ffbc23d8ece3 100755 --- a/ipc/native/src/mock/include/binder_invoker.h +++ b/ipc/native/src/mock/include/binder_invoker.h @@ -80,6 +80,10 @@ public: uid_t GetCallerUid() const override; + uint32_t GetCallerTokenID() const override; + + uint32_t GetFirstTokenID() const override; + uint32_t GetStatus() const override; bool IsLocalCalling() override; @@ -111,6 +115,8 @@ protected: bool stopWorkThread; pid_t callerPid_; pid_t callerUid_; + uint32_t callerTokenID_; + uint32_t firstTokenID_; private: int TransactWithDriver(bool doRead = true); diff --git a/ipc/native/src/mock/include/dbinder_base_invoker.h b/ipc/native/src/mock/include/dbinder_base_invoker.h index 1cd8f5ac215f0871978a5ee84e49a4add49bc95c..6b352df082c138e30c1fb2663594d834df94ceeb 100755 --- a/ipc/native/src/mock/include/dbinder_base_invoker.h +++ b/ipc/native/src/mock/include/dbinder_base_invoker.h @@ -343,9 +343,9 @@ template uint64_t DBinderBaseInvoker::GetUniqueSeqNumber(int cmd) return 0; } - if (cmd == BC_TRANSACTION) { + if (cmd == BC_TRANSACTION_V8) { return current->GetSeqNumber(); - } else if (cmd == BC_REPLY) { + } else if (cmd == BC_REPLY_V8) { /* use sender sequence number */ return GetSeqNum(); } else { @@ -679,7 +679,7 @@ int DBinderBaseInvoker::SendRequest(int32_t handle, uint32_t code, MessagePar HiTraceId traceId = HiTrace::GetId(); // set client send trace point if trace is enabled HiTraceId childId = HitraceInvoker::TraceClientSend(handle, code, newData, flags, traceId); - std::shared_ptr session = WriteTransaction(BC_TRANSACTION, flags, handle, 0, code, data, seqNumber, 0); + std::shared_ptr session = WriteTransaction(BC_TRANSACTION_V8, flags, handle, 0, code, data, seqNumber, 0); if (session == nullptr) { newData.RewindWrite(oldWritePosition); DBINDER_BASE_LOGE("seqNumber can not be zero,handle=%d", handle); @@ -724,7 +724,8 @@ template bool DBinderBaseInvoker::SetMaxWorkThread(int maxThreadNum template int DBinderBaseInvoker::SendReply(MessageParcel &reply, uint32_t flags, int32_t result) { uint64_t seqNumber = 0; - std::shared_ptr sessionObject = WriteTransaction(BC_REPLY, flags, 0, GetClientFd(), 0, reply, seqNumber, result); + std::shared_ptr sessionObject = + WriteTransaction(BC_REPLY_V8, flags, 0, GetClientFd(), 0, reply, seqNumber, result); if (seqNumber == 0) { DBINDER_BASE_LOGE("seqNumber can not be zero"); @@ -956,9 +957,9 @@ template void DBinderBaseInvoker::OnTransaction(std::shared_ptrcmd == BC_TRANSACTION) { + if (tr->cmd == BC_TRANSACTION_V8) { ProcessTransaction(tr, listenFd); - } else if (tr->cmd == BC_REPLY) { + } else if (tr->cmd == BC_REPLY_V8) { ProcessReply(tr, listenFd); } return; diff --git a/ipc/native/src/mock/include/dbinder_databus_invoker.h b/ipc/native/src/mock/include/dbinder_databus_invoker.h index e08045a375a688ca5dbdf48d7cac4285342ab97b..1d9ecadcc51f09e614bb8b4501484a62117f0b01 100755 --- a/ipc/native/src/mock/include/dbinder_databus_invoker.h +++ b/ipc/native/src/mock/include/dbinder_databus_invoker.h @@ -46,6 +46,8 @@ public: bool WriteFileDescriptor(Parcel &parcel, int fd, bool takeOwnership) override; pid_t GetCallerPid() const override; uid_t GetCallerUid() const override; + uint32_t GetCallerTokenID() const override; + uint32_t GetFirstTokenID() const override; uint32_t GetStatus() const override; bool IsLocalCalling() override; std::string GetLocalDeviceID() override; @@ -102,6 +104,8 @@ private: pid_t callerPid_; pid_t callerUid_; std::string callerDeviceID_; + uint32_t callerTokenID_; + uint32_t firstTokenID_; uint64_t seqNumber_ = 0; uint32_t clientFd_ = 0; uint32_t status_; diff --git a/ipc/native/src/mock/include/iremote_invoker.h b/ipc/native/src/mock/include/iremote_invoker.h index ba62f420af82016312a37f10e7acb9abcf6d0a41..a3bbf157b3fb498989d74df693177d321ad4cdcf 100755 --- a/ipc/native/src/mock/include/iremote_invoker.h +++ b/ipc/native/src/mock/include/iremote_invoker.h @@ -68,6 +68,10 @@ public: virtual uid_t GetCallerUid() const = 0; + virtual uint32_t GetCallerTokenID() const = 0; + + virtual uint32_t GetFirstTokenID() const = 0; + virtual uint32_t GetStatus() const = 0; virtual bool IsLocalCalling() = 0; diff --git a/ipc/native/src/mock/include/sys_binder.h b/ipc/native/src/mock/include/sys_binder.h index 7bd14c44e0027b19f32f3f105b1eb32fe3189661..e12156a82f9e9055ba727913336bd5bdc412c49e 100755 --- a/ipc/native/src/mock/include/sys_binder.h +++ b/ipc/native/src/mock/include/sys_binder.h @@ -28,6 +28,10 @@ #define B_PACK_CHARS(c1, c2, c3, c4) ((((c1) << 24)) | (((c2) << 16)) | (((c3) << 8)) | (c4)) #endif +#define BINDER_SUB_VERSION_SHIFT_BASE 16 +#define BINDER_VERSION_MASK 0x0000FFFF +#define ACCESS_TOKEN_MASK (1 << 0) + #define B_TYPE_LARGE 0x85 enum { BINDER_TYPE_BINDER = B_PACK_CHARS('s', 'b', '*', B_TYPE_LARGE), @@ -152,15 +156,28 @@ struct binder_transaction_data { } ptr; __u8 buf[8]; } data; + __u64 sender_tokenid; + __u64 first_tokenid; }; -struct binder_transaction_data_secctx { - struct binder_transaction_data transaction_data; - binder_uintptr_t secctx; -}; - -struct binder_transaction_data_sg { - struct binder_transaction_data transaction_data; - binder_size_t buffers_size; +struct binder_transaction_data_v8 { + union { + __u32 handle; + binder_uintptr_t ptr; + } target; + binder_uintptr_t cookie; + __u32 code; + __u32 flags; + pid_t sender_pid; + uid_t sender_euid; + binder_size_t data_size; + binder_size_t offsets_size; + union { + struct { + binder_uintptr_t buffer; + binder_uintptr_t offsets; + } ptr; + __u8 buf[8]; + } data; }; struct binder_ptr_cookie { binder_uintptr_t ptr; @@ -182,9 +199,10 @@ struct binder_pri_ptr_cookie { enum binder_driver_return_protocol { BR_ERROR = _IOR('r', 0, __s32), BR_OK = _IO('r', 1), - BR_TRANSACTION_SEC_CTX = _IOR('r', 2, struct binder_transaction_data_secctx), BR_TRANSACTION = _IOR('r', 2, struct binder_transaction_data), + BR_TRANSACTION_V8 = _IOR('r', 2, struct binder_transaction_data_v8), BR_REPLY = _IOR('r', 3, struct binder_transaction_data), + BR_REPLY_V8 = _IOR('r', 3, struct binder_transaction_data_v8), BR_ACQUIRE_RESULT = _IOR('r', 4, __s32), BR_DEAD_REPLY = _IO('r', 5), BR_TRANSACTION_COMPLETE = _IO('r', 6), @@ -203,7 +221,9 @@ enum binder_driver_return_protocol { }; enum binder_driver_command_protocol { BC_TRANSACTION = _IOW('c', 0, struct binder_transaction_data), + BC_TRANSACTION_V8 = _IOW('c', 0, struct binder_transaction_data_v8), BC_REPLY = _IOW('c', 1, struct binder_transaction_data), + BC_REPLY_V8 = _IOW('c', 1, struct binder_transaction_data_v8), BC_ACQUIRE_RESULT = _IOW('c', 2, __s32), BC_FREE_BUFFER = _IOW('c', 3, binder_uintptr_t), BC_INCREFS = _IOW('c', 4, __u32), @@ -219,8 +239,6 @@ enum binder_driver_command_protocol { BC_REQUEST_DEATH_NOTIFICATION = _IOW('c', 14, struct binder_handle_cookie), BC_CLEAR_DEATH_NOTIFICATION = _IOW('c', 15, struct binder_handle_cookie), BC_DEAD_BINDER_DONE = _IOW('c', 16, binder_uintptr_t), - BC_TRANSACTION_SG = _IOW('c', 17, struct binder_transaction_data_sg), - BC_REPLY_SG = _IOW('c', 18, struct binder_transaction_data_sg), BC_SEND_RAWDATA = _IOW('c', 20, __u32), }; #endif /* * _UAPI_LINUX_BINDER_H * */ diff --git a/ipc/native/src/mock/source/binder_connector.cpp b/ipc/native/src/mock/source/binder_connector.cpp index 14b7df413b1ee0e8900884e03983a607c99ae16a..2b3cec0982bda8e9ee87a9f10a5f8ca5522e542a 100755 --- a/ipc/native/src/mock/source/binder_connector.cpp +++ b/ipc/native/src/mock/source/binder_connector.cpp @@ -26,6 +26,7 @@ #include "ipc_debug.h" #include "dbinder_error_code.h" #include "log_tags.h" +#include "sys_binder.h" namespace OHOS { #ifdef CONFIG_IPC_SINGLE @@ -41,7 +42,7 @@ static const std::string DRIVER_NAME = std::string("/dev/binder"); BinderConnector *BinderConnector::instance_ = nullptr; BinderConnector::BinderConnector(const std::string &deviceName) - : driverFD_(-1), vmAddr_(MAP_FAILED), deviceName_(deviceName) + : driverFD_(-1), vmAddr_(MAP_FAILED), deviceName_(deviceName), version_(0), subVersion_(0) {} BinderConnector::~BinderConnector() @@ -73,7 +74,21 @@ bool BinderConnector::OpenDriver() #endif return false; } - + int32_t version = 0; + int ret = ioctl(fd, BINDER_VERSION, &version); + if (ret != 0) { + ZLOGE(LABEL, "Get Binder version failed: %s", strerror(errno)); + close(fd); + return false; + } + int32_t subVersion = version >> BINDER_SUB_VERSION_SHIFT_BASE; + version = version & BINDER_VERSION_MASK; + if (version != BINDER_CURRENT_PROTOCOL_VERSION) { + ZLOGE(LABEL, "Binder version not match! driver version:%d, ipc version:%d", + version, BINDER_CURRENT_PROTOCOL_VERSION); + close(fd); + return false; + } ZLOGI(LABEL, "%s:succ to open, fd=%d", __func__, fd); driverFD_ = fd; vmAddr_ = mmap(0, IPC_MMAP_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, driverFD_, 0); @@ -87,10 +102,19 @@ bool BinderConnector::OpenDriver() #endif return false; } - + version_ = version; + subVersion_ = subVersion; return true; } +bool BinderConnector::IsAccessTokenSupported() +{ + if (driverFD_ > 0) { + return subVersion_ & ACCESS_TOKEN_MASK; + } + return false; +} + int BinderConnector::WriteBinder(unsigned long request, void *value) { int err = -EINTR; diff --git a/ipc/native/src/mock/source/binder_debug.cpp b/ipc/native/src/mock/source/binder_debug.cpp index b15cb3ddf0fd68269b8ad00cb829a37fc4123f71..1382574e23082baedbf889aa5fb5717146d585b8 100755 --- a/ipc/native/src/mock/source/binder_debug.cpp +++ b/ipc/native/src/mock/source/binder_debug.cpp @@ -28,7 +28,9 @@ ErrorMap &BinderDebug::GetErrorMap() static ErrorMap errorMap = { { BR_ERROR, "BR_ERROR" }, { BR_OK, "BR_OK" }, { BR_TRANSACTION, "BR_TRANSACTION" }, + { BR_TRANSACTION_V8, "BR_TRANSACTION_V8" }, { BR_REPLY, "BR_REPLY" }, + { BR_REPLY_V8, "BR_REPLY_V8" }, { BR_ACQUIRE_RESULT, "BR_ACQUIRE_RESULT" }, { BR_DEAD_REPLY, "BR_DEAD_REPLY" }, { BR_TRANSACTION_COMPLETE, "BR_TRANSACTION_COMPLETE" }, @@ -44,7 +46,9 @@ ErrorMap &BinderDebug::GetErrorMap() { BR_CLEAR_DEATH_NOTIFICATION_DONE, "BR_CLEAR_DEATH_NOTIFICATION_DONE" }, { BR_FAILED_REPLY, "BR_FAILED_REPLY" }, { BC_TRANSACTION, "BC_TRANSACTION" }, + { BC_TRANSACTION_V8, "BC_TRANSACTION_V8" }, { BC_REPLY, "BC_REPLY" }, + { BC_REPLY_V8, "BC_REPLY_V8" }, { BC_ACQUIRE_RESULT, "BC_ACQUIRE_RESULT" }, { BC_FREE_BUFFER, "BC_FREE_BUFFER" }, { BC_INCREFS, "BC_INCREFS" }, diff --git a/ipc/native/src/mock/source/binder_invoker.cpp b/ipc/native/src/mock/source/binder_invoker.cpp index b06c2f736be9667832c1e265a88bf1863e077b25..5f6c9aadb89b09e5c42edf748fc6b8fd7ab928dc 100755 --- a/ipc/native/src/mock/source/binder_invoker.cpp +++ b/ipc/native/src/mock/source/binder_invoker.cpp @@ -25,6 +25,7 @@ #include "hitrace_invoker.h" #include "dbinder_error_code.h" #include "log_tags.h" +#include "token_setproc.h" namespace OHOS { #ifdef CONFIG_IPC_SINGLE @@ -40,8 +41,10 @@ enum { }; BinderInvoker::BinderInvoker() - : isMainWorkThread(false), stopWorkThread(false), callerPid_(getpid()), callerUid_(getuid()), status_(0) + : isMainWorkThread(false), stopWorkThread(false), callerPid_(getpid()), callerUid_(getuid()), + firstTokenID_(-1), status_(0) { + callerTokenID_ = (uint32_t)GetSelfTokenID(); input_.SetDataCapacity(IPC_DEFAULT_PARCEL_SIZE); binderConnector_ = BinderConnector::GetInstance(); } @@ -98,7 +101,8 @@ int BinderInvoker::SendRequest(int handle, uint32_t code, MessageParcel &data, M HiTraceId traceId = HiTrace::GetId(); // set client send trace point if trace is enabled HiTraceId childId = HitraceInvoker::TraceClientSend(handle, code, newData, flags, traceId); - if (!WriteTransaction(BC_TRANSACTION, flags, handle, code, data, nullptr)) { + int cmd = binderConnector_->IsAccessTokenSupported() ? BC_TRANSACTION : BC_TRANSACTION_V8; + if (!WriteTransaction(cmd, flags, handle, code, data, nullptr)) { newData.RewindWrite(oldWritePosition); ZLOGE(LABEL, "WriteTransaction ERROR"); #ifndef BUILD_PUBLIC_VERSION @@ -318,7 +322,8 @@ void BinderInvoker::StartWorkLoop() int BinderInvoker::SendReply(MessageParcel &reply, uint32_t flags, int32_t result) { - int error = WriteTransaction(BC_REPLY, flags, -1, 0, reply, &result); + int cmd = binderConnector_->IsAccessTokenSupported() ? BC_REPLY : BC_REPLY_V8; + int error = WriteTransaction(cmd, flags, -1, 0, reply, &result); if (error < ERR_NONE) { return error; } @@ -415,9 +420,15 @@ void BinderInvoker::OnTransaction(const uint8_t *buffer) int isServerTraced = HitraceInvoker::TraceServerReceieve(tr->target.handle, tr->code, *data, newflags); const pid_t oldPid = callerPid_; const auto oldUid = static_cast(callerUid_); + const uint32_t oldToken = callerTokenID_; + const uint32_t oldFirstToken = firstTokenID_; uint32_t oldStatus = status_; callerPid_ = tr->sender_pid; callerUid_ = tr->sender_euid; + if (binderConnector_->IsAccessTokenSupported()) { + callerTokenID_ = tr->sender_tokenid; + firstTokenID_ = tr->first_tokenid; + } SetStatus(IRemoteInvoker::ACTIVE_INVOKER); int error = ERR_DEAD_OBJECT; sptr targetObject; @@ -443,6 +454,8 @@ void BinderInvoker::OnTransaction(const uint8_t *buffer) } callerPid_ = oldPid; callerUid_ = oldUid; + callerTokenID_ = oldToken; + firstTokenID_ = oldFirstToken; SetStatus(oldStatus); } @@ -481,7 +494,8 @@ void BinderInvoker::OnRemoveRecipientDone() int BinderInvoker::HandleReply(MessageParcel *reply) { - const size_t readSize = sizeof(binder_transaction_data); + const size_t readSize = binderConnector_->IsAccessTokenSupported() ? + sizeof(binder_transaction_data) : sizeof(binder_transaction_data_v8); const uint8_t *buffer = input_.ReadBuffer(readSize); if (buffer == nullptr) { ZLOGE(LABEL, "HandleReply read tr failed"); @@ -548,6 +562,15 @@ int BinderInvoker::HandleCommands(uint32_t cmd) OnTransaction(buffer); break; } + case BR_TRANSACTION_V8: { + const uint8_t *buffer = input_.ReadBuffer(sizeof(binder_transaction_data_v8)); + if (buffer == nullptr) { + error = IPC_INVOKER_INVALID_DATA_ERR; + break; + } + OnTransaction(buffer); + break; + } case BR_SPAWN_LOOPER: { IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent(); if (current != nullptr) { @@ -666,8 +689,8 @@ bool BinderInvoker::WriteTransaction(int cmd, uint32_t flags, int32_t handle, ui ZLOGE(LABEL, "WriteTransaction Command failure"); return false; } - - return output_.WriteBuffer(&tr, sizeof(binder_transaction_data)); + size_t buffSize = (cmd == BC_TRANSACTION) ? sizeof(binder_transaction_data) : sizeof(binder_transaction_data_v8); + return output_.WriteBuffer(&tr, buffSize); } int BinderInvoker::WaitForCompletion(MessageParcel *reply, int32_t *acquireResult) @@ -716,6 +739,15 @@ int BinderInvoker::WaitForCompletion(MessageParcel *reply, int32_t *acquireResul error = ERR_NONE; break; } + case BR_REPLY_V8: { + error = HandleReply(reply); + if (error != IPC_INVOKER_INVALID_REPLY_ERR) { + continueLoop = false; + break; + } + error = ERR_NONE; + break; + } default: { error = HandleCommands(cmd); if (error != ERR_NONE) { @@ -794,6 +826,19 @@ uid_t BinderInvoker::GetCallerUid() const return callerUid_; } +uint32_t BinderInvoker::GetCallerTokenID() const +{ + return callerTokenID_; +} + +uint32_t BinderInvoker::GetFirstTokenID() const +{ + if (firstTokenID_ == -1) { + return (uint32_t)GetFirstCallerTokenID(); + } + return firstTokenID_; +} + uint32_t BinderInvoker::GetStatus() const { return status_; diff --git a/ipc/native/src/mock/source/dbinder_databus_invoker.cpp b/ipc/native/src/mock/source/dbinder_databus_invoker.cpp index 20c0b2871f4a1c4e791c40c48d1915d6356b5d45..4c6b4028ccc3aafbd0c333da13c061d017011f38 100755 --- a/ipc/native/src/mock/source/dbinder_databus_invoker.cpp +++ b/ipc/native/src/mock/source/dbinder_databus_invoker.cpp @@ -41,7 +41,8 @@ static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_RPC, (void)OHOS::HiviewDFX::HiLog::Info(LOG_LABEL, "%{public}s %{public}d: " fmt, TITLE, __LINE__, ##args) DBinderDatabusInvoker::DBinderDatabusInvoker() - : stopWorkThread_(false), callerPid_(getpid()), callerUid_(getuid()), callerDeviceID_(""), status_(0) + : stopWorkThread_(false), callerPid_(getpid()), callerUid_(getuid()), callerDeviceID_(""), + callerTokenID_(0), firstTokenID_(0), status_(0) { DBINDER_LOGI("Create DBinderDatabusInvoker"); } @@ -642,6 +643,16 @@ void DBinderDatabusInvoker::SetCallerUid(pid_t uid) callerUid_ = uid; } +uint32_t DBinderDatabusInvoker::GetCallerTokenID() const +{ + return callerTokenID_; +} + +uint32_t DBinderDatabusInvoker::GetFirstTokenID() const +{ + return firstTokenID_; +} + void DBinderDatabusInvoker::SetCallerDeviceID(const std::string &deviceId) { callerDeviceID_ = deviceId; diff --git a/ipc/native/test/unittest/common/ipc_core_unittest.cpp b/ipc/native/test/unittest/common/ipc_core_unittest.cpp index 88e9e4a7ed33ae0cb356d6bc2794f2fb04598479..5e50daa3d081317b8dbe529a729efaa5c144510f 100755 --- a/ipc/native/test/unittest/common/ipc_core_unittest.cpp +++ b/ipc/native/test/unittest/common/ipc_core_unittest.cpp @@ -193,6 +193,35 @@ HWTEST_F(IPCNativeUnitTest, MaxWorkThread001, TestSize.Level1) ASSERT_GE(childPids.size(), (const unsigned long)1); } +/** + * @tc.name: AccessTokenid001 + * @tc.desc: Test IPC AccessTokenid transport + * @tc.type: FUNC + */ +HWTEST_F(IPCNativeUnitTest, AccessTokenid001, TestSize.Level1) +{ + IPCTestHelper helper; + bool res = helper.StartTestApp(IPCTestHelper::IPC_TEST_SERVER); + ASSERT_TRUE(res); + + auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + ASSERT_TRUE(saMgr != nullptr); + + // test get service and call it + sptr service = saMgr->GetSystemAbility(IPC_TEST_SERVICE); + sptr testService = iface_cast(service); + ASSERT_TRUE(testService != nullptr); + + if (service->IsProxyObject()) { + ZLOGI(LABEL, "Got Proxy node"); + TestServiceProxy *proxy = static_cast(testService.GetRefPtr()); + int ret = proxy->TestAccessTokenID(3571); + EXPECT_EQ(ret, 0); + } else { + ZLOGE(LABEL, "Got Stub node"); + } +} + /** * @tc.name: SyncTransaction001 * @tc.desc: Test IPC data transaction. diff --git a/ipc/test/auxiliary/native/BUILD.gn b/ipc/test/auxiliary/native/BUILD.gn index 914806198c47ebe6a094c46debff0333e2b2a2aa..4390845e6c3d1bfc80343a9c1ea43220d609f4f5 100755 --- a/ipc/test/auxiliary/native/BUILD.gn +++ b/ipc/test/auxiliary/native/BUILD.gn @@ -32,7 +32,10 @@ ohos_shared_library("ipc_test_helper") { "$SUBSYSTEM_DIR:ipc_util_config", ] - deps = [ "//utils/native/base:utils" ] + deps = [ + "//base/security/access_token/interfaces/innerkits/token_setproc:libtoken_setproc", + "//utils/native/base:utils", + ] external_deps = [ "hiviewdfx_hilog_native:libhilog", @@ -54,6 +57,7 @@ ohos_executable("ipc_server_test") { deps = [ ":ipc_test_helper", + "//base/security/access_token/interfaces/innerkits/token_setproc:libtoken_setproc", "//utils/native/base:utils", ] @@ -109,7 +113,10 @@ ohos_shared_library("ipc_test_helper_extra") { "$SUBSYSTEM_DIR:ipc_util_config", ] - deps = [ "//utils/native/base:utils" ] + deps = [ + "//base/security/access_token/interfaces/innerkits/token_setproc:libtoken_setproc", + "//utils/native/base:utils", + ] external_deps = [ "hiviewdfx_hilog_native:libhilog", diff --git a/ipc/test/auxiliary/native/include/test_service.h b/ipc/test/auxiliary/native/include/test_service.h index 585bfb027717b40520dcc2980d02812f0a87154b..55a4bba58a316f7834031ab8ad470893bd9b288f 100755 --- a/ipc/test/auxiliary/native/include/test_service.h +++ b/ipc/test/auxiliary/native/include/test_service.h @@ -45,6 +45,7 @@ public: std::u16string TestAshmem(sptr ashmem, int32_t contentSize) override; void TestAsyncDumpService() override; int TestNestingSend(int sendCode, int &replyCode) override; + int TestAccessTokenID(int32_t ftoken_expected) override; private: int testFd_; static constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_ID_IPC, "TestService" }; diff --git a/ipc/test/auxiliary/native/include/test_service_skeleton.h b/ipc/test/auxiliary/native/include/test_service_skeleton.h index d8d89f4097bd7ee3c8fe6943cf3c7f9c237be86d..83c9321d02e92faca6eb19f161ba4e0fad12405b 100755 --- a/ipc/test/auxiliary/native/include/test_service_skeleton.h +++ b/ipc/test/auxiliary/native/include/test_service_skeleton.h @@ -46,6 +46,7 @@ public: TRANS_ID_ASHMEM = 15, TRANS_ID_ASYNC_DUMP_SERVICE = 16, TRANS_ID_NESTING_SEND = 17, + TRANS_ID_ACCESS_TOKENID = 18, }; public: virtual int TestSyncTransaction(int data, int &reply, int delayTime = 0) = 0; @@ -65,6 +66,7 @@ public: virtual std::u16string TestAshmem(sptr ashmem, int32_t contentSize) = 0; virtual void TestAsyncDumpService() = 0; virtual int TestNestingSend(int sendCode, int &replyCode) = 0; + virtual int TestAccessTokenID(int32_t ftoken_expected) = 0; public: DECLARE_INTERFACE_DESCRIPTOR(u"test.ipc.ITestService"); }; @@ -102,6 +104,7 @@ public: std::u16string TestAshmem(sptr ashmem, int32_t contentSize) override; void TestAsyncDumpService() override; int TestNestingSend(int sendCode, int &replyCode) override; + int TestAccessTokenID(int32_t ftoken_expected) override; private: static inline BrokerDelegator delegator_; static constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_ID_IPC, "TestServiceProxy" }; diff --git a/ipc/test/auxiliary/native/src/test_service.cpp b/ipc/test/auxiliary/native/src/test_service.cpp index de6f69700b829b5c76b32dc57b2ecd11f7cbc3c7..cdbb66a2add5a6cc76ffe75c293e2575bbd8496b 100755 --- a/ipc/test/auxiliary/native/src/test_service.cpp +++ b/ipc/test/auxiliary/native/src/test_service.cpp @@ -183,6 +183,11 @@ int TestService::TestCallingUidPid() return 0; } +int TestService::TestAccessTokenID(int32_t ftoken_expected) +{ + return 0; +} + int TestService::TestFlushAsyncCalls(int count, int length) { return 0; diff --git a/ipc/test/auxiliary/native/src/test_service_skeleton.cpp b/ipc/test/auxiliary/native/src/test_service_skeleton.cpp index d6d5e553947ff2b6f50465099b5e513d28264b29..40aee575d4c87177e017a7494d4e68f9d3d4062e 100755 --- a/ipc/test/auxiliary/native/src/test_service_skeleton.cpp +++ b/ipc/test/auxiliary/native/src/test_service_skeleton.cpp @@ -27,6 +27,7 @@ #include "if_system_ability_manager.h" #include "iservice_registry.h" #include "system_ability_definition.h" +#include "token_setproc.h" namespace OHOS { using namespace OHOS::HiviewDFX; @@ -280,6 +281,85 @@ int TestServiceProxy::TestCallingUidPid() return -1; } +int TestServiceProxy::TestAccessTokenID(int32_t ftoken_expected) +{ + MessageOption option; + MessageParcel dataParcel, replyParcel1, replyParcel2; + + int32_t token = IPCSkeleton::GetCallingTokenID(); + int32_t ftoken = IPCSkeleton::GetFirstTokenID(); + int32_t tokenSelf = GetSelfTokenID(); + ZLOGE(LABEL, "TestServiceProxy tokenSelf: %{public}d", tokenSelf); + ZLOGE(LABEL, "TestServiceProxy ftoken: %{public}d", ftoken); + ZLOGE(LABEL, "TestServiceProxy ftoken_expected: %{public}d", ftoken_expected); + + if (token != tokenSelf) { + ZLOGE(LABEL, "token != tokenSelf 1, token:%{public}d", token); + return -1; + } + + if (ftoken != 0) { + ZLOGE(LABEL, "ftoken != 0 1"); + return -1; + } + + int ret = SetFirstCallerTokenID(ftoken_expected); + if (ret != 0) { + ZLOGE(LABEL, "SetFirstCallerTokenID ret = %{public}d", ret); + return -1; + } + + ret = GetFirstCallerTokenID(); + ZLOGE(LABEL, "TestServiceProxy get ftoken after set: %{public}d", ret); + + ret = Remote()->SendRequest(TRANS_ID_ACCESS_TOKENID, dataParcel, replyParcel1, option); + if (ret != ERR_NONE) { + ZLOGE(LABEL, "SendRequest ret = %{public}d", ret); + return ret; + } + + token = replyParcel1.ReadInt32(); + ftoken = replyParcel1.ReadInt32(); + + if (token != tokenSelf) { + ZLOGE(LABEL, "token != tokenSelf 2, token:%{public}d", token); + return -1; + } + + if (ftoken != ftoken_expected) { + ZLOGE(LABEL, "ftoken != ftoken_expected 2, ftoken:%{public}d", ftoken); + return -1; + } + + ret = SetSelfTokenID(666); + if (ret != 0) { + ZLOGE(LABEL, "SetSelfTokenID ret = %{public}d", ret); + return -1; + } + + tokenSelf = GetSelfTokenID(); + ZLOGE(LABEL, "TestServiceProxy get token after set: %{public}d", tokenSelf); + ret = Remote()->SendRequest(TRANS_ID_ACCESS_TOKENID, dataParcel, replyParcel2, option); + if (ret != ERR_NONE) { + ZLOGE(LABEL, "ret = %{public}d", ret); + return ret; + } + + token = replyParcel2.ReadInt32(); + ftoken = replyParcel2.ReadInt32(); + + if (token != tokenSelf) { + ZLOGE(LABEL, "token != tokenSelf 3, token:%{public}d", token); + return -1; + } + + if (ftoken != ftoken_expected) { + ZLOGE(LABEL, "ftoken != ftoken_expected 3, ftoken:%{public}d", ftoken); + return -1; + } + return 0; +} + int TestServiceProxy::TestFlushAsyncCalls(int count, int length) { int ret; @@ -491,6 +571,15 @@ int TestServiceStub::OnRemoteRequest(uint32_t code, reply.WriteInt32(innerResult); break; } + case TRANS_ID_ACCESS_TOKENID: { + int32_t token = IPCSkeleton::GetCallingTokenID(); + int32_t ftoken = IPCSkeleton::GetFirstTokenID(); + ZLOGE(LABEL, "server GetCallingTokenID:%{public}d", token); + ZLOGE(LABEL, "server GetFirstTokenID:%{public}d", ftoken); + reply.WriteInt32(token); + reply.WriteInt32(ftoken); + break; + } default: ret = IPCObjectStub::OnRemoteRequest(code, data, reply, option); break;