[*] Introduce APIs to access IProcessSectionMapView safely when malicious calls to Unmap could be made
This commit is contained in:
parent
f589227c1d
commit
3115627424
@ -79,6 +79,32 @@ namespace Aurora::Memory
|
||||
this->controlBlock.pPinner = view.controlBlock.pPinner;
|
||||
}
|
||||
|
||||
MemoryView(const MemoryView &view, const AuSPtr<void> &pThat)
|
||||
{
|
||||
this->ptr = view.ptr;
|
||||
this->length = view.length;
|
||||
this->controlBlock.pInUseCounter = view.controlBlock.pInUseCounter;
|
||||
if (this->controlBlock.pInUseCounter)
|
||||
{
|
||||
AuAtomicAdd(this->controlBlock.pInUseCounter, 1u);
|
||||
}
|
||||
if (view.controlBlock.pPinner)
|
||||
{
|
||||
auto pThat2 = AuMakeSharedArray<AuSPtr<void>>(2);
|
||||
this->controlBlock.pPinner = pThat2;
|
||||
if (!this->controlBlock.pPinner)
|
||||
{
|
||||
AuMemoryPanic("OOM");
|
||||
}
|
||||
pThat2.get()[0] = pThat;
|
||||
pThat2.get()[1] = view.controlBlock.pPinner;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->controlBlock.pPinner = pThat;
|
||||
}
|
||||
}
|
||||
|
||||
MemoryView(MemoryView &&view)
|
||||
{
|
||||
this->ptr = view.ptr;
|
||||
@ -280,7 +306,9 @@ namespace Aurora::Memory
|
||||
{
|
||||
if (uOffset < this->uLength)
|
||||
{
|
||||
return MemoryView(this->pBase + uOffset, this->uLength - uOffset, this->controlBlock);
|
||||
return MemoryView((AuUInt8 *)this->pBase + uOffset,
|
||||
this->uLength - uOffset,
|
||||
this->controlBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -292,7 +320,9 @@ namespace Aurora::Memory
|
||||
{
|
||||
if (uLength <= this->uLength)
|
||||
{
|
||||
return MemoryView(this->pBase, uLength, this->controlBlock);
|
||||
return MemoryView((AuUInt8 *)this->pBase,
|
||||
uLength,
|
||||
this->controlBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -13,13 +13,16 @@ namespace Aurora::Process
|
||||
{
|
||||
virtual void Unmap() = 0;
|
||||
|
||||
virtual bool Flush(AuUInt offset, AuUInt length) = 0;
|
||||
virtual bool Flush(AuUInt uOffset, AuUInt uLength) = 0;
|
||||
|
||||
virtual AuUInt GetBaseAddress() = 0;
|
||||
virtual AuUInt GetAddress(AuUInt offset) = 0;
|
||||
virtual AuUInt GetAddress(AuUInt uOffset) = 0;
|
||||
|
||||
virtual AuUInt8 *GetBasePointer() = 0;
|
||||
virtual AuUInt8 *GetPointer(AuUInt offset) = 0;
|
||||
virtual AuUInt8 *GetPointer(AuUInt uOffset) = 0;
|
||||
|
||||
virtual Memory::MemoryViewWrite ToWriteView() = 0;
|
||||
virtual Memory::MemoryViewRead ToReadView() = 0;
|
||||
|
||||
virtual bool LockSwap() = 0;
|
||||
virtual bool UnlockSwap() = 0;
|
||||
|
@ -12,26 +12,35 @@
|
||||
|
||||
namespace Aurora::Process
|
||||
{
|
||||
ProcessSectionFileMapView::~ProcessSectionFileMapView()
|
||||
{
|
||||
Unmap();
|
||||
}
|
||||
|
||||
ProcessSectionFileMapView::ProcessSectionFileMapView(AuUInt uAddress, HANDLE hSection) :
|
||||
uAddress(uAddress),
|
||||
ProcessSectionFileMapView::ProcessSectionFileMapView(AuUInt uAddress,
|
||||
HANDLE hSection) :
|
||||
uAddress_(uAddress),
|
||||
hFileSection(hSection)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ProcessSectionFileMapView::~ProcessSectionFileMapView()
|
||||
{
|
||||
Unmap();
|
||||
}
|
||||
|
||||
void ProcessSectionFileMapView::Unmap()
|
||||
{
|
||||
AU_LOCK_GUARD(this->mutex_);
|
||||
|
||||
if (AuAtomicLoad(&this->uInUse_))
|
||||
{
|
||||
SysPushErrorResourceLocked("Cannot unmap memory while it's in use");
|
||||
return;
|
||||
}
|
||||
|
||||
if (AuExchange(this->bIsDead_, true))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->uAddress)
|
||||
if (this->uAddress_)
|
||||
{
|
||||
if (this->pSharedSectionHint)
|
||||
{
|
||||
@ -39,9 +48,9 @@ namespace Aurora::Process
|
||||
}
|
||||
else
|
||||
{
|
||||
::UnmapViewOfFile((PVOID)this->uAddress);
|
||||
::UnmapViewOfFile((PVOID)this->uAddress_);
|
||||
}
|
||||
this->uAddress = 0;
|
||||
this->uAddress_ = 0;
|
||||
}
|
||||
|
||||
AuWin32CloseHandle(this->hFileSection);
|
||||
@ -49,48 +58,62 @@ namespace Aurora::Process
|
||||
this->pProcessGlobalHint = nullptr;
|
||||
}
|
||||
|
||||
bool ProcessSectionFileMapView::Flush(AuUInt offset, AuUInt length)
|
||||
bool ProcessSectionFileMapView::Flush(AuUInt uOffset, AuUInt uLength)
|
||||
{
|
||||
return ::FlushViewOfFile(this->GetPointer(offset), length);
|
||||
return ::FlushViewOfFile(this->GetPointer(uOffset), uLength);
|
||||
}
|
||||
|
||||
AuMemoryViewWrite ProcessSectionFileMapView::ToWriteView()
|
||||
{
|
||||
return AuMemoryViewWrite((char *)this->uAddress_, this->uLength, &this->uInUse_);
|
||||
}
|
||||
|
||||
AuMemoryViewRead ProcessSectionFileMapView::ToReadView()
|
||||
{
|
||||
return AuMemoryViewRead((char *)this->uAddress_, this->uLength, &this->uInUse_);
|
||||
}
|
||||
|
||||
AuUInt ProcessSectionFileMapView::GetBaseAddress()
|
||||
{
|
||||
return this->uAddress;
|
||||
return this->uAddress_;
|
||||
}
|
||||
|
||||
AuUInt ProcessSectionFileMapView::GetAddress(AuUInt offset)
|
||||
AuUInt ProcessSectionFileMapView::GetAddress(AuUInt uOffset)
|
||||
{
|
||||
return this->uAddress ? this->uAddress + offset : 0;
|
||||
return this->uAddress_ && this->uLength > uOffset ?
|
||||
this->uAddress_ + uOffset :
|
||||
0;
|
||||
}
|
||||
|
||||
AuUInt8 *ProcessSectionFileMapView::GetBasePointer()
|
||||
{
|
||||
return AuReinterpretCast<AuUInt8 *>(this->uAddress);
|
||||
return AuReinterpretCast<AuUInt8 *>(this->uAddress_);
|
||||
}
|
||||
|
||||
AuUInt8 *ProcessSectionFileMapView::GetPointer(AuUInt offset)
|
||||
AuUInt8 *ProcessSectionFileMapView::GetPointer(AuUInt uOffset)
|
||||
{
|
||||
return this->uAddress ? AuReinterpretCast<AuUInt8 *>(this->uAddress) + offset : 0;
|
||||
return this->uAddress_ && this->uLength > uOffset ?
|
||||
AuReinterpretCast<AuUInt8 *>(this->uAddress_) + uOffset :
|
||||
0;
|
||||
}
|
||||
|
||||
bool ProcessSectionFileMapView::LockSwap()
|
||||
{
|
||||
if (!this->uAddress)
|
||||
if (!this->uAddress_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return AuMemory::SwapLock::Lock({ { this->uAddress, this->uLength} });
|
||||
return AuMemory::SwapLock::Lock({ { this->uAddress_, this->uLength } });
|
||||
}
|
||||
|
||||
bool ProcessSectionFileMapView::UnlockSwap()
|
||||
{
|
||||
if (!this->uAddress)
|
||||
if (!this->uAddress_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return AuMemory::SwapLock::Unlock({ { this->uAddress, this->uLength} });
|
||||
return AuMemory::SwapLock::Unlock({ { this->uAddress_, this->uLength } });
|
||||
}
|
||||
}
|
@ -18,13 +18,16 @@ namespace Aurora::Process
|
||||
|
||||
void Unmap() override;
|
||||
|
||||
bool Flush(AuUInt offset, AuUInt length) override;
|
||||
bool Flush(AuUInt uOffset, AuUInt uLength) override;
|
||||
|
||||
AuUInt GetBaseAddress() override;
|
||||
AuUInt GetAddress(AuUInt offset) override;
|
||||
AuUInt GetAddress(AuUInt uOffset) override;
|
||||
|
||||
AuUInt8 *GetBasePointer() override;
|
||||
AuUInt8 *GetPointer(AuUInt offset) override;
|
||||
AuUInt8 *GetPointer(AuUInt uOffset) override;
|
||||
|
||||
Memory::MemoryViewWrite ToWriteView() override;
|
||||
Memory::MemoryViewRead ToReadView() override;
|
||||
|
||||
bool LockSwap() override;
|
||||
bool UnlockSwap() override;
|
||||
@ -36,7 +39,9 @@ namespace Aurora::Process
|
||||
|
||||
private:
|
||||
HANDLE hFileSection {};
|
||||
AuUInt uAddress {};
|
||||
AuUInt uAddress_ {};
|
||||
AuAUInt32 uInUse_ {};
|
||||
AuMutex mutex_;
|
||||
|
||||
bool bIsDead_ {};
|
||||
};
|
||||
|
@ -13,8 +13,11 @@
|
||||
|
||||
namespace Aurora::Process
|
||||
{
|
||||
ProcessSectionFileMapView::ProcessSectionFileMapView(AuUInt uAddress, AuUInt uLength, bool bShouldUnmap, int optFd) :
|
||||
uAddress(uAddress),
|
||||
ProcessSectionFileMapView::ProcessSectionFileMapView(AuUInt uAddress,
|
||||
AuUInt uLength,
|
||||
bool bShouldUnmap,
|
||||
int optFd) :
|
||||
uAddress_(uAddress),
|
||||
uLength_(uLength),
|
||||
bShouldUnmap_(bShouldUnmap),
|
||||
optFd_(optFd)
|
||||
@ -29,16 +32,24 @@ namespace Aurora::Process
|
||||
|
||||
void ProcessSectionFileMapView::Unmap()
|
||||
{
|
||||
AU_LOCK_GUARD(this->mutex_);
|
||||
|
||||
if (AuAtomicLoad(&this->uInUse_))
|
||||
{
|
||||
SysPushErrorResourceLocked("Cannot unmap memory while it's in use");
|
||||
return;
|
||||
}
|
||||
|
||||
if (AuExchange(this->bIsDead_, true))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->uAddress)
|
||||
if (this->uAddress_)
|
||||
{
|
||||
if (this->pSharedSectionHint)
|
||||
{
|
||||
AuStaticCast<ProcessSectionViewReserved>(this->pSharedSectionHint)->Release(this->uAddress);
|
||||
AuStaticCast<ProcessSectionViewReserved>(this->pSharedSectionHint)->Release(this->uAddress_);
|
||||
}
|
||||
|
||||
if (this->bShouldUnmap_)
|
||||
@ -53,9 +64,10 @@ namespace Aurora::Process
|
||||
}
|
||||
}
|
||||
|
||||
this->uAddress = 0;
|
||||
this->uAddress_ = 0;
|
||||
}
|
||||
|
||||
// TODO: posix explicitly states this isnt necessary
|
||||
int fd {-1};
|
||||
if ((fd = AuExchange(this->optFd_, -1)) != -1)
|
||||
{
|
||||
@ -63,48 +75,62 @@ namespace Aurora::Process
|
||||
}
|
||||
}
|
||||
|
||||
bool ProcessSectionFileMapView::Flush(AuUInt offset, AuUInt length)
|
||||
bool ProcessSectionFileMapView::Flush(AuUInt uOffset, AuUInt uLength)
|
||||
{
|
||||
return ::msync(this->GetPointer(offset), length, MS_SYNC) == 0;
|
||||
return ::msync(this->GetPointer(uOffset), uLength, MS_SYNC) == 0;
|
||||
}
|
||||
|
||||
AuMemoryViewWrite ProcessSectionFileMapView::ToWriteView()
|
||||
{
|
||||
return AuMemoryViewWrite((char *)this->uAddress_, this->uLength_, &this->uInUse_);
|
||||
}
|
||||
|
||||
AuMemoryViewRead ProcessSectionFileMapView::ToReadView()
|
||||
{
|
||||
return AuMemoryViewRead((char *)this->uAddress_, this->uLength_, &this->uInUse_);
|
||||
}
|
||||
|
||||
AuUInt ProcessSectionFileMapView::GetBaseAddress()
|
||||
{
|
||||
return this->uAddress;
|
||||
return this->uAddress_;
|
||||
}
|
||||
|
||||
AuUInt ProcessSectionFileMapView::GetAddress(AuUInt offset)
|
||||
AuUInt ProcessSectionFileMapView::GetAddress(AuUInt uOffset)
|
||||
{
|
||||
return this->uAddress ? this->uAddress + offset : 0;
|
||||
return this->uAddress_ && this->uLength_ > uOffset ?
|
||||
this->uAddress_ + uOffset :
|
||||
0;
|
||||
}
|
||||
|
||||
AuUInt8 *ProcessSectionFileMapView::GetBasePointer()
|
||||
{
|
||||
return AuReinterpretCast<AuUInt8 *>(this->uAddress);
|
||||
return AuReinterpretCast<AuUInt8 *>(this->uAddress_);
|
||||
}
|
||||
|
||||
AuUInt8 *ProcessSectionFileMapView::GetPointer(AuUInt offset)
|
||||
AuUInt8 *ProcessSectionFileMapView::GetPointer(AuUInt uOffset)
|
||||
{
|
||||
return this->uAddress ? AuReinterpretCast<AuUInt8 *>(this->uAddress) + offset : 0;
|
||||
return this->uAddress_ && this->uLength_ > uOffset ?
|
||||
AuReinterpretCast<AuUInt8 *>(this->uAddress_) + uOffset :
|
||||
0;
|
||||
}
|
||||
|
||||
bool ProcessSectionFileMapView::LockSwap()
|
||||
{
|
||||
if (!this->uAddress)
|
||||
if (!this->uAddress_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return AuMemory::SwapLock::Lock({ { this->uAddress, this->uLength_ } });
|
||||
return AuMemory::SwapLock::Lock({ { this->uAddress_, this->uLength_ } });
|
||||
}
|
||||
|
||||
bool ProcessSectionFileMapView::UnlockSwap()
|
||||
{
|
||||
if (!this->uAddress)
|
||||
if (!this->uAddress_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return AuMemory::SwapLock::Unlock({ { this->uAddress, this->uLength_ } });
|
||||
return AuMemory::SwapLock::Unlock({ { this->uAddress_, this->uLength_ } });
|
||||
}
|
||||
}
|
@ -18,13 +18,16 @@ namespace Aurora::Process
|
||||
|
||||
void Unmap() override;
|
||||
|
||||
bool Flush(AuUInt offset, AuUInt length) override;
|
||||
bool Flush(AuUInt uOffset, AuUInt uLength) override;
|
||||
|
||||
AuUInt GetBaseAddress() override;
|
||||
AuUInt GetAddress(AuUInt offset) override;
|
||||
AuUInt GetAddress(AuUInt uOffset) override;
|
||||
|
||||
AuUInt8 *GetBasePointer() override;
|
||||
AuUInt8 *GetPointer(AuUInt offset) override;
|
||||
AuUInt8 *GetPointer(AuUInt uOffset) override;
|
||||
|
||||
Memory::MemoryViewWrite ToWriteView() override;
|
||||
Memory::MemoryViewRead ToReadView() override;
|
||||
|
||||
AuSPtr<IProcessSectionView> pSharedSectionHint {};
|
||||
|
||||
@ -32,8 +35,10 @@ namespace Aurora::Process
|
||||
bool UnlockSwap() override;
|
||||
|
||||
private:
|
||||
AuUInt uAddress {};
|
||||
AuUInt uAddress_ {};
|
||||
AuUInt uLength_ {};
|
||||
AuMutex mutex_;
|
||||
AuAUInt32 uInUse_ {};
|
||||
bool bShouldUnmap_ {};
|
||||
int optFd_ {-1};
|
||||
bool bIsDead_ {};
|
||||
|
Loading…
Reference in New Issue
Block a user