io: always pass O_NONBLOCK to open()
Opening a FIFO may block indefinitely (until a writer connects). This is dangerous because it may be a DoS vulnerability in many programs that do not expect open() to block. This obsoletes the method FileDescriptor::OpenNonBlocking() which wasn't used anyway.
This commit is contained in:

committed by
Max Kellermann

parent
88fa68f030
commit
9a7a8ec137
@@ -24,6 +24,13 @@
|
|||||||
#define O_CLOEXEC 0
|
#define O_CLOEXEC 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* this library implies the O_NONBLOCK in all open() calls to avoid
|
||||||
|
blocking the caller when a FIFO is opened; this may not only affect
|
||||||
|
the open() call but also other operations like mandatory locking */
|
||||||
|
#ifndef O_NONBLOCK
|
||||||
|
#define O_NONBLOCK 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -61,7 +68,7 @@ bool
|
|||||||
FileDescriptor::Open(FileDescriptor dir, const char *pathname,
|
FileDescriptor::Open(FileDescriptor dir, const char *pathname,
|
||||||
int flags, mode_t mode) noexcept
|
int flags, mode_t mode) noexcept
|
||||||
{
|
{
|
||||||
fd = ::openat(dir.Get(), pathname, flags | O_NOCTTY | O_CLOEXEC, mode);
|
fd = ::openat(dir.Get(), pathname, flags | O_NOCTTY | O_CLOEXEC | O_NONBLOCK, mode);
|
||||||
return IsDefined();
|
return IsDefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +77,7 @@ FileDescriptor::Open(FileDescriptor dir, const char *pathname,
|
|||||||
bool
|
bool
|
||||||
FileDescriptor::Open(const char *pathname, int flags, mode_t mode) noexcept
|
FileDescriptor::Open(const char *pathname, int flags, mode_t mode) noexcept
|
||||||
{
|
{
|
||||||
fd = ::open(pathname, flags | O_NOCTTY | O_CLOEXEC, mode);
|
fd = ::open(pathname, flags | O_NOCTTY | O_CLOEXEC | O_NONBLOCK, mode);
|
||||||
return IsDefined();
|
return IsDefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +86,7 @@ FileDescriptor::Open(const char *pathname, int flags, mode_t mode) noexcept
|
|||||||
bool
|
bool
|
||||||
FileDescriptor::Open(const wchar_t *pathname, int flags, mode_t mode) noexcept
|
FileDescriptor::Open(const wchar_t *pathname, int flags, mode_t mode) noexcept
|
||||||
{
|
{
|
||||||
fd = ::_wopen(pathname, flags | O_NOCTTY | O_CLOEXEC, mode);
|
fd = ::_wopen(pathname, flags | O_NOCTTY | O_CLOEXEC | O_NONBLOCK, mode);
|
||||||
return IsDefined();
|
return IsDefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,20 +106,6 @@ FileDescriptor::OpenReadOnly(FileDescriptor dir, const char *pathname) noexcept
|
|||||||
return Open(dir, pathname, O_RDONLY);
|
return Open(dir, pathname, O_RDONLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __linux__
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
|
|
||||||
bool
|
|
||||||
FileDescriptor::OpenNonBlocking(const char *pathname) noexcept
|
|
||||||
{
|
|
||||||
return Open(pathname, O_RDWR | O_NONBLOCK);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
FileDescriptor::CreatePipe(FileDescriptor &r, FileDescriptor &w,
|
FileDescriptor::CreatePipe(FileDescriptor &r, FileDescriptor &w,
|
||||||
int flags) noexcept
|
int flags) noexcept
|
||||||
|
@@ -115,14 +115,7 @@ public:
|
|||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
bool OpenReadOnly(FileDescriptor dir,
|
bool OpenReadOnly(FileDescriptor dir,
|
||||||
const char *pathname) noexcept;
|
const char *pathname) noexcept;
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
[[nodiscard]]
|
|
||||||
bool OpenNonBlocking(const char *pathname) noexcept;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
static bool CreatePipe(FileDescriptor &r, FileDescriptor &w,
|
static bool CreatePipe(FileDescriptor &r, FileDescriptor &w,
|
||||||
int flags) noexcept;
|
int flags) noexcept;
|
||||||
|
Reference in New Issue
Block a user