Fix race conditions in UNIX socket listen()

This commit is contained in:
Ruihan Li 2024-08-15 13:17:36 +08:00 committed by Tate, Hongliang Tian
parent a2d94675eb
commit ac19a7e0e7
2 changed files with 14 additions and 10 deletions

View File

@ -16,9 +16,9 @@ pub(super) struct Listener {
}
impl Listener {
pub(super) fn new(addr: UnixSocketAddrBound, backlog: usize) -> Result<Self> {
let backlog = BACKLOG_TABLE.add_backlog(addr, backlog)?;
Ok(Self { backlog })
pub(super) fn new(addr: UnixSocketAddrBound, backlog: usize) -> Self {
let backlog = BACKLOG_TABLE.add_backlog(addr, backlog).unwrap();
Self { backlog }
}
pub(super) fn addr(&self) -> &UnixSocketAddrBound {
@ -78,21 +78,22 @@ impl BacklogTable {
}
}
fn add_backlog(&self, addr: UnixSocketAddrBound, backlog: usize) -> Result<Arc<Backlog>> {
fn add_backlog(&self, addr: UnixSocketAddrBound, backlog: usize) -> Option<Arc<Backlog>> {
let inode = {
let UnixSocketAddrBound::Path(_, ref dentry) = addr else {
todo!()
};
create_keyable_inode(dentry)
};
let new_backlog = Arc::new(Backlog::new(addr, backlog));
let mut backlog_sockets = self.backlog_sockets.write();
if backlog_sockets.contains_key(&inode) {
return_errno_with_message!(Errno::EADDRINUSE, "the addr is already used");
return None;
}
let new_backlog = Arc::new(Backlog::new(addr, backlog));
backlog_sockets.insert(inode, new_backlog.clone());
Ok(new_backlog)
Some(new_backlog)
}
fn get_backlog(&self, addr: &UnixSocketAddrBound) -> Result<Arc<Backlog>> {

View File

@ -232,7 +232,9 @@ impl Socket for UnixStreamSocket {
}
fn listen(&self, backlog: usize) -> Result<()> {
let addr = match &*self.state.read() {
let mut state = self.state.write();
let addr = match &*state {
State::Init(init) => init
.addr()
.ok_or(Error::with_message(
@ -248,8 +250,9 @@ impl Socket for UnixStreamSocket {
}
};
let listener = Listener::new(addr, backlog)?;
*self.state.write() = State::Listen(listener);
let listener = Listener::new(addr, backlog);
*state = State::Listen(listener);
Ok(())
}