[*] 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;
|
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)
|
MemoryView(MemoryView &&view)
|
||||||
{
|
{
|
||||||
this->ptr = view.ptr;
|
this->ptr = view.ptr;
|
||||||
@ -280,7 +306,9 @@ namespace Aurora::Memory
|
|||||||
{
|
{
|
||||||
if (uOffset < this->uLength)
|
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
|
else
|
||||||
{
|
{
|
||||||
@ -292,7 +320,9 @@ namespace Aurora::Memory
|
|||||||
{
|
{
|
||||||
if (uLength <= this->uLength)
|
if (uLength <= this->uLength)
|
||||||
{
|
{
|
||||||
return MemoryView(this->pBase, uLength, this->controlBlock);
|
return MemoryView((AuUInt8 *)this->pBase,
|
||||||
|
uLength,
|
||||||
|
this->controlBlock);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -13,13 +13,16 @@ namespace Aurora::Process
|
|||||||
{
|
{
|
||||||
virtual void Unmap() = 0;
|
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 GetBaseAddress() = 0;
|
||||||
virtual AuUInt GetAddress(AuUInt offset) = 0;
|
virtual AuUInt GetAddress(AuUInt uOffset) = 0;
|
||||||
|
|
||||||
virtual AuUInt8 *GetBasePointer() = 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 LockSwap() = 0;
|
||||||
virtual bool UnlockSwap() = 0;
|
virtual bool UnlockSwap() = 0;
|
||||||
|
@ -12,26 +12,35 @@
|
|||||||
|
|
||||||
namespace Aurora::Process
|
namespace Aurora::Process
|
||||||
{
|
{
|
||||||
|
ProcessSectionFileMapView::ProcessSectionFileMapView(AuUInt uAddress,
|
||||||
|
HANDLE hSection) :
|
||||||
|
uAddress_(uAddress),
|
||||||
|
hFileSection(hSection)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
ProcessSectionFileMapView::~ProcessSectionFileMapView()
|
ProcessSectionFileMapView::~ProcessSectionFileMapView()
|
||||||
{
|
{
|
||||||
Unmap();
|
Unmap();
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessSectionFileMapView::ProcessSectionFileMapView(AuUInt uAddress, HANDLE hSection) :
|
|
||||||
uAddress(uAddress),
|
|
||||||
hFileSection(hSection)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void 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))
|
if (AuExchange(this->bIsDead_, true))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->uAddress)
|
if (this->uAddress_)
|
||||||
{
|
{
|
||||||
if (this->pSharedSectionHint)
|
if (this->pSharedSectionHint)
|
||||||
{
|
{
|
||||||
@ -39,9 +48,9 @@ namespace Aurora::Process
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
::UnmapViewOfFile((PVOID)this->uAddress);
|
::UnmapViewOfFile((PVOID)this->uAddress_);
|
||||||
}
|
}
|
||||||
this->uAddress = 0;
|
this->uAddress_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
AuWin32CloseHandle(this->hFileSection);
|
AuWin32CloseHandle(this->hFileSection);
|
||||||
@ -49,48 +58,62 @@ namespace Aurora::Process
|
|||||||
this->pProcessGlobalHint = nullptr;
|
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()
|
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()
|
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()
|
bool ProcessSectionFileMapView::LockSwap()
|
||||||
{
|
{
|
||||||
if (!this->uAddress)
|
if (!this->uAddress_)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return AuMemory::SwapLock::Lock({ { this->uAddress, this->uLength} });
|
return AuMemory::SwapLock::Lock({ { this->uAddress_, this->uLength } });
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProcessSectionFileMapView::UnlockSwap()
|
bool ProcessSectionFileMapView::UnlockSwap()
|
||||||
{
|
{
|
||||||
if (!this->uAddress)
|
if (!this->uAddress_)
|
||||||
{
|
{
|
||||||
return false;
|
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;
|
void Unmap() override;
|
||||||
|
|
||||||
bool Flush(AuUInt offset, AuUInt length) override;
|
bool Flush(AuUInt uOffset, AuUInt uLength) override;
|
||||||
|
|
||||||
AuUInt GetBaseAddress() override;
|
AuUInt GetBaseAddress() override;
|
||||||
AuUInt GetAddress(AuUInt offset) override;
|
AuUInt GetAddress(AuUInt uOffset) override;
|
||||||
|
|
||||||
AuUInt8 *GetBasePointer() 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 LockSwap() override;
|
||||||
bool UnlockSwap() override;
|
bool UnlockSwap() override;
|
||||||
@ -36,7 +39,9 @@ namespace Aurora::Process
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
HANDLE hFileSection {};
|
HANDLE hFileSection {};
|
||||||
AuUInt uAddress {};
|
AuUInt uAddress_ {};
|
||||||
|
AuAUInt32 uInUse_ {};
|
||||||
|
AuMutex mutex_;
|
||||||
|
|
||||||
bool bIsDead_ {};
|
bool bIsDead_ {};
|
||||||
};
|
};
|
||||||
|
@ -13,8 +13,11 @@
|
|||||||
|
|
||||||
namespace Aurora::Process
|
namespace Aurora::Process
|
||||||
{
|
{
|
||||||
ProcessSectionFileMapView::ProcessSectionFileMapView(AuUInt uAddress, AuUInt uLength, bool bShouldUnmap, int optFd) :
|
ProcessSectionFileMapView::ProcessSectionFileMapView(AuUInt uAddress,
|
||||||
uAddress(uAddress),
|
AuUInt uLength,
|
||||||
|
bool bShouldUnmap,
|
||||||
|
int optFd) :
|
||||||
|
uAddress_(uAddress),
|
||||||
uLength_(uLength),
|
uLength_(uLength),
|
||||||
bShouldUnmap_(bShouldUnmap),
|
bShouldUnmap_(bShouldUnmap),
|
||||||
optFd_(optFd)
|
optFd_(optFd)
|
||||||
@ -29,16 +32,24 @@ namespace Aurora::Process
|
|||||||
|
|
||||||
void 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))
|
if (AuExchange(this->bIsDead_, true))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->uAddress)
|
if (this->uAddress_)
|
||||||
{
|
{
|
||||||
if (this->pSharedSectionHint)
|
if (this->pSharedSectionHint)
|
||||||
{
|
{
|
||||||
AuStaticCast<ProcessSectionViewReserved>(this->pSharedSectionHint)->Release(this->uAddress);
|
AuStaticCast<ProcessSectionViewReserved>(this->pSharedSectionHint)->Release(this->uAddress_);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->bShouldUnmap_)
|
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};
|
int fd {-1};
|
||||||
if ((fd = AuExchange(this->optFd_, -1)) != -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()
|
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()
|
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()
|
bool ProcessSectionFileMapView::LockSwap()
|
||||||
{
|
{
|
||||||
if (!this->uAddress)
|
if (!this->uAddress_)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return AuMemory::SwapLock::Lock({ { this->uAddress, this->uLength_ } });
|
return AuMemory::SwapLock::Lock({ { this->uAddress_, this->uLength_ } });
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProcessSectionFileMapView::UnlockSwap()
|
bool ProcessSectionFileMapView::UnlockSwap()
|
||||||
{
|
{
|
||||||
if (!this->uAddress)
|
if (!this->uAddress_)
|
||||||
{
|
{
|
||||||
return false;
|
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;
|
void Unmap() override;
|
||||||
|
|
||||||
bool Flush(AuUInt offset, AuUInt length) override;
|
bool Flush(AuUInt uOffset, AuUInt uLength) override;
|
||||||
|
|
||||||
AuUInt GetBaseAddress() override;
|
AuUInt GetBaseAddress() override;
|
||||||
AuUInt GetAddress(AuUInt offset) override;
|
AuUInt GetAddress(AuUInt uOffset) override;
|
||||||
|
|
||||||
AuUInt8 *GetBasePointer() 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 {};
|
AuSPtr<IProcessSectionView> pSharedSectionHint {};
|
||||||
|
|
||||||
@ -32,8 +35,10 @@ namespace Aurora::Process
|
|||||||
bool UnlockSwap() override;
|
bool UnlockSwap() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AuUInt uAddress {};
|
AuUInt uAddress_ {};
|
||||||
AuUInt uLength_ {};
|
AuUInt uLength_ {};
|
||||||
|
AuMutex mutex_;
|
||||||
|
AuAUInt32 uInUse_ {};
|
||||||
bool bShouldUnmap_ {};
|
bool bShouldUnmap_ {};
|
||||||
int optFd_ {-1};
|
int optFd_ {-1};
|
||||||
bool bIsDead_ {};
|
bool bIsDead_ {};
|
||||||
|
Loading…
Reference in New Issue
Block a user