Skip to content

Commit

Permalink
io: always pass O_NONBLOCK to open()
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
MaxKellermann committed Jan 1, 2025
1 parent 2114449 commit 14e1337
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 24 deletions.
27 changes: 10 additions & 17 deletions src/io/FileDescriptor.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@
#define O_CLOEXEC 0
#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

bool
Expand Down Expand Up @@ -61,7 +68,7 @@ bool
FileDescriptor::Open(FileDescriptor dir, const char *pathname,
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();
}

Expand All @@ -70,7 +77,7 @@ FileDescriptor::Open(FileDescriptor dir, const char *pathname,
bool
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();
}

Expand All @@ -79,7 +86,7 @@ FileDescriptor::Open(const char *pathname, int flags, mode_t mode) noexcept
bool
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();
}

Expand All @@ -99,20 +106,6 @@ FileDescriptor::OpenReadOnly(FileDescriptor dir, const char *pathname) noexcept
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
FileDescriptor::CreatePipe(FileDescriptor &r, FileDescriptor &w,
int flags) noexcept
Expand Down
7 changes: 0 additions & 7 deletions src/io/FileDescriptor.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,7 @@ public:
[[nodiscard]]
bool OpenReadOnly(FileDescriptor dir,
const char *pathname) noexcept;
#endif

#ifndef _WIN32
[[nodiscard]]
bool OpenNonBlocking(const char *pathname) noexcept;
#endif

#ifdef __linux__
[[nodiscard]]
static bool CreatePipe(FileDescriptor &r, FileDescriptor &w,
int flags) noexcept;
Expand Down

0 comments on commit 14e1337

Please sign in to comment.