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:
Max Kellermann
2024-11-19 11:08:29 +01:00
committed by Max Kellermann
parent 88fa68f030
commit 9a7a8ec137
2 changed files with 10 additions and 24 deletions

View File

@@ -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

View File

@@ -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;