[*] Harden IPC pipes

This commit is contained in:
Reece Wilson 2023-12-16 21:08:46 +00:00
parent a932aa57d2
commit 9b99e6e7c7
5 changed files with 94 additions and 25 deletions

View File

@ -336,7 +336,7 @@ namespace Aurora::IO::FS
return false;
}
if (written != blockSize)
if (!written)
{
SysPushErrorNested("File Error: {}", path_);
break;

View File

@ -93,20 +93,37 @@ namespace Aurora::IO::IPC
if (serverHandle != INVALID_HANDLE_VALUE)
{
this->hasClient_ = Loop::NewLSEvent(false, false, true);
SysAssert(this->hasClient_);
if (!this->hasClient_)
{
this->bDead = true;
return;
}
}
this->fsHandle_ = AuIO::IOHandleShared();
SysAssert(this->fsHandle_);
if (!this->fsHandle_)
{
this->bDead = true;
return;
}
this->fsStream_ = AuMakeSharedPanic<IO::FS::NtAsyncFileStream>();
this->fsStream_ = AuMakeShared<IO::FS::NtAsyncFileStream>();
if (!this->fsStream_)
{
this->bDead = true;
return;
}
this->fsHandle_->InitFromMove((AuUInt)this->GetPipeHandle());
(void)this->fsHandle_->InitFromMove((AuUInt)this->GetPipeHandle());
AuStaticCast<AFileHandle>(this->fsHandle_)->bIsAsync = true;
AuStaticCast<AFileHandle>(this->fsHandle_)->pIPCPipe = this;
this->fsBlockingStream_ = AuFS::OpenBlockingFileStreamFromHandle(this->fsHandle_);
SysAssert(this->fsBlockingStream_);
if (!this->fsBlockingStream_)
{
this->bDead = true;
return;
}
this->fsStream_->Init(this->fsHandle_);
@ -392,6 +409,13 @@ namespace Aurora::IO::IPC
return {};
}
if (object->bDead)
{
SysPushErrorMemory();
SysPushErrorNested();
return {};
}
return object;
}
@ -442,11 +466,18 @@ namespace Aurora::IO::IPC
auto object = AuMakeShared<IPCPipeImpl>(pipe, INVALID_HANDLE_VALUE, handle);
if (!object)
{
SysPushErrorMem();
SysPushErrorMemory();
AuWin32CloseHandle(pipe);
return {};
}
if (object->bDead)
{
SysPushErrorMemory();
SysPushErrorNested();
return {};
}
return object;
}
}

View File

@ -61,6 +61,7 @@ namespace Aurora::IO::IPC
OVERLAPPED overlapped {};
HANDLE clientHandle_ {INVALID_HANDLE_VALUE};
bool bDead {};
AuSPtr<Loop::ILSEvent> hasClient_;
private:
HANDLE serverHandle_ {INVALID_HANDLE_VALUE};

View File

@ -15,8 +15,15 @@
#include <termios.h>
#include <Source/IO/AuIOHandle.hpp>
namespace Aurora::IO::FS
{
bool PosixWrite(int fd, const void *buf, AuUInt32 count, AuUInt32 *pWritten);
}
namespace Aurora::IO::IPC
{
static const AuUInt64 kFileCopyBlock = 0x4000; // 16KiB
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Pipes
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -162,19 +169,31 @@ namespace Aurora::IO::IPC
}
#endif
this->fsHandle_ = AuIO::IOHandleShared();
SysAssert(this->fsHandle_);
if (!this->fsHandle_)
{
this->bDead = true;
return;
}
this->fsStream_ = AuMakeShared<IO::FS::LinuxAsyncFileStream>();
if (!this->fsStream_)
{
this->bDead = true;
return;
}
AuStaticCast<AFileHandle>(this->fsHandle_)->pIPCPipe = this;
this->fsHandle_->InitFromPairMove(fds2[0], fds2[1]);
(void)this->fsHandle_->InitFromPairMove(fds2[0], fds2[1]);
this->fsStream_->Init(this->fsHandle_);
this->fsBlockingStream_ = AuFS::OpenBlockingFileStreamFromHandle(this->fsHandle_);
SysAssert(this->fsBlockingStream_);
if (!this->fsBlockingStream_)
{
this->bDead = true;
return;
}
}
AuSPtr<Loop::ILoopSource> IPCPipeImpl::AsReadChannelIsOpen()
@ -287,23 +306,33 @@ namespace Aurora::IO::IPC
{
::fcntl(handle, F_SETFL, control);
}
int tmp;
do
AuUInt length = read.length;
AuUInt offset {0};
while (length)
{
tmp = ::write(handle, read.ptr, read.length);
}
while ((tmp == -1 && errno == EINTR));
AuUInt32 written;
if (tmp <= 0)
{
if (tmp == 0)
int blockSize = AuMin(AuUInt(kFileCopyBlock), length);
if (!FS::PosixWrite(handle, &reinterpret_cast<const char *>(read.ptr)[offset], blockSize, &written))
{
if (!nonblock)
{
SysPushErrorNested("File Error: {}", this->pHandle_->GetPath());
}
return nonblock;
}
offset += written;
length -= written;
}
SysPushErrorMem();
return false;
if (!offset)
{
return nonblock;
}
read.outVariable = tmp;
@ -473,6 +502,11 @@ namespace Aurora::IO::IPC
return {};
}
if (object->bDead)
{
return {};
}
return handle;
}
@ -574,14 +608,17 @@ namespace Aurora::IO::IPC
return {};
}
if (object->bDead)
{
return {};
}
mutex->WaitOn(0);
if (event->IsSignaled())
{
mutex->Unlock();
SysPushErrorIO("Pipe Busy");
::close(fds[0]);
::close(fds[1]);
return {};
}

View File

@ -89,7 +89,7 @@ namespace Aurora::IO::IPC
AuUInt GetPreemptFd();
bool bIsSendingZero {};
bool bDead {};
private:
int fds[2] {-1, -1};
int secondary[2] {-1, -1};