summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortaylor.fish <contact@taylor.fish>2021-10-18 23:05:39 -0700
committertaylor.fish <contact@taylor.fish>2021-10-21 21:06:04 -0700
commitdc80b4cd52f7195380f9848cd780138c8a7d21f9 (patch)
treeb1c4bc150391dd35f8b8331ccfaab93b56b3d1f1 /src
parent103b29ffa7f895614ff0c2f9d26774701112f4af (diff)
downloadnix-dc80b4cd52f7195380f9848cd780138c8a7d21f9.zip
Fix unsoundness in `FdSet` methods
Ensure file descriptors are nonnegative and less than `FD_SETSIZE`. (Fixes #1572.)
Diffstat (limited to 'src')
-rw-r--r--src/sys/select.rs11
1 files changed, 11 insertions, 0 deletions
diff --git a/src/sys/select.rs b/src/sys/select.rs
index 5f3337f3..4d7576a5 100644
--- a/src/sys/select.rs
+++ b/src/sys/select.rs
@@ -1,4 +1,5 @@
//! Portably monitor a group of file descriptors for readiness.
+use std::convert::TryFrom;
use std::iter::FusedIterator;
use std::mem;
use std::ops::Range;
@@ -17,6 +18,13 @@ pub use libc::FD_SETSIZE;
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct FdSet(libc::fd_set);
+fn assert_fd_valid(fd: RawFd) {
+ assert!(
+ usize::try_from(fd).map_or(false, |fd| fd < FD_SETSIZE),
+ "fd must be in the range 0..FD_SETSIZE",
+ );
+}
+
impl FdSet {
/// Create an empty `FdSet`
pub fn new() -> FdSet {
@@ -29,16 +37,19 @@ impl FdSet {
/// Add a file descriptor to an `FdSet`
pub fn insert(&mut self, fd: RawFd) {
+ assert_fd_valid(fd);
unsafe { libc::FD_SET(fd, &mut self.0) };
}
/// Remove a file descriptor from an `FdSet`
pub fn remove(&mut self, fd: RawFd) {
+ assert_fd_valid(fd);
unsafe { libc::FD_CLR(fd, &mut self.0) };
}
/// Test an `FdSet` for the presence of a certain file descriptor.
pub fn contains(&self, fd: RawFd) -> bool {
+ assert_fd_valid(fd);
unsafe { libc::FD_ISSET(fd, &self.0) }
}