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..258b1262729767267b91c4b459ced14d160e4f10 100755 --- a/interfaces/innerkits/ipc_core/include/ipc_skeleton.h +++ b/interfaces/innerkits/ipc_core/include/ipc_skeleton.h @@ -37,6 +37,12 @@ public: static pid_t GetCallingUid(); + static uint32_t GetCallingTokenID(); + + static uint32_t GetFirstTokenID(); + + static int SetFirstTokenID(uint32_t tokenID); + static std::string GetLocalDeviceID(); static std::string GetCallingDeviceID(); diff --git a/interfaces/innerkits/ipc_core/include/ipc_types.h b/interfaces/innerkits/ipc_core/include/ipc_types.h index 66b46ad1b8ac72b24d874fd4f4b0fe615fc31716..cc93a98838e5cad8348c1ffec0ef01a9b9d47377 100755 --- a/interfaces/innerkits/ipc_core/include/ipc_types.h +++ b/interfaces/innerkits/ipc_core/include/ipc_types.h @@ -77,6 +77,7 @@ enum { ERR_INVALID_STATE, IPC_SKELETON_ERR = 100, IPC_SKELETON_NULL_OBJECT_ERR, + IPC_SKELETON_SET_FTOKEN_ERR, IPC_PROXY_ERR = 200, IPC_PROXY_DEAD_OBJECT_ERR, IPC_PROXY_NULL_INVOKER_ERR, 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..7b4b43a4ea7bd422a916073d7cd9a0105e641601 100755 --- a/ipc/native/src/core/source/ipc_skeleton.cpp +++ b/ipc/native/src/core/source/ipc_skeleton.cpp @@ -84,6 +84,44 @@ pid_t IPCSkeleton::GetCallingUid() return getuid(); } +uint32_t IPCSkeleton::GetCallingTokenID() +{ + IRemoteInvoker *invoker = IPCThreadSkeleton::GetActiveInvoker(); + if (invoker != nullptr) { + return invoker->GetCallerTokenID(); + } + uint64_t token; + int ret = sys_gettokenid(&token, 0); + if (ret != 0) { + return 0; + } + return (uint32_t)token; +} + +uint32_t IPCSkeleton::GetFirstTokenID() +{ + IRemoteInvoker *invoker = IPCThreadSkeleton::GetActiveInvoker(); + if (invoker != nullptr) { + return invoker->GetFirstTokenID(); + } + uint64_t ftoken; + int ret = sys_getftokenid(&ftoken, 0); + if (ret != 0) { + return 0; + } + return (uint32_t)ftoken; +} + +int IPCSkeleton::SetFirstTokenID(uint32_t tokenID) +{ + uint64_t tmp = (uint64_t)tokenID; + int ret = sys_setftokenid(&tmp, 0); + if (ret != 0) { + return IPC_SKELETON_SET_FTOKEN_ERR; + } + return ERR_NONE; +} + std::string IPCSkeleton::GetLocalDeviceID() { IRemoteInvoker *invoker = IPCThreadSkeleton::GetActiveInvoker(); 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_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..1996d2eeefdbfefade36ddfdb66ee1d35a569c51 100755 --- a/ipc/native/src/mock/include/sys_binder.h +++ b/ipc/native/src/mock/include/sys_binder.h @@ -16,6 +16,7 @@ #ifndef OHOS_IPC_SYS_BINDER_H #define OHOS_IPC_SYS_BINDER_H +#include #include #ifndef _UAPI_LINUX_BINDER_H @@ -143,6 +144,8 @@ struct binder_transaction_data { __u32 flags; pid_t sender_pid; uid_t sender_euid; + __u64 sender_tokenid; + __u64 first_tokenid; binder_size_t data_size; binder_size_t offsets_size; union { diff --git a/ipc/native/src/mock/source/binder_invoker.cpp b/ipc/native/src/mock/source/binder_invoker.cpp index 46fc5119bf8f9541960cc7b4e3286d5237f52834..a1e5d5e029ba4755b8f5c3f67d444bede35da7be 100755 --- a/ipc/native/src/mock/source/binder_invoker.cpp +++ b/ipc/native/src/mock/source/binder_invoker.cpp @@ -42,8 +42,16 @@ 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) { + uint64_t token; + int ret = sys_gettokenid(&token, 0); + if (ret != 0) { + callerTokenID_ = -1; + } else { + callerTokenID_ = (uint32_t)token; + } input_.SetDataCapacity(IPC_DEFAULT_PARCEL_SIZE); binderConnector_ = BinderConnector::GetInstance(); } @@ -423,9 +431,13 @@ void BinderInvoker::OnTransaction(const uint8_t *buffer) #endif 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; + callerTokenID_ = tr->sender_tokenid; + firstTokenID_ = tr->first_tokenid; SetStatus(IRemoteInvoker::ACTIVE_INVOKER); int error = ERR_DEAD_OBJECT; sptr targetObject; @@ -453,6 +465,8 @@ void BinderInvoker::OnTransaction(const uint8_t *buffer) } callerPid_ = oldPid; callerUid_ = oldUid; + callerTokenID_ = oldToken; + firstTokenID_ = oldFirstToken; SetStatus(oldStatus); } @@ -804,6 +818,24 @@ uid_t BinderInvoker::GetCallerUid() const return callerUid_; } +uint32_t BinderInvoker::GetCallerTokenID() const +{ + return callerTokenID_; +} + +uint32_t BinderInvoker::GetFirstTokenID() const +{ + if (firstTokenID_ == -1) { + uint64_t ftoken; + int ret = sys_getftokenid(&ftoken, 0); + if (ret != 0) { + return 0; + } + return (uint32_t)ftoken; + } + 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/test/auxiliary/native/include/test_service_skeleton.h b/ipc/test/auxiliary/native/include/test_service_skeleton.h index d8d89f4097bd7ee3c8fe6943cf3c7f9c237be86d..8c4072d0af8d922c58ca4940b583ba715434cc97 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; diff --git a/ipc/test/auxiliary/native/src/test_service_skeleton.cpp b/ipc/test/auxiliary/native/src/test_service_skeleton.cpp index d6d5e553947ff2b6f50465099b5e513d28264b29..e6badf381173005f2a546fc730193758d61926a8 100755 --- a/ipc/test/auxiliary/native/src/test_service_skeleton.cpp +++ b/ipc/test/auxiliary/native/src/test_service_skeleton.cpp @@ -280,6 +280,52 @@ int TestServiceProxy::TestCallingUidPid() return -1; } + +int TestServiceProxy::TestAccessTokenID() +{ + MessageOption option; + MessageParcel dataParcel, replyParcel; + + int32_t token = IPCSkeleton::GetCallingTokenID(); + int32_t ftoken = IPCSkeleton::GetFirstTokenID(); + int32_t tokenSelf; + int ret = sys_gettokenid(&tokenSelf, 0); + if (ret != 0 || tokenSelf != token || ftoken != 0) { + return -1; + } + + ret = IPCSkeleton::SetFirstTokenID(0x12345678); + if (ret != 0) { + return -1; + } + ret = Remote()->SendRequest(TRANS_ID_ACCESS_TOKENID, dataParcel, replyParcel, option); + if (ret != ERR_NONE) { + ZLOGE(LABEL, "ret = %{public}d", ret); + return ret; + } + + token = replyParcel.ReadInt32(); + ftoken = replyParcel.ReadInt32(); + + if (token != tokenSelf || ftoken != 0x12345678) { + return -1; + } + + ret = Remote()->SendRequest(TRANS_ID_ACCESS_TOKENID, dataParcel, replyParcel, option); + if (ret != ERR_NONE) { + ZLOGE(LABEL, "ret = %{public}d", ret); + return ret; + } + + token = replyParcel.ReadInt32(); + ftoken = replyParcel.ReadInt32(); + + if (token != tokenSelf || ftoken != 0x12345678) { + return -1; + } + return 0; +} + int TestServiceProxy::TestFlushAsyncCalls(int count, int length) { int ret; @@ -472,6 +518,11 @@ int TestServiceStub::OnRemoteRequest(uint32_t code, IPCSkeleton::GetCallingUid(), IPCSkeleton::GetCallingPid()); break; } + case TRANS_ID_ACCESS_TOKENID: { + reply.WriteInt32(IPCSkeleton::GetCallingTokenID()); + reply.WriteInt32(IPCSkeleton::GetFirstTokenID()); + break; + } case TRANS_ID_FLUSH_ASYNC_CALLS: { (void)data.ReadString16(); break;