ipc rectification of security vulnerabilities

Signed-off-by: dengyutao <dengyutao2@huawei.com>
This commit is contained in:
dengyutao 2024-07-06 09:31:26 +00:00 committed by jason
parent 32d9e3bc96
commit 02f587bd16
8 changed files with 58 additions and 44 deletions

View File

@ -37,7 +37,7 @@ struct InvokerProcInfo {
uint64_t tokenId;
uint64_t firstTokenId;
std::string sid;
uintptr_t invoker;
uint32_t invoker;
};
class ProcessSkeleton {
@ -45,6 +45,7 @@ public:
static std::string ConvertToSecureDesc(const std::string &str);
bool SetIPCProxyLimit(uint64_t num, std::function<void (uint64_t num)> callback);
static bool IsPrint(int err, int &lastErr, int &lastErrCnt);
static uint32_t ConvertAddr(const void *ptr);
static ProcessSkeleton* GetInstance();
sptr<IRemoteObject> GetRegistryObject();
void SetRegistryObject(sptr<IRemoteObject> &object);

View File

@ -63,8 +63,8 @@ static const long long int SEND_REQUEST_TIMEOUT = 2000;
IPCObjectProxy::IPCObjectProxy(int handle, std::u16string descriptor, int proto)
: IRemoteObject(std::move(descriptor)), handle_(handle), proto_(proto), isFinishInit_(false), isRemoteDead_(false)
{
ZLOGD(LABEL, "handle:%{public}u desc:%{public}s %{public}zu", handle_,
ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(descriptor_)).c_str(), reinterpret_cast<uintptr_t>(this));
ZLOGD(LABEL, "handle:%{public}u desc:%{public}s %{public}u", handle_,
ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(descriptor_)).c_str(), ProcessSkeleton::ConvertAddr(this));
ExtendObjectLifetime();
ProcessSkeleton *current = ProcessSkeleton::GetInstance();
if (current == nullptr) {
@ -76,9 +76,9 @@ IPCObjectProxy::IPCObjectProxy(int handle, std::u16string descriptor, int proto)
IPCObjectProxy::~IPCObjectProxy()
{
ZLOGD(LABEL, "handle:%{public}u desc:%{public}s %{public}zu", handle_,
ZLOGD(LABEL, "handle:%{public}u desc:%{public}s %{public}u", handle_,
ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(remoteDescriptor_)).c_str(),
reinterpret_cast<uintptr_t>(this));
ProcessSkeleton::ConvertAddr(this));
ProcessSkeleton *current = ProcessSkeleton::GetInstance();
if (current == nullptr) {
ZLOGE(LABEL, "ProcessSkeleton is null");
@ -384,9 +384,9 @@ bool IPCObjectProxy::AddDeathRecipient(const sptr<DeathRecipient> &recipient)
}
}
#endif
ZLOGD(LABEL, "success, handle:%{public}d desc:%{public}s %{public}zu", handle_,
ZLOGD(LABEL, "success, handle:%{public}d desc:%{public}s %{public}u", handle_,
ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(remoteDescriptor_)).c_str(),
reinterpret_cast<uintptr_t>(this));
ProcessSkeleton::ConvertAddr(this));
return true;
}
@ -426,9 +426,9 @@ bool IPCObjectProxy::RemoveDeathRecipient(const sptr<DeathRecipient> &recipient)
dbinderStatus = RemoveDbinderDeathRecipient();
}
#endif
ZLOGD(LABEL, "result:%{public}d handle:%{public}d desc:%{public}s %{public}zu", status && dbinderStatus,
ZLOGD(LABEL, "result:%{public}d handle:%{public}d desc:%{public}s %{public}u", status && dbinderStatus,
handle_, ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(remoteDescriptor_)).c_str(),
reinterpret_cast<uintptr_t>(this));
ProcessSkeleton::ConvertAddr(this));
return status && dbinderStatus;
}
return recipientErased;
@ -436,9 +436,9 @@ bool IPCObjectProxy::RemoveDeathRecipient(const sptr<DeathRecipient> &recipient)
void IPCObjectProxy::SendObituary()
{
ZLOGW(LABEL, "handle:%{public}d desc:%{public}s %{public}zu", handle_,
ZLOGW(LABEL, "handle:%{public}d desc:%{public}s %{public}u", handle_,
ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(remoteDescriptor_)).c_str(),
reinterpret_cast<uintptr_t>(this));
ProcessSkeleton::ConvertAddr(this));
#ifndef CONFIG_IPC_SINGLE
if (handle_ < IPCProcessSkeleton::DBINDER_HANDLE_BASE) {
if (proto_ == IRemoteObject::IF_PROT_DATABUS || proto_ == IRemoteObject::IF_PROT_ERROR) {

View File

@ -63,9 +63,9 @@ static constexpr int IPC_CMD_PROCESS_WARN_TIME = 500 * COEFF_MILLI_TO_MICRO; //
IPCObjectStub::IPCObjectStub(std::u16string descriptor, bool serialInvokeFlag)
: IRemoteObject(descriptor), serialInvokeFlag_(serialInvokeFlag), lastRequestTime_(0)
{
ZLOGD(LABEL, "desc:%{public}s, %{public}zu",
ZLOGD(LABEL, "desc:%{public}s, %{public}u",
ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(descriptor_)).c_str(),
reinterpret_cast<uintptr_t>(this));
ProcessSkeleton::ConvertAddr(this));
InitCodeMap();
ProcessSkeleton *current = ProcessSkeleton::GetInstance();
if (current == nullptr) {
@ -80,9 +80,9 @@ IPCObjectStub::IPCObjectStub(std::u16string descriptor, bool serialInvokeFlag)
IPCObjectStub::~IPCObjectStub()
{
ZLOGD(LABEL, "desc:%{public}s, %{public}zu",
ZLOGD(LABEL, "desc:%{public}s, %{public}u",
ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(descriptor_)).c_str(),
reinterpret_cast<uintptr_t>(this));
ProcessSkeleton::ConvertAddr(this));
ProcessSkeleton *current = ProcessSkeleton::GetInstance();
if (current == nullptr) {
ZLOGE(LABEL, "ProcessSkeleton is null");

View File

@ -206,7 +206,7 @@ sptr<IRemoteObject> IPCProcessSkeleton::FindOrNewObject(int handle)
uint64_t curTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::steady_clock::now().time_since_epoch()).count());
ZLOGE(LOG_LABEL, "init rpc proxy failed, handle:%{public}d %{public}zu, time:%{public}" PRIu64, handle,
reinterpret_cast<uintptr_t>(result.GetRefPtr()), curTime);
ProcessSkeleton::ConvertAddr(result.GetRefPtr()), curTime);
if (proxy->GetSptrRefCount() <= DETACH_PROXY_REF_COUNT) {
DetachObject(result.GetRefPtr());
}

View File

@ -83,7 +83,7 @@ IPCThreadSkeleton *IPCThreadSkeleton::GetCurrent()
IPCThreadSkeleton::IPCThreadSkeleton()
{
ZLOGD(LOG_LABEL, "%{public}zu", reinterpret_cast<uintptr_t>(this));
ZLOGD(LOG_LABEL, "%{public}u", ProcessSkeleton::ConvertAddr(this));
pthread_setspecific(TLSKey_, this);
}
@ -92,10 +92,10 @@ IPCThreadSkeleton::~IPCThreadSkeleton()
exitFlag_ = true;
pthread_setspecific(TLSKey_, nullptr);
while (usingFlag_.load()) {
ZLOGI(LOG_LABEL, "%{public}zu is using, wait a moment", reinterpret_cast<uintptr_t>(this));
ZLOGI(LOG_LABEL, "%{public}u is using, wait a moment", ProcessSkeleton::ConvertAddr(this));
usleep(1);
}
ZLOGD(LOG_LABEL, "%{public}zu", reinterpret_cast<uintptr_t>(this));
ZLOGD(LOG_LABEL, "%{public}u", ProcessSkeleton::ConvertAddr(this));
for (auto it = invokers_.begin(); it != invokers_.end();) {
delete it->second;
it = invokers_.erase(it);

View File

@ -29,6 +29,12 @@ static constexpr uint64_t DEAD_OBJECT_TIMEOUT = 20 * (60 * 1000); // min
static constexpr uint64_t DEAD_OBJECT_CHECK_INTERVAL = 11 * (60 * 1000); // min
static constexpr int PRINT_ERR_CNT = 100;
#ifdef __aarch64__
static constexpr uint32_t IPC_OBJECT_MASK = 0xffffffff;
#else
static constexpr uint32_t IPC_OBJECT_MASK = 0xffffff;
#endif
ProcessSkeleton* ProcessSkeleton::instance_ = nullptr;
std::mutex ProcessSkeleton::mutex_;
ProcessSkeleton::DestroyInstance ProcessSkeleton::destroyInstance_;
@ -130,7 +136,7 @@ bool ProcessSkeleton::AttachObject(IRemoteObject *object, const std::u16string &
(void)isContainStub_.insert(std::pair<IRemoteObject *, bool>(object, true));
if (descriptor.empty()) {
ZLOGE(LOG_LABEL, "descriptor is null %{public}zu", reinterpret_cast<uintptr_t>(object));
ZLOGE(LOG_LABEL, "descriptor is null %{public}u", ConvertAddr(object));
return false;
}
// If attemptIncStrong failed, old proxy might still exist, replace it with the new proxy.
@ -199,8 +205,8 @@ bool ProcessSkeleton::AttachDeadObject(IRemoteObject *object, DeadObjectInfo &ob
CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
std::unique_lock<std::shared_mutex> lockGuard(deadObjectMutex_);
auto result = deadObjectRecord_.insert_or_assign(object, objInfo);
ZLOGD(LOG_LABEL, "%{public}zu handle:%{public}d desc:%{public}s inserted:%{public}d",
reinterpret_cast<uintptr_t>(object), objInfo.handle,
ZLOGD(LOG_LABEL, "%{public}u handle:%{public}d desc:%{public}s inserted:%{public}d",
ConvertAddr(object), objInfo.handle,
ConvertToSecureDesc(Str16ToStr8(objInfo.desc)).c_str(), result.second);
DetachTimeoutDeadObject();
return result.second;
@ -213,7 +219,7 @@ bool ProcessSkeleton::DetachDeadObject(IRemoteObject *object)
std::unique_lock<std::shared_mutex> lockGuard(deadObjectMutex_);
auto it = deadObjectRecord_.find(object);
if (it != deadObjectRecord_.end()) {
ZLOGD(LOG_LABEL, "erase %{public}zu handle:%{public}d desc:%{public}s", reinterpret_cast<uintptr_t>(object),
ZLOGD(LOG_LABEL, "erase %{public}u handle:%{public}d desc:%{public}s", ConvertAddr(object),
it->second.handle, ConvertToSecureDesc(Str16ToStr8(it->second.desc)).c_str());
deadObjectRecord_.erase(it);
ret = true;
@ -250,8 +256,8 @@ void ProcessSkeleton::DetachTimeoutDeadObject()
deadObjectClearTime_ = curTime;
for (auto it = deadObjectRecord_.begin(); it != deadObjectRecord_.end();) {
if (curTime - it->second.agingTime >= DEAD_OBJECT_TIMEOUT) {
ZLOGD(LOG_LABEL, "erase %{public}zu handle:%{public}d desc:%{public}s time:%{public}" PRIu64,
reinterpret_cast<uintptr_t>(it->first), it->second.handle,
ZLOGD(LOG_LABEL, "erase %{public}u handle:%{public}d desc:%{public}s time:%{public}" PRIu64,
ConvertAddr(it->first), it->second.handle,
ConvertToSecureDesc(Str16ToStr8(it->second.desc)).c_str(), it->second.deadTime);
it = deadObjectRecord_.erase(it);
continue;
@ -267,7 +273,7 @@ bool ProcessSkeleton::AttachInvokerProcInfo(bool isLocal, InvokerProcInfo &invok
std::string key = std::to_string(gettid()) + "_" + std::to_string(isLocal);
auto result = invokerProcInfo_.insert_or_assign(key, invokeInfo);
auto &info = result.first->second;
ZLOGD(LOG_LABEL, "%{public}zu, %{public}u %{public}u %{public}u %{public}" PRIu64 " %{public}" PRIu64,
ZLOGD(LOG_LABEL, "%{public}u, %{public}u %{public}u %{public}u %{public}" PRIu64 " %{public}" PRIu64,
info.invoker, info.pid, info.realPid, info.uid, info.tokenId, info.firstTokenId);
return result.second;
}
@ -282,7 +288,7 @@ bool ProcessSkeleton::QueryInvokerProcInfo(bool isLocal, InvokerProcInfo &invoke
return false;
}
invokeInfo = it->second;
ZLOGD(LOG_LABEL, "%{public}zu, %{public}u %{public}u %{public}u %{public}" PRIu64 " %{public}" PRIu64,
ZLOGD(LOG_LABEL, "%{public}u, %{public}u %{public}u %{public}u %{public}" PRIu64 " %{public}" PRIu64,
invokeInfo.invoker, invokeInfo.pid, invokeInfo.realPid, invokeInfo.uid, invokeInfo.tokenId,
invokeInfo.firstTokenId);
return true;
@ -296,7 +302,7 @@ bool ProcessSkeleton::DetachInvokerProcInfo(bool isLocal)
auto it = invokerProcInfo_.find(key);
if (it != invokerProcInfo_.end()) {
auto &invokeInfo = it->second;
ZLOGD(LOG_LABEL, "%{public}zu, %{public}u %{public}u %{public}u %{public}" PRIu64 " %{public}" PRIu64,
ZLOGD(LOG_LABEL, "%{public}u, %{public}u %{public}u %{public}u %{public}" PRIu64 " %{public}" PRIu64,
invokeInfo.invoker, invokeInfo.pid, invokeInfo.realPid, invokeInfo.uid, invokeInfo.tokenId,
invokeInfo.firstTokenId);
invokerProcInfo_.erase(it);
@ -335,4 +341,13 @@ bool ProcessSkeleton::SetIPCProxyLimit(uint64_t num, std::function<void (uint64_
ipcProxyCallback_ = callback;
return true;
}
uint32_t ProcessSkeleton::ConvertAddr(const void *ptr)
{
if (ptr == nullptr) {
ZLOGE(LOG_LABEL, "ptr is null");
return 0;
}
return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(ptr)) & IPC_OBJECT_MASK;
}
} // namespace OHOS

View File

@ -83,15 +83,15 @@ BinderInvoker::BinderInvoker()
callerTokenID_(0), firstTokenID_(0), callerSid_(""), status_(0)
{
invokerInfo_ = { callerPid_, callerRealPid_, callerUid_, callerTokenID_, firstTokenID_, callerSid_,
reinterpret_cast<uintptr_t>(this) };
ProcessSkeleton::ConvertAddr(this) };
input_.SetDataCapacity(IPC_DEFAULT_PARCEL_SIZE);
binderConnector_ = BinderConnector::GetInstance();
ZLOGD(LABEL, "created %{public}zu", reinterpret_cast<uintptr_t>(this));
ZLOGD(LABEL, "created %{public}u", ProcessSkeleton::ConvertAddr(this));
}
BinderInvoker::~BinderInvoker()
{
ZLOGD(LABEL, "destroyed %{public}zu", reinterpret_cast<uintptr_t>(this));
ZLOGD(LABEL, "destroyed %{public}u", ProcessSkeleton::ConvertAddr(this));
auto current = ProcessSkeleton::GetInstance();
if (current != nullptr) {
current->DetachInvokerProcInfo(true);
@ -442,8 +442,8 @@ void BinderInvoker::OnBinderDied()
ProcessSkeleton *current = ProcessSkeleton::GetInstance();
DeadObjectInfo deadInfo;
if ((current != nullptr) && current->IsDeadObject(proxy, deadInfo)) {
ZLOGE(LABEL, "%{public}zu handle:%{public}d desc:%{public}s is deaded at time:%{public}" PRIu64,
reinterpret_cast<uintptr_t>(proxy), deadInfo.handle,
ZLOGE(LABEL, "%{public}u handle:%{public}d desc:%{public}s is deaded at time:%{public}" PRIu64,
ProcessSkeleton::ConvertAddr(proxy), deadInfo.handle,
ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(deadInfo.desc)).c_str(), deadInfo.deadTime);
} else {
proxy->SendObituary();
@ -476,8 +476,8 @@ void BinderInvoker::OnAcquireObject(uint32_t cmd)
ProcessSkeleton *current = ProcessSkeleton::GetInstance();
DeadObjectInfo deadInfo;
if ((current != nullptr) && current->IsDeadObject(obj, deadInfo)) {
ZLOGE(LABEL, "%{public}zu desc:%{public}s is deaded at time:%{public}" PRIu64,
reinterpret_cast<uintptr_t>(obj),
ZLOGE(LABEL, "%{public}u desc:%{public}s is deaded at time:%{public}" PRIu64,
ProcessSkeleton::ConvertAddr(obj),
ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(deadInfo.desc)).c_str(), deadInfo.deadTime);
return;
}
@ -516,14 +516,14 @@ void BinderInvoker::OnReleaseObject(uint32_t cmd)
return;
}
ZLOGD(LABEL, "refcount:%{public}d refs:%{public}zu obj:%{public}zu", refs->GetStrongRefCount(),
reinterpret_cast<uintptr_t>(refs), reinterpret_cast<uintptr_t>(obj));
ZLOGD(LABEL, "refcount:%{public}d refs:%{public}u obj:%{public}u", refs->GetStrongRefCount(),
ProcessSkeleton::ConvertAddr(refs), ProcessSkeleton::ConvertAddr(obj));
if (cmd == BR_RELEASE) {
ProcessSkeleton *current = ProcessSkeleton::GetInstance();
DeadObjectInfo deadInfo;
if ((current != nullptr) && current->IsDeadObject(obj, deadInfo)) {
ZLOGD(LABEL, "%{public}zu desc:%{public}s is deaded at time:%{public}" PRIu64,
reinterpret_cast<uintptr_t>(obj),
ZLOGD(LABEL, "%{public}u desc:%{public}s is deaded at time:%{public}" PRIu64,
ProcessSkeleton::ConvertAddr(obj),
ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(deadInfo.desc)).c_str(), deadInfo.deadTime);
return;
}
@ -572,7 +572,7 @@ void BinderInvoker::RestoreInvokerProcInfo(const InvokerProcInfo &info)
void BinderInvoker::AttachInvokerProcInfoWrapper()
{
InvokerProcInfo invokerInfo = { callerPid_, callerRealPid_,
callerUid_, callerTokenID_, firstTokenID_, callerSid_, reinterpret_cast<uintptr_t>(this) };
callerUid_, callerTokenID_, firstTokenID_, callerSid_, ProcessSkeleton::ConvertAddr(this) };
auto current = ProcessSkeleton::GetInstance();
if (current != nullptr) {
current->AttachInvokerProcInfo(true, invokerInfo);
@ -605,8 +605,8 @@ int32_t BinderInvoker::GeneralServiceSendRequest(
DeadObjectInfo deadInfo;
auto current = ProcessSkeleton::GetInstance();
if ((current != nullptr) && current->IsDeadObject(targetObject, deadInfo)) {
ZLOGE(LABEL, "%{public}zu desc:%{public}s is deaded at time:%{public}" PRIu64,
reinterpret_cast<uintptr_t>(targetObject),
ZLOGE(LABEL, "%{public}u desc:%{public}s is deaded at time:%{public}" PRIu64,
ProcessSkeleton::ConvertAddr(targetObject),
ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(deadInfo.desc)).c_str(), deadInfo.deadTime);
} else {
error = targetObject->SendRequest(tr.code, data, reply, option);

View File

@ -35,12 +35,10 @@ DBinderDatabusInvoker::DBinderDatabusInvoker()
: stopWorkThread_(false), callerPid_(getpid()), callerUid_(getuid()), callerDeviceID_(""),
callerTokenID_(0), firstTokenID_(0), status_(0)
{
ZLOGI(LOG_LABEL, "create %{public}zu", reinterpret_cast<uintptr_t>(this));
}
DBinderDatabusInvoker::~DBinderDatabusInvoker()
{
ZLOGI(LOG_LABEL, "destroy %{public}zu", reinterpret_cast<uintptr_t>(this));
}
bool DBinderDatabusInvoker::AcquireHandle(int32_t handle)