From 569502786fee3d66ba440acfd4f7c805e1c67fb9 Mon Sep 17 00:00:00 2001 From: rupeshkoushik07 Date: Thu, 12 Sep 2024 19:56:20 +0000 Subject: [PATCH 1/4] reslove bug --- src/safeposix/syscalls/fs_calls.rs | 103 ++++++++++++++++++---------- src/safeposix/syscalls/net_calls.rs | 73 +++++++++++++++----- src/safeposix/syscalls/sys_calls.rs | 10 ++- 3 files changed, 132 insertions(+), 54 deletions(-) diff --git a/src/safeposix/syscalls/fs_calls.rs b/src/safeposix/syscalls/fs_calls.rs index beb037a21..5f948df04 100644 --- a/src/safeposix/syscalls/fs_calls.rs +++ b/src/safeposix/syscalls/fs_calls.rs @@ -1310,7 +1310,10 @@ impl Cage { pub fn fstat_syscall(&self, fd: i32, statbuf: &mut StatData) -> i32 { // Attempt to get the file descriptor - // BUG: This can panic if there is an invalid file descriptor provided + + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); // Acquire a write lock on the file descriptor to ensure exclusive access. @@ -1466,9 +1469,10 @@ impl Cage { /// refer to the statfs man page [here](https://man7.org/linux/man-pages/man2/statfs.2.html). pub fn fstatfs_syscall(&self, fd: i32, databuf: &mut FSData) -> i32 { - // BUG: If the provided file descriptor is out of bounds, get_filedescriptor - // returns Err(), unwrapping on which produces a 'panic!' - // otherwise, file descriptor table entry is stored in 'checkedfd' + + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); let unlocked_fd = checkedfd.read(); @@ -1579,6 +1583,9 @@ impl Cage { /// [read(2)](https://man7.org/linux/man-pages/man2/read.2.html) pub fn read_syscall(&self, fd: i32, buf: *mut u8, count: usize) -> i32 { // Attempt to get the file descriptor + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); // Acquire a write lock on the file descriptor to ensure exclusive access. let mut unlocked_fd = checkedfd.write(); @@ -1790,6 +1797,9 @@ impl Cage { /// [pread(2)](https://man7.org/linux/man-pages/man2/pread.2.html) pub fn pread_syscall(&self, fd: i32, buf: *mut u8, count: usize, offset: isize) -> i32 { // Attempt to get the file descriptor + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); // Acquire a write lock on the file descriptor to ensure exclusive access. let mut unlocked_fd = checkedfd.write(); @@ -2011,6 +2021,9 @@ impl Cage { //If the provided file descriptor is out of bounds, get_filedescriptor returns //Err(), unwrapping on which produces a 'panic!' //otherwise, file descriptor table entry is stored in 'checkedfd' + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); // Acquire a write lock on the file descriptor to ensure exclusive access. let mut unlocked_fd = checkedfd.write(); @@ -2242,10 +2255,10 @@ impl Cage { /// For more detailed description of all the commands and return values, see /// [pwrite(2)](https://man7.org/linux/man-pages/man2/pwrite.2.html) pub fn pwrite_syscall(&self, fd: i32, buf: *const u8, count: usize, offset: isize) -> i32 { - //BUG - //If the provided file descriptor is out of bounds, get_filedescriptor returns - //Err(), unwrapping on which produces a 'panic!' - //otherwise, file descriptor table entry is stored in 'checkedfd' + + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); // Acquire a write lock on the file descriptor to ensure exclusive access. let mut unlocked_fd = checkedfd.write(); @@ -2516,6 +2529,9 @@ impl Cage { iovec: *const interface::IovecStruct, iovcnt: i32, ) -> i32 { + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); let mut unlocked_fd = checkedfd.write(); if let Some(filedesc_enum) = &mut *unlocked_fd { @@ -2827,10 +2843,10 @@ impl Cage { /// For more detailed description of all the commands and return values, see /// [lseek(2)](https://man7.org/linux/man-pages/man2/lseek.2.html) pub fn lseek_syscall(&self, fd: i32, offset: isize, whence: i32) -> i32 { - //BUG - //If the provided file descriptor is out of bounds, get_filedescriptor returns - //Err(), unwrapping on which produces a 'panic!' - //otherwise, file descriptor table entry is stored in 'checkedfd' + + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); // Acquire a write lock on the file descriptor to ensure exclusive access. let mut unlocked_fd = checkedfd.write(); @@ -3111,10 +3127,10 @@ impl Cage { /// [fchdir(2)](https://linux.die.net/man/2/fchdir) pub fn fchdir_syscall(&self, fd: i32) -> i32 { - //BUG - //if the provided file descriptor is out of bounds, get_filedescriptor returns - //Err(), unwrapping on which produces a 'panic!' - //otherwise, file descriptor table entry is stored in 'checkedfd' + + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); let unlocked_fd = checkedfd.read(); //If a table descriptor entry corresponds to a file, we check if it is @@ -3593,10 +3609,10 @@ impl Cage { /// For more detailed description of all the commands and return values, see /// [close(2)](https://man7.org/linux/man-pages/man2/close.2.html) pub fn _close_helper_inner(&self, fd: i32) -> i32 { - //BUG - //if the provided file descriptor is out of bounds, get_filedescriptor returns - // Err(), unwrapping on which produces a 'panic!' - //otherwise, file descriptor table entry is stored in 'checkedfd' + + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); let mut unlocked_fd = checkedfd.write(); if let Some(filedesc_enum) = &mut *unlocked_fd { @@ -3828,10 +3844,10 @@ impl Cage { // Once we know that the closing of the fd was successful, // we remove the file descriptor from the fd table and free the space. // - // Bug: - // if the provided file descriptor is out of bounds, get_filedescriptor returns - // Err(), unwrapping on which produces a 'panic!' - //otherwise, file descriptor table entry is stored in 'checkedfd' + + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); let mut unlocked_fd = checkedfd.write(); // This operation effectively removes the file descriptor from the fd table @@ -3878,10 +3894,10 @@ impl Cage { /// [fcntl(2)](https://linux.die.net/man/2/fcntl) pub fn fcntl_syscall(&self, fd: i32, cmd: i32, arg: i32) -> i32 { - //BUG - //if the provided file descriptor is out of bounds, get_filedescriptor returns - // Err(), unwrapping on which produces a 'panic!' - //otherwise, file descriptor table entry is stored in 'checkedfd' + + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); let mut unlocked_fd = checkedfd.write(); if let Some(filedesc_enum) = &mut *unlocked_fd { @@ -4024,10 +4040,10 @@ impl Cage { /// devices, and possible error values, see [ioctl(2)](https://man.openbsd.org/ioctl) pub fn ioctl_syscall(&self, fd: i32, request: u32, ptrunion: IoctlPtrUnion) -> i32 { - //BUG - //if the provided file descriptor is out of bounds, 'get_filedescriptor' - // returns Err(), unwrapping on which produces a 'panic!' - //otherwise, file descriptor table entry is stored in 'checkedfd' + + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); let mut unlocked_fd = checkedfd.write(); //if a table descriptor entry is non-empty, a valid request is performed @@ -4297,10 +4313,10 @@ impl Cage { /// [fchmod(2)](https://linux.die.net/man/2/fchmod) pub fn fchmod_syscall(&self, fd: i32, mode: u32) -> i32 { - //BUG - //if the provided file descriptor is out of bounds, 'get_filedescriptor' - //returns `Err()`, unwrapping on which produces a `panic!` - //otherwise, file descriptor table entry is stored in `checkedfd` + + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); let unlocked_fd = checkedfd.read(); //if a table descriptor entry is non-empty, a valid request is performed @@ -4574,6 +4590,9 @@ impl Cage { //------------------------------------FLOCK SYSCALL------------------------------------ pub fn flock_syscall(&self, fd: i32, operation: i32) -> i32 { + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); let unlocked_fd = checkedfd.read(); if let Some(filedesc_enum) = &*unlocked_fd { @@ -5057,6 +5076,9 @@ impl Cage { //------------------------------------FSYNC SYSCALL------------------------------------ pub fn fsync_syscall(&self, fd: i32) -> i32 { + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); let mut unlocked_fd = checkedfd.write(); if let Some(filedesc_enum) = &mut *unlocked_fd { @@ -5108,6 +5130,9 @@ impl Cage { //------------------------------------FDATASYNC SYSCALL------------------------------------ pub fn fdatasync_syscall(&self, fd: i32) -> i32 { + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); let mut unlocked_fd = checkedfd.write(); if let Some(filedesc_enum) = &mut *unlocked_fd { @@ -5165,6 +5190,9 @@ impl Cage { nbytes: isize, flags: u32, ) -> i32 { + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); let mut unlocked_fd = checkedfd.write(); if let Some(filedesc_enum) = &mut *unlocked_fd { @@ -5221,6 +5249,9 @@ impl Cage { //------------------FTRUNCATE SYSCALL------------------ pub fn ftruncate_syscall(&self, fd: i32, length: isize) -> i32 { + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); let unlocked_fd = checkedfd.read(); if let Some(filedesc_enum) = &*unlocked_fd { diff --git a/src/safeposix/syscalls/net_calls.rs b/src/safeposix/syscalls/net_calls.rs index 90f738d53..795613176 100644 --- a/src/safeposix/syscalls/net_calls.rs +++ b/src/safeposix/syscalls/net_calls.rs @@ -629,6 +629,9 @@ impl Cage { prereserved: bool, ) -> i32 { //checkedfd is an atomic reference count of the number of locks on the fd + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); //returns a write lock once no other writers or readers have access to the lock let mut unlocked_fd = checkedfd.write(); @@ -877,6 +880,9 @@ impl Cage { pub fn connect_syscall(&self, fd: i32, remoteaddr: &interface::GenSockaddr) -> i32 { //If fd is out of range of [0,MAXFD], process will panic //Otherwise, we obtain a write guard to the Option object + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); let mut unlocked_fd = checkedfd.write(); //Pattern match such that FileDescriptor object must be the Socket variant @@ -1356,9 +1362,10 @@ impl Cage { if dest_addr.port() == 0 && dest_addr.addr().is_unspecified() { return self.send_syscall(fd, buf, buflen, flags); } - //BUG: - //If fd is out of range of [0,MAXFD], process will panic - //Otherwise, we obtain a write guard to the Option object + + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); let mut unlocked_fd = checkedfd.write(); //Check if the write guard holds a valid FileDescriptor @@ -1591,9 +1598,10 @@ impl Cage { /// for more detailed description of all the commands and return values, see /// [send(2)](https://linux.die.net/man/2/send) pub fn send_syscall(&self, fd: i32, buf: *const u8, buflen: usize, flags: i32) -> i32 { - //BUG: - //If fd is out of range of [0,MAXFD], process will panic - //Otherwise, we obtain a write guard to the Option object + + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); let mut unlocked_fd = checkedfd.write(); //Check if the write guard holds a valid FileDescriptor @@ -2212,9 +2220,10 @@ impl Cage { flags: i32, addr: &mut Option<&mut interface::GenSockaddr>, ) -> i32 { - //BUG: - //If fd is out of range of [0,MAXFD], process will panic - //Otherwise, we obtain a write guard to the Option object + + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); let mut unlocked_fd = checkedfd.write(); //Check if the write guard holds a valid FileDescriptor, and if so @@ -2430,9 +2439,10 @@ impl Cage { /// for more detailed description of all the commands and return values, see /// [listen(2)](https://linux.die.net/man/2/listen) pub fn listen_syscall(&self, fd: i32, backlog: i32) -> i32 { - //BUG: - //If fd is out of range of [0,MAXFD], process will panic - //Otherwise, we obtain a write guard to the Option object + + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); let mut unlocked_fd = checkedfd.write(); if let Some(filedesc_enum) = &mut *unlocked_fd { @@ -2819,6 +2829,9 @@ impl Cage { // this function is an inner function of shutdown and checks for fd pub fn _cleanup_socket(&self, fd: i32, how: i32) -> i32 { // get the file descriptor object + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); let mut unlocked_fd = checkedfd.write(); if let Some(ref mut filedesc_enum) = &mut *unlocked_fd { @@ -2915,6 +2928,9 @@ impl Cage { pub fn accept_syscall(&self, fd: i32, addr: &mut interface::GenSockaddr) -> i32 { //If fd is out of range of [0,MAXFD], process will panic //Otherwise, we obtain a write guard to the Option object + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); let mut unlocked_fd = checkedfd.write(); if let Some(filedesc_enum) = &mut *unlocked_fd { @@ -3412,7 +3428,11 @@ impl Cage { if !exceptfds_ref.is_set(fd) { continue; } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } + let checkedfd = self.get_filedescriptor(fd).unwrap(); let unlocked_fd = checkedfd.read(); if unlocked_fd.is_none() { return syscall_error(Errno::EBADF, "select", "invalid file descriptor"); @@ -3469,7 +3489,10 @@ impl Cage { // try to get the FileDescriptor Object from fd number // if the fd exists, do further processing based on the file descriptor type // otherwise, raise an error - let checkedfd = self.get_filedescriptor(fd).unwrap(); + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } + let checkedfd = self.get_filedescriptor(fd).unwrap(); let unlocked_fd = checkedfd.read(); if let Some(filedesc_enum) = &*unlocked_fd { match filedesc_enum { @@ -3628,7 +3651,10 @@ impl Cage { // try to get the FileDescriptor Object from fd number // if the fd exists, do further processing based on the file descriptor type // otherwise, raise an error - let checkedfd = self.get_filedescriptor(fd).unwrap(); + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } + let checkedfd = self.get_filedescriptor(fd).unwrap(); let unlocked_fd = checkedfd.read(); if let Some(filedesc_enum) = &*unlocked_fd { match filedesc_enum { @@ -3795,6 +3821,9 @@ impl Cage { } // try to get the file descriptor object + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); let mut unlocked_fd = checkedfd.write(); if let Some(filedesc_enum) = &mut *unlocked_fd { @@ -4011,6 +4040,9 @@ impl Cage { } // get the file descriptor object + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); let mut unlocked_fd = checkedfd.write(); if let Some(filedesc_enum) = &mut *unlocked_fd { @@ -4245,6 +4277,9 @@ impl Cage { } // get the file descriptor object + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); let unlocked_fd = checkedfd.read(); if let Some(filedesc_enum) = &*unlocked_fd { @@ -4316,6 +4351,9 @@ impl Cage { } // get the file descriptor object + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } let checkedfd = self.get_filedescriptor(fd).unwrap(); let unlocked_fd = checkedfd.read(); if let Some(filedesc_enum) = &*unlocked_fd { @@ -4751,7 +4789,10 @@ impl Cage { } // check if the other fd is an epoll or not... - let checkedfd = self.get_filedescriptor(fd).unwrap(); + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } + let checkedfd = self.get_filedescriptor(fd).unwrap(); let unlocked_fd = checkedfd.read(); if let Some(filedesc_enum) = &*unlocked_fd { match filedesc_enum { diff --git a/src/safeposix/syscalls/sys_calls.rs b/src/safeposix/syscalls/sys_calls.rs index 10be51220..f190d000c 100644 --- a/src/safeposix/syscalls/sys_calls.rs +++ b/src/safeposix/syscalls/sys_calls.rs @@ -204,7 +204,10 @@ impl Cage { let newfdtable = init_fdtable(); //Loop from 0 to maximum value of file descriptor index for fd in 0..MAXFD { - let checkedfd = self.get_filedescriptor(fd).unwrap(); + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } + let checkedfd = self.get_filedescriptor(fd).unwrap(); //Get the lock for the file descriptor let unlocked_fd = checkedfd.read(); if let Some(filedesc_enum) = &*unlocked_fd { @@ -447,7 +450,10 @@ impl Cage { let mut cloexecvec = vec![]; for fd in 0..MAXFD { // Get mutex of the file descriptor - let checkedfd = self.get_filedescriptor(fd).unwrap(); + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } + let checkedfd = self.get_filedescriptor(fd).unwrap(); let unlocked_fd = checkedfd.read(); if let Some(filedesc_enum) = &*unlocked_fd { // For each valid file descriptor we chech if the O_CLOEXEC flag is set or not From 809584fd9455a0ad9fe6c97c9f5d4c5eabfd0830 Mon Sep 17 00:00:00 2001 From: rupeshkoushik07 Date: Fri, 13 Sep 2024 11:13:27 +0000 Subject: [PATCH 2/4] update fmt --- src/safeposix/syscalls/fs_calls.rs | 108 ++++++++++++++-------------- src/safeposix/syscalls/net_calls.rs | 39 +++++----- src/safeposix/syscalls/sys_calls.rs | 10 +-- 3 files changed, 78 insertions(+), 79 deletions(-) diff --git a/src/safeposix/syscalls/fs_calls.rs b/src/safeposix/syscalls/fs_calls.rs index 5f948df04..6962ecf5f 100644 --- a/src/safeposix/syscalls/fs_calls.rs +++ b/src/safeposix/syscalls/fs_calls.rs @@ -186,13 +186,13 @@ impl Cage { if path.len() == 0 { return syscall_error(Errno::ENOENT, "open", "given path was null"); } - + // Retrieve the absolute path from the root directory. The absolute path is then // used to validate directory paths while navigating through // subdirectories and creating a new file or open existing file at the given // location. let truepath = normpath(convpath(path), self); - + // Fetch the next file descriptor and its lock write guard to ensure the file // can be associated with the file descriptor let (fd, guardopt) = self.get_next_fd(None); @@ -204,11 +204,12 @@ impl Cage { "no available file descriptor number could be found", ); } - + // When the file descriptor is valid, we proceed with performing the remaining // checks for open_syscall. - let fdoption = &mut *guardopt.unwrap_or_else(|| panic!("File descriptor couldn't be fetched!")); - + let fdoption = + &mut *guardopt.unwrap_or_else(|| panic!("File descriptor couldn't be fetched!")); + // Walk through the absolute path which returns a tuple consisting of inode // number of file (if it exists), and inode number of parent (if it exists) match metawalkandparent(truepath.as_path()) { @@ -223,13 +224,13 @@ impl Cage { "tried to open a file that did not exist, and O_CREAT was not specified", ); } - + // Error is thrown when the input flags contain S_IFCHR flag representing a // special character file. if S_IFCHR == (S_IFCHR & flags) { return syscall_error(Errno::EINVAL, "open", "Invalid value in flags"); } - + // S_FILETYPEFLAGS represents a bitmask that can be used to extract the file // type information from a file's mode. This code is // referenced from Lind-Repy codebase. Here, we are @@ -239,14 +240,14 @@ impl Cage { if mode & (S_IRWXA | S_FILETYPEFLAGS as u32) != mode { return syscall_error(Errno::EPERM, "open", "Mode bits were not sane"); } - + let filename = truepath.file_name().unwrap().to_str().unwrap().to_string(); //for now we assume this is sane, but maybe this should be checked later let time = interface::timestamp(); //We do a real timestamp now - + // S_IFREG is the flag for a regular file, so it's added to the mode to // indicate that the new file being created is a regular file. let effective_mode = S_IFREG as u32 | mode; - + // Create a new inode of type "File" representing a file and set the // required attributes let newinode = Inode::File(GenericInode { @@ -263,12 +264,12 @@ impl Cage { ctime: time, mtime: time, }); - + // Fetch the next available inode number using the FileSystem MetaData table let newinodenum = FS_METADATA .nextinode .fetch_add(1, interface::RustAtomicOrdering::Relaxed); //fetch_add returns the previous value, which is the inode number we want - + // Fetch the inode of the parent directory and only proceed when its type is // directory. if let Inode::Dir(ref mut ind) = @@ -291,7 +292,7 @@ impl Cage { FS_METADATA.inodetable.insert(newinodenum, newinode); log_metadata(&FS_METADATA, pardirinode); log_metadata(&FS_METADATA, newinodenum); - + // FileObjectTable stores the entries of the currently opened files in the // system Since, a new file is being opened here, an // entry corresponding to that newinode is made in the FileObjectTable @@ -303,13 +304,14 @@ impl Cage { vac.insert(interface::openfile(sysfilename, 0).unwrap()); // new file of size 0 } - + // The file object of size 0, associated with the newinode number is // inserted into the FileDescriptorTable associated with the cage using the // guard lock. - let _insertval = fdoption.insert(File(self._file_initializer(newinodenum, flags, 0))); + let _insertval = + fdoption.insert(File(self._file_initializer(newinodenum, flags, 0))); } - + // Case 2: When the file exists (we don't need to look at parent here) (Some(inodenum), ..) => { //If O_CREAT and O_EXCL flags are set in the input parameters, @@ -326,7 +328,7 @@ impl Cage { ); } let size; - + // Fetch the Inode Object associated with the inode number of the existing // file. There are different Inode types supported // by the open_syscall (i.e., File, Directory, Socket, CharDev). @@ -344,38 +346,40 @@ impl Cage { if let interface::RustHashEntry::Occupied(occ) = &entry { occ.get().close().unwrap(); } - + f.size = 0; - + // Update the timestamps as well let latest_time = interface::timestamp(); f.ctime = latest_time; f.mtime = latest_time; - + // Remove the previous file and add a new one of 0 length if let interface::RustHashEntry::Occupied(occ) = entry { occ.remove_entry(); } - + // The current file is removed from the filesystem let sysfilename = format!("{}{}", FILEDATAPREFIX, inodenum); interface::removefile(sysfilename.clone()).unwrap(); } - + // Once the metadata for the file is reset, a new file is inserted // in file system. Also, it is // inserted back to the FileObjectTable and associated with same // inodeNumber representing that the file is currently in open // state. - if let interface::RustHashEntry::Vacant(vac) = FILEOBJECTTABLE.entry(inodenum) { + if let interface::RustHashEntry::Vacant(vac) = + FILEOBJECTTABLE.entry(inodenum) + { let sysfilename = format!("{}{}", FILEDATAPREFIX, inodenum); vac.insert(interface::openfile(sysfilename, f.size).unwrap()); } - + // Update the final size and reference count for the file size = f.size; f.refcount += 1; - + // Current Implementation for File Truncate: The // previous entry of the file is removed from // the FileObjectTable, with a new file of size @@ -384,7 +388,7 @@ impl Cage { // the file size and pointer of the existing // file? } - + // When the existing file type is of Directory or Character Device, only // the file size and the reference count is updated. Inode::Dir(ref mut f) => { @@ -395,20 +399,21 @@ impl Cage { size = f.size; f.refcount += 1; } - + // If the existing file type is a socket, error is thrown as socket type // files are not supported by open_syscall Inode::Socket(_) => { return syscall_error(Errno::ENXIO, "open", "file is a UNIX domain socket"); } } - + // The file object of size 0, associated with the existing inode number is // inserted into the FileDescriptorTable associated with the cage using the // guard lock. - let _insertval = fdoption.insert(File(self._file_initializer(inodenum, flags, size))); + let _insertval = + fdoption.insert(File(self._file_initializer(inodenum, flags, size))); } - + // Case 3: When neither the file directory nor the parent directory exists (None, None) => { // O_CREAT flag is used to create a file if it doesn't exist. @@ -433,7 +438,6 @@ impl Cage { // Return the valid file descriptor fd } - /// ### Description /// @@ -1469,7 +1473,6 @@ impl Cage { /// refer to the statfs man page [here](https://man7.org/linux/man-pages/man2/statfs.2.html). pub fn fstatfs_syscall(&self, fd: i32, databuf: &mut FSData) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { return -1; } @@ -2021,7 +2024,7 @@ impl Cage { //If the provided file descriptor is out of bounds, get_filedescriptor returns //Err(), unwrapping on which produces a 'panic!' //otherwise, file descriptor table entry is stored in 'checkedfd' - if let Err(_) = self.get_filedescriptor(fd) { + if let Err(_) = self.get_filedescriptor(fd) { return -1; } let checkedfd = self.get_filedescriptor(fd).unwrap(); @@ -2255,7 +2258,6 @@ impl Cage { /// For more detailed description of all the commands and return values, see /// [pwrite(2)](https://man7.org/linux/man-pages/man2/pwrite.2.html) pub fn pwrite_syscall(&self, fd: i32, buf: *const u8, count: usize, offset: isize) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { return -1; } @@ -2465,7 +2467,7 @@ impl Cage { /// The function first retrieves the file descriptor object associated with /// the provided file descriptor and then matches the file descriptor /// type and calls the appropriate write function based on the type. - /// #### Sockets: + /// #### Sockets: /// The function writes data to the connected socket, handling /// both TCP and UDP sockets. /// * Checks if the socket is connected (either fully connected or @@ -2473,7 +2475,7 @@ impl Cage { /// * If connected, calls the underlying `writev` function on the raw /// socket. /// * Handles errors returned by the underlying `writev` function. - /// #### Pipes: + /// #### Pipes: /// The function writes data to the pipe, supporting non-blocking /// writes. /// * Checks if the pipe is open for writing. @@ -2482,19 +2484,23 @@ impl Cage { /// /// #### Streams: /// The function supports logging data written to a stream. - /// * Concatenates the multiple buffers (`iovec`) into a single contiguous slice. + /// * Concatenates the multiple buffers (`iovec`) into a single contiguous + /// slice. /// * Calls `log_from_slice` to write the data and logs the result. /// * Returns the number of bytes successfully written. /// /// #### Files: /// The function writes data to regular files using vectored I/O. /// * Checks if the file is open for writing. - /// * Retrieves the associated inode and ensures the write position is valid. - /// * Handles writing past the end of the file by padding with blank bytes if necessary. + /// * Retrieves the associated inode and ensures the write position is + /// valid. + /// * Handles writing past the end of the file by padding with blank bytes + /// if necessary. /// * Updates the file size if the write extends the file. - /// * Writes data using the vectored I/O method and returns the number of bytes written. + /// * Writes data using the vectored I/O method and returns the number of + /// bytes written. /// * Triggers `EISDIR` if an attempt is made to write to a directory. - /// + /// /// ### Function Arguments /// * `fd`: The file descriptor to write to. /// * `iovec`: A pointer to an array of `IovecStruct` objects representing @@ -2516,8 +2522,9 @@ impl Cage { /// socket protocol. /// * `EAGAIN(11)`: There is no data available right now (for pipes). /// * `EPIPE(32)`: The pipe has been closed on the other end (for pipes). - /// * `EISDIR(21)`: The target file descriptor points to a directory (for files). - /// + /// * `EISDIR(21)`: The target file descriptor points to a directory (for + /// files). + /// /// ### Panics /// * If an unknown error code is returned by the underlying socket writev /// * If the inode number does not exist in the file system metadata table. @@ -2703,11 +2710,12 @@ impl Cage { Inode::File(ref mut normalfile_inode_obj) => { // The inode object retrieved is of type File. We get a mutable // reference to the actual inode data. - let position = normalfile_filedesc_obj.position; + let position = normalfile_filedesc_obj.position; // Get the current write position from the file descriptor object let filesize = normalfile_inode_obj.size; // Get the file size - let blankbytecount = position as isize - filesize as isize; - // Calculate the difference between the required and desired file position + let blankbytecount = position as isize - filesize as isize; + // Calculate the difference between the required and desired file + // position // Retrieve the file object from the file object table let mut fileobject = FILEOBJECTTABLE @@ -2843,7 +2851,6 @@ impl Cage { /// For more detailed description of all the commands and return values, see /// [lseek(2)](https://man7.org/linux/man-pages/man2/lseek.2.html) pub fn lseek_syscall(&self, fd: i32, offset: isize, whence: i32) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { return -1; } @@ -3127,7 +3134,6 @@ impl Cage { /// [fchdir(2)](https://linux.die.net/man/2/fchdir) pub fn fchdir_syscall(&self, fd: i32) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { return -1; } @@ -3609,7 +3615,6 @@ impl Cage { /// For more detailed description of all the commands and return values, see /// [close(2)](https://man7.org/linux/man-pages/man2/close.2.html) pub fn _close_helper_inner(&self, fd: i32) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { return -1; } @@ -3894,7 +3899,6 @@ impl Cage { /// [fcntl(2)](https://linux.die.net/man/2/fcntl) pub fn fcntl_syscall(&self, fd: i32, cmd: i32, arg: i32) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { return -1; } @@ -4040,7 +4044,6 @@ impl Cage { /// devices, and possible error values, see [ioctl(2)](https://man.openbsd.org/ioctl) pub fn ioctl_syscall(&self, fd: i32, request: u32, ptrunion: IoctlPtrUnion) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { return -1; } @@ -4313,7 +4316,6 @@ impl Cage { /// [fchmod(2)](https://linux.die.net/man/2/fchmod) pub fn fchmod_syscall(&self, fd: i32, mode: u32) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { return -1; } @@ -5076,7 +5078,7 @@ impl Cage { //------------------------------------FSYNC SYSCALL------------------------------------ pub fn fsync_syscall(&self, fd: i32) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { + if let Err(_) = self.get_filedescriptor(fd) { return -1; } let checkedfd = self.get_filedescriptor(fd).unwrap(); diff --git a/src/safeposix/syscalls/net_calls.rs b/src/safeposix/syscalls/net_calls.rs index 795613176..9754631f0 100644 --- a/src/safeposix/syscalls/net_calls.rs +++ b/src/safeposix/syscalls/net_calls.rs @@ -1598,7 +1598,6 @@ impl Cage { /// for more detailed description of all the commands and return values, see /// [send(2)](https://linux.die.net/man/2/send) pub fn send_syscall(&self, fd: i32, buf: *const u8, buflen: usize, flags: i32) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { return -1; } @@ -2220,7 +2219,6 @@ impl Cage { flags: i32, addr: &mut Option<&mut interface::GenSockaddr>, ) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { return -1; } @@ -2439,7 +2437,6 @@ impl Cage { /// for more detailed description of all the commands and return values, see /// [listen(2)](https://linux.die.net/man/2/listen) pub fn listen_syscall(&self, fd: i32, backlog: i32) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { return -1; } @@ -3428,11 +3425,11 @@ impl Cage { if !exceptfds_ref.is_set(fd) { continue; } - - if let Err(_) = self.get_filedescriptor(fd) { - return -1; - } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } + let checkedfd = self.get_filedescriptor(fd).unwrap(); let unlocked_fd = checkedfd.read(); if unlocked_fd.is_none() { return syscall_error(Errno::EBADF, "select", "invalid file descriptor"); @@ -3489,10 +3486,10 @@ impl Cage { // try to get the FileDescriptor Object from fd number // if the fd exists, do further processing based on the file descriptor type // otherwise, raise an error - if let Err(_) = self.get_filedescriptor(fd) { - return -1; - } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } + let checkedfd = self.get_filedescriptor(fd).unwrap(); let unlocked_fd = checkedfd.read(); if let Some(filedesc_enum) = &*unlocked_fd { match filedesc_enum { @@ -3651,10 +3648,10 @@ impl Cage { // try to get the FileDescriptor Object from fd number // if the fd exists, do further processing based on the file descriptor type // otherwise, raise an error - if let Err(_) = self.get_filedescriptor(fd) { - return -1; - } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } + let checkedfd = self.get_filedescriptor(fd).unwrap(); let unlocked_fd = checkedfd.read(); if let Some(filedesc_enum) = &*unlocked_fd { match filedesc_enum { @@ -4277,7 +4274,7 @@ impl Cage { } // get the file descriptor object - if let Err(_) = self.get_filedescriptor(fd) { + if let Err(_) = self.get_filedescriptor(fd) { return -1; } let checkedfd = self.get_filedescriptor(fd).unwrap(); @@ -4789,10 +4786,10 @@ impl Cage { } // check if the other fd is an epoll or not... - if let Err(_) = self.get_filedescriptor(fd) { - return -1; - } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } + let checkedfd = self.get_filedescriptor(fd).unwrap(); let unlocked_fd = checkedfd.read(); if let Some(filedesc_enum) = &*unlocked_fd { match filedesc_enum { diff --git a/src/safeposix/syscalls/sys_calls.rs b/src/safeposix/syscalls/sys_calls.rs index f190d000c..967367e2f 100644 --- a/src/safeposix/syscalls/sys_calls.rs +++ b/src/safeposix/syscalls/sys_calls.rs @@ -204,10 +204,10 @@ impl Cage { let newfdtable = init_fdtable(); //Loop from 0 to maximum value of file descriptor index for fd in 0..MAXFD { - if let Err(_) = self.get_filedescriptor(fd) { - return -1; - } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + if let Err(_) = self.get_filedescriptor(fd) { + return -1; + } + let checkedfd = self.get_filedescriptor(fd).unwrap(); //Get the lock for the file descriptor let unlocked_fd = checkedfd.read(); if let Some(filedesc_enum) = &*unlocked_fd { @@ -453,7 +453,7 @@ impl Cage { if let Err(_) = self.get_filedescriptor(fd) { return -1; } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = self.get_filedescriptor(fd).unwrap(); let unlocked_fd = checkedfd.read(); if let Some(filedesc_enum) = &*unlocked_fd { // For each valid file descriptor we chech if the O_CLOEXEC flag is set or not From f7dc352235822862a39d9ff2cc823679128c2d2c Mon Sep 17 00:00:00 2001 From: rupeshkoushik07 Date: Tue, 24 Sep 2024 13:42:59 +0000 Subject: [PATCH 3/4] update fd check --- src/safeposix/syscalls/fs_calls.rs | 133 ++++++++++++++++------------ src/safeposix/syscalls/net_calls.rs | 84 ++++++++++-------- src/safeposix/syscalls/sys_calls.rs | 14 +-- 3 files changed, 132 insertions(+), 99 deletions(-) diff --git a/src/safeposix/syscalls/fs_calls.rs b/src/safeposix/syscalls/fs_calls.rs index 6962ecf5f..3587e3a37 100644 --- a/src/safeposix/syscalls/fs_calls.rs +++ b/src/safeposix/syscalls/fs_calls.rs @@ -1315,10 +1315,11 @@ impl Cage { pub fn fstat_syscall(&self, fd: i32, statbuf: &mut StatData) -> i32 { // Attempt to get the file descriptor - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "fstat_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); // Acquire a write lock on the file descriptor to ensure exclusive access. let unlocked_fd = checkedfd.read(); @@ -1473,10 +1474,11 @@ impl Cage { /// refer to the statfs man page [here](https://man7.org/linux/man-pages/man2/statfs.2.html). pub fn fstatfs_syscall(&self, fd: i32, databuf: &mut FSData) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "fstatfs_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let unlocked_fd = checkedfd.read(); if let Some(filedesc_enum) = &*unlocked_fd { @@ -1586,10 +1588,11 @@ impl Cage { /// [read(2)](https://man7.org/linux/man-pages/man2/read.2.html) pub fn read_syscall(&self, fd: i32, buf: *mut u8, count: usize) -> i32 { // Attempt to get the file descriptor - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "read_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); // Acquire a write lock on the file descriptor to ensure exclusive access. let mut unlocked_fd = checkedfd.write(); @@ -1800,10 +1803,11 @@ impl Cage { /// [pread(2)](https://man7.org/linux/man-pages/man2/pread.2.html) pub fn pread_syscall(&self, fd: i32, buf: *mut u8, count: usize, offset: isize) -> i32 { // Attempt to get the file descriptor - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "pread_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); // Acquire a write lock on the file descriptor to ensure exclusive access. let mut unlocked_fd = checkedfd.write(); @@ -2024,10 +2028,11 @@ impl Cage { //If the provided file descriptor is out of bounds, get_filedescriptor returns //Err(), unwrapping on which produces a 'panic!' //otherwise, file descriptor table entry is stored in 'checkedfd' - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "write_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); // Acquire a write lock on the file descriptor to ensure exclusive access. let mut unlocked_fd = checkedfd.write(); @@ -2258,10 +2263,11 @@ impl Cage { /// For more detailed description of all the commands and return values, see /// [pwrite(2)](https://man7.org/linux/man-pages/man2/pwrite.2.html) pub fn pwrite_syscall(&self, fd: i32, buf: *const u8, count: usize, offset: isize) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "pwrite_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); // Acquire a write lock on the file descriptor to ensure exclusive access. let mut unlocked_fd = checkedfd.write(); @@ -2536,10 +2542,11 @@ impl Cage { iovec: *const interface::IovecStruct, iovcnt: i32, ) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "writev_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let mut unlocked_fd = checkedfd.write(); if let Some(filedesc_enum) = &mut *unlocked_fd { // we're only implementing this for INET/tcp sockets right now @@ -2851,10 +2858,11 @@ impl Cage { /// For more detailed description of all the commands and return values, see /// [lseek(2)](https://man7.org/linux/man-pages/man2/lseek.2.html) pub fn lseek_syscall(&self, fd: i32, offset: isize, whence: i32) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "lseek_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); // Acquire a write lock on the file descriptor to ensure exclusive access. let mut unlocked_fd = checkedfd.write(); @@ -3134,10 +3142,11 @@ impl Cage { /// [fchdir(2)](https://linux.die.net/man/2/fchdir) pub fn fchdir_syscall(&self, fd: i32) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "fchdir_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let unlocked_fd = checkedfd.read(); //If a table descriptor entry corresponds to a file, we check if it is //a directory file type. If it is not, we return `A component of path is @@ -3615,10 +3624,11 @@ impl Cage { /// For more detailed description of all the commands and return values, see /// [close(2)](https://man7.org/linux/man-pages/man2/close.2.html) pub fn _close_helper_inner(&self, fd: i32) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "close_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let mut unlocked_fd = checkedfd.write(); if let Some(filedesc_enum) = &mut *unlocked_fd { // We decide, how to proceed depending on the fd type. @@ -3850,10 +3860,11 @@ impl Cage { // we remove the file descriptor from the fd table and free the space. // - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "close_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let mut unlocked_fd = checkedfd.write(); // This operation effectively removes the file descriptor from the fd table // by removing its reference from the variable and then not using it further, @@ -3899,10 +3910,11 @@ impl Cage { /// [fcntl(2)](https://linux.die.net/man/2/fcntl) pub fn fcntl_syscall(&self, fd: i32, cmd: i32, arg: i32) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "fcntl_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let mut unlocked_fd = checkedfd.write(); if let Some(filedesc_enum) = &mut *unlocked_fd { //'flags' consists of bitwise-or'd access mode, file creation, and file status flags @@ -4044,10 +4056,11 @@ impl Cage { /// devices, and possible error values, see [ioctl(2)](https://man.openbsd.org/ioctl) pub fn ioctl_syscall(&self, fd: i32, request: u32, ptrunion: IoctlPtrUnion) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "ioctl_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let mut unlocked_fd = checkedfd.write(); //if a table descriptor entry is non-empty, a valid request is performed if let Some(filedesc_enum) = &mut *unlocked_fd { @@ -4316,10 +4329,11 @@ impl Cage { /// [fchmod(2)](https://linux.die.net/man/2/fchmod) pub fn fchmod_syscall(&self, fd: i32, mode: u32) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "fchmod_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let unlocked_fd = checkedfd.read(); //if a table descriptor entry is non-empty, a valid request is performed if let Some(filedesc_enum) = &*unlocked_fd { @@ -4592,10 +4606,11 @@ impl Cage { //------------------------------------FLOCK SYSCALL------------------------------------ pub fn flock_syscall(&self, fd: i32, operation: i32) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "flock_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let unlocked_fd = checkedfd.read(); if let Some(filedesc_enum) = &*unlocked_fd { let lock = match filedesc_enum { @@ -5078,10 +5093,11 @@ impl Cage { //------------------------------------FSYNC SYSCALL------------------------------------ pub fn fsync_syscall(&self, fd: i32) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "fsync_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let mut unlocked_fd = checkedfd.write(); if let Some(filedesc_enum) = &mut *unlocked_fd { match filedesc_enum { @@ -5132,10 +5148,11 @@ impl Cage { //------------------------------------FDATASYNC SYSCALL------------------------------------ pub fn fdatasync_syscall(&self, fd: i32) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "fdatasync_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let mut unlocked_fd = checkedfd.write(); if let Some(filedesc_enum) = &mut *unlocked_fd { match filedesc_enum { @@ -5192,10 +5209,11 @@ impl Cage { nbytes: isize, flags: u32, ) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "sync_file_range_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let mut unlocked_fd = checkedfd.write(); if let Some(filedesc_enum) = &mut *unlocked_fd { match filedesc_enum { @@ -5251,10 +5269,11 @@ impl Cage { //------------------FTRUNCATE SYSCALL------------------ pub fn ftruncate_syscall(&self, fd: i32, length: isize) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "ftruncate_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let unlocked_fd = checkedfd.read(); if let Some(filedesc_enum) = &*unlocked_fd { match filedesc_enum { diff --git a/src/safeposix/syscalls/net_calls.rs b/src/safeposix/syscalls/net_calls.rs index 9754631f0..cf04c22d7 100644 --- a/src/safeposix/syscalls/net_calls.rs +++ b/src/safeposix/syscalls/net_calls.rs @@ -629,10 +629,11 @@ impl Cage { prereserved: bool, ) -> i32 { //checkedfd is an atomic reference count of the number of locks on the fd - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "bind_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); //returns a write lock once no other writers or readers have access to the lock let mut unlocked_fd = checkedfd.write(); if let Some(filedesc_enum) = &mut *unlocked_fd { @@ -880,10 +881,11 @@ impl Cage { pub fn connect_syscall(&self, fd: i32, remoteaddr: &interface::GenSockaddr) -> i32 { //If fd is out of range of [0,MAXFD], process will panic //Otherwise, we obtain a write guard to the Option object - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "connect_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let mut unlocked_fd = checkedfd.write(); //Pattern match such that FileDescriptor object must be the Socket variant //Otherwise, return with an err as the fd refers to something other than a @@ -1363,10 +1365,11 @@ impl Cage { return self.send_syscall(fd, buf, buflen, flags); } - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "sendto_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let mut unlocked_fd = checkedfd.write(); //Check if the write guard holds a valid FileDescriptor if let Some(filedesc_enum) = &mut *unlocked_fd { @@ -1598,10 +1601,11 @@ impl Cage { /// for more detailed description of all the commands and return values, see /// [send(2)](https://linux.die.net/man/2/send) pub fn send_syscall(&self, fd: i32, buf: *const u8, buflen: usize, flags: i32) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "send_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let mut unlocked_fd = checkedfd.write(); //Check if the write guard holds a valid FileDescriptor if let Some(filedesc_enum) = &mut *unlocked_fd { @@ -2219,10 +2223,11 @@ impl Cage { flags: i32, addr: &mut Option<&mut interface::GenSockaddr>, ) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "recv_common", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let mut unlocked_fd = checkedfd.write(); //Check if the write guard holds a valid FileDescriptor, and if so //call recv_common_inner. @@ -2437,10 +2442,11 @@ impl Cage { /// for more detailed description of all the commands and return values, see /// [listen(2)](https://linux.die.net/man/2/listen) pub fn listen_syscall(&self, fd: i32, backlog: i32) -> i32 { - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "listen_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let mut unlocked_fd = checkedfd.write(); if let Some(filedesc_enum) = &mut *unlocked_fd { match filedesc_enum { @@ -2826,10 +2832,11 @@ impl Cage { // this function is an inner function of shutdown and checks for fd pub fn _cleanup_socket(&self, fd: i32, how: i32) -> i32 { // get the file descriptor object - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "netshutdown_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let mut unlocked_fd = checkedfd.write(); if let Some(ref mut filedesc_enum) = &mut *unlocked_fd { let inner_result = self._cleanup_socket_inner(filedesc_enum, how, true); @@ -2925,10 +2932,11 @@ impl Cage { pub fn accept_syscall(&self, fd: i32, addr: &mut interface::GenSockaddr) -> i32 { //If fd is out of range of [0,MAXFD], process will panic //Otherwise, we obtain a write guard to the Option object - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "accept_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let mut unlocked_fd = checkedfd.write(); if let Some(filedesc_enum) = &mut *unlocked_fd { //Find the next available file descriptor and grab a mutable reference @@ -3818,10 +3826,11 @@ impl Cage { } // try to get the file descriptor object - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "getsockopt_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let mut unlocked_fd = checkedfd.write(); if let Some(filedesc_enum) = &mut *unlocked_fd { if let Socket(ref mut sockfdobj) = filedesc_enum { @@ -4037,10 +4046,11 @@ impl Cage { } // get the file descriptor object - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "setsockopt_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let mut unlocked_fd = checkedfd.write(); if let Some(filedesc_enum) = &mut *unlocked_fd { if let Socket(ref mut sockfdobj) = filedesc_enum { @@ -4274,10 +4284,11 @@ impl Cage { } // get the file descriptor object - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "getpeername_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let unlocked_fd = checkedfd.read(); if let Some(filedesc_enum) = &*unlocked_fd { if let Socket(sockfdobj) = filedesc_enum { @@ -4348,10 +4359,11 @@ impl Cage { } // get the file descriptor object - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "getsockname_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let unlocked_fd = checkedfd.read(); if let Some(filedesc_enum) = &*unlocked_fd { if let Socket(sockfdobj) = filedesc_enum { diff --git a/src/safeposix/syscalls/sys_calls.rs b/src/safeposix/syscalls/sys_calls.rs index 967367e2f..4794fc38c 100644 --- a/src/safeposix/syscalls/sys_calls.rs +++ b/src/safeposix/syscalls/sys_calls.rs @@ -204,10 +204,11 @@ impl Cage { let newfdtable = init_fdtable(); //Loop from 0 to maximum value of file descriptor index for fd in 0..MAXFD { - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "fork_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); //Get the lock for the file descriptor let unlocked_fd = checkedfd.read(); if let Some(filedesc_enum) = &*unlocked_fd { @@ -450,10 +451,11 @@ impl Cage { let mut cloexecvec = vec![]; for fd in 0..MAXFD { // Get mutex of the file descriptor - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "exec_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let unlocked_fd = checkedfd.read(); if let Some(filedesc_enum) = &*unlocked_fd { // For each valid file descriptor we chech if the O_CLOEXEC flag is set or not From e3679fb59cbde7d86aa6f66652e2d271cc9c0361 Mon Sep 17 00:00:00 2001 From: rupeshkoushik07 Date: Tue, 24 Sep 2024 13:48:38 +0000 Subject: [PATCH 4/4] update net_calls --- src/safeposix/syscalls/net_calls.rs | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/safeposix/syscalls/net_calls.rs b/src/safeposix/syscalls/net_calls.rs index cf04c22d7..7e4a9d83f 100644 --- a/src/safeposix/syscalls/net_calls.rs +++ b/src/safeposix/syscalls/net_calls.rs @@ -3433,11 +3433,11 @@ impl Cage { if !exceptfds_ref.is_set(fd) { continue; } - - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "select_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let unlocked_fd = checkedfd.read(); if unlocked_fd.is_none() { return syscall_error(Errno::EBADF, "select", "invalid file descriptor"); @@ -3494,10 +3494,11 @@ impl Cage { // try to get the FileDescriptor Object from fd number // if the fd exists, do further processing based on the file descriptor type // otherwise, raise an error - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "select_readfds", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let unlocked_fd = checkedfd.read(); if let Some(filedesc_enum) = &*unlocked_fd { match filedesc_enum { @@ -3656,10 +3657,11 @@ impl Cage { // try to get the FileDescriptor Object from fd number // if the fd exists, do further processing based on the file descriptor type // otherwise, raise an error - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "select_writefds", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let unlocked_fd = checkedfd.read(); if let Some(filedesc_enum) = &*unlocked_fd { match filedesc_enum { @@ -4798,10 +4800,11 @@ impl Cage { } // check if the other fd is an epoll or not... - if let Err(_) = self.get_filedescriptor(fd) { - return -1; + let fdres = self.get_filedescriptor(fd); + if fdres.is_err() { + return syscall_error(Errno::EBADF, "epoll_ctl_syscall", "invalid file descriptor"); } - let checkedfd = self.get_filedescriptor(fd).unwrap(); + let checkedfd = fdres.unwrap(); let unlocked_fd = checkedfd.read(); if let Some(filedesc_enum) = &*unlocked_fd { match filedesc_enum {