Skip to content

Commit f131ebc

Browse files
author
lind
committed
formatted
2 parents c9fdff1 + 232e99d commit f131ebc

File tree

2 files changed

+126
-18
lines changed

2 files changed

+126
-18
lines changed

src/safeposix/syscalls/net_calls.rs

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,54 @@ impl Cage {
152152
0
153153
}
154154

155+
/// ## `socket_syscall`
156+
///
157+
/// ### Description
158+
/// This function creates a new socket, ensuring the requested domain, socket type,
159+
/// and protocol are supported by SafePosix.
160+
/// It validates the requested communication domain, socket type, and protocol, permitting only combinations that are known
161+
/// to be safe and secure.
162+
///
163+
/// ### Function Arguments
164+
/// * `domain`: The communication domain for the socket. Supported values are
165+
/// `PF_INET` (Internet Protocol) and `PF_UNIX` (Unix domain sockets).
166+
/// * `socktype`: The socket type. Supported values are `SOCK_STREAM` (stream sockets) and `SOCK_DGRAM` (datagram sockets).
167+
/// * `protocol`: The protocol to use for communication. This defaults to TCP for stream sockets
168+
/// (`SOCK_STREAM`) and UDP for datagram sockets (`SOCK_DGRAM`).
169+
///
170+
/// ### Returns
171+
/// * The new file descriptor representing the socket on success.
172+
///
173+
/// ### Errors
174+
/// * `EOPNOTSUPP(95)`: If an unsupported combination of domain, socket type, or protocol is requested.
175+
/// * `EINVAL(22)`: If an invalid combination of flags is provided.
176+
/// ### Panics
177+
/// There are no panics in this syscall.
155178
pub fn socket_syscall(&self, domain: i32, socktype: i32, protocol: i32) -> i32 {
156179
let real_socktype = socktype & 0x7; //get the type without the extra flags, it's stored in the last 3 bits
157-
let nonblocking = (socktype & SOCK_NONBLOCK) != 0;
180+
let nonblocking = (socktype & SOCK_NONBLOCK) != 0; // Checks if the socket should be non-blocking.
181+
//Check blocking status for storage in the file descriptor, we'll need this for calls that don't access the kernel
182+
//socket, unix sockets, and properly directing kernel calls for recv and accept
158183
let cloexec = (socktype & SOCK_CLOEXEC) != 0;
159-
160-
match real_socktype {
184+
// Checks if the 'close-on-exec' flag is set. This flag ensures the socket is automatically closed if the current
185+
// process executes another program, preventing unintended inheritance of the socket by the new program.
186+
187+
// additional flags are not supported
188+
// filtering out any socktypes with unexpected flags set.
189+
// This is important as we dont want to pass down any flags that are not supported by SafePOSIX.
190+
// which may potentially cause issues with the underlying libc call. or the socket creation process.
191+
// leading to unexpected behavior.
192+
if socktype & !(SOCK_NONBLOCK | SOCK_CLOEXEC | 0x7) != 0 {
193+
return syscall_error(
194+
Errno::EOPNOTSUPP,
195+
"socket",
196+
"Invalid combination of flags"
197+
);
198+
}
199+
//SafePOSIX intentionally supports only a restricted subset of socket types . This is to make sure that
200+
// applications not creating other socket types which may lead to security issues.
201+
//By using the match statement, SafePOSIX ensures that only these approved socket types are allowed.
202+
match real_socktype {// Handles different socket types SOCK_STREAM or SOCK_DGRAM in this cases
161203
SOCK_STREAM => {
162204
//SOCK_STREAM defaults to TCP for protocol, otherwise protocol is unsupported
163205
let newprotocol = if protocol == 0 { IPPROTO_TCP } else { protocol };
@@ -169,8 +211,10 @@ impl Cage {
169211
"The only SOCK_STREAM implemented is TCP. Unknown protocol input.",
170212
);
171213
}
172-
match domain {
173-
PF_INET | PF_UNIX => {
214+
match domain {// Handles different communication domains in this case PF_INET/PF_UNIX
215+
PF_INET | PF_UNIX => {// Internet Protocol (PF_INET) and Unix Domain Sockets (PF_UNIX)
216+
//PR_INET / AF_INET and PF_UNIX / AF_UNIX are the same
217+
//https://man7.org/linux/man-pages/man2/socket.2.html
174218
let sockfdobj = self._socket_initializer(
175219
domain,
176220
socktype,
@@ -179,14 +223,18 @@ impl Cage {
179223
cloexec,
180224
ConnState::NOTCONNECTED,
181225
);
226+
// Creates a SafePOSIX socket descriptor using '_socket_initializer', a helper function
227+
// that encapsulates the internal details of socket creation and initialization.
182228
return self._socket_inserter(Socket(sockfdobj));
229+
// Inserts the newly created socket descriptor into the cage's file descriptor table,
230+
// making it accessible to the application.Returns the file descriptor representing the socket.
183231
}
184232
_ => {
185233
return syscall_error(
186234
Errno::EOPNOTSUPP,
187235
"socket",
188236
"trying to use an unimplemented domain",
189-
);
237+
);// Returns an error if an unsupported domain is requested.
190238
}
191239
}
192240
}
@@ -202,8 +250,13 @@ impl Cage {
202250
"The only SOCK_DGRAM implemented is UDP. Unknown protocol input.",
203251
);
204252
}
205-
match domain {
206-
PF_INET | PF_UNIX => {
253+
// SafePOSIX intentionally supports only a restricted subset of socket types . This is to make sure
254+
// that applications not creating other socket types which may lead to security issues.
255+
//By using the match statement, SafePOSIX ensures that only these approved socket types are allowed.
256+
match domain {// Handles different communication domains in this case PF_INET/PF_UNIX
257+
PF_INET | PF_UNIX => {// Internet Protocol (PF_INET) and Unix Domain Sockets (PF_UNIX)
258+
//PR_INET / AF_INET and PF_UNIX / AF_UNIX are the same
259+
//https://man7.org/linux/man-pages/man2/socket.2.html
207260
let sockfdobj = self._socket_initializer(
208261
domain,
209262
socktype,
@@ -212,7 +265,11 @@ impl Cage {
212265
cloexec,
213266
ConnState::NOTCONNECTED,
214267
);
268+
// Creates a SafePOSIX socket descriptor using '_socket_initializer', a helper
269+
// function that encapsulates the internal details of socket creation and initialization.
215270
return self._socket_inserter(Socket(sockfdobj));
271+
// Inserts the newly created socket descriptor into the cage's file descriptor table,making it accessible to the application.
272+
// Returns the file descriptor (an integer) representing the socket.
216273
}
217274
_ => {
218275
return syscall_error(
@@ -229,7 +286,7 @@ impl Cage {
229286
Errno::EOPNOTSUPP,
230287
"socket",
231288
"trying to use an unimplemented socket type",
232-
);
289+
);// Returns an error if an unsupported domain is requested.
233290
}
234291
}
235292
}

src/tests/networking_tests.rs

Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1921,27 +1921,78 @@ pub mod net_tests {
19211921

19221922
let cage = interface::cagetable_getref(1);
19231923

1924+
// Following checks are inplace to ensure that the socket types are correctly defined
1925+
// and that the assumptions about the values of the socket types are correct across platforms.
1926+
// Check that SOCK_STREAM only uses the lowest 3 bits
1927+
assert_eq!(SOCK_STREAM & !0x7, 0);
1928+
1929+
// Check that SOCK_DGRAM only uses the lowest 3 bits
1930+
assert_eq!(SOCK_DGRAM & !0x7, 0);
1931+
1932+
// Check that SOCK_NONBLOCK does not use the lowest 3 bits
1933+
assert_eq!(SOCK_NONBLOCK & 0x7, 0);
1934+
1935+
// Check that SOCK_CLOEXEC does not use the lowest 3 bits
1936+
assert_eq!(SOCK_CLOEXEC & 0x7, 0);
1937+
1938+
//let's check an illegal operation...
1939+
// RDM is not a valid socket type for SOCK_DGRAM (UDP) as its not implemented yet.
1940+
let sockfd5 = cage.socket_syscall(AF_INET, SOCK_RDM, 0);
1941+
assert!(sockfd5 < 0, "Expected an error, got a valid file descriptor");
1942+
1943+
//let's check an illegal operation...
1944+
//invalid protocol for SOCK_STREAM Type.
1945+
let sockfd6 = cage.socket_syscall(AF_INET, SOCK_STREAM, 999);
1946+
assert!(sockfd6 < 0, "Expected an error, got a valid file descriptor");
1947+
1948+
//let's check an illegal operation...
1949+
//invalid domain for socket
1950+
let sockfd7 = cage.socket_syscall(999, SOCK_STREAM, 0);
1951+
assert!(sockfd7 < 0, "Expected an error, got a valid file descriptor");
1952+
1953+
//let's check an illegal operation...
1954+
//invalid socket type flags combination
1955+
let sockfd8 = cage.socket_syscall(AF_INET, SOCK_STREAM | 0x100000, 0);
1956+
assert!(sockfd8 < 0, "Expected an error, got a valid file descriptor");
1957+
1958+
//let's check an illegal operation...
1959+
//invalid socket type protocol combination
1960+
let sockfd9 = cage.socket_syscall(AF_INET, SOCK_STREAM, IPPROTO_UDP);
1961+
assert!(sockfd9 < 0, "Expected an error, got a valid file descriptor");
1962+
1963+
//let's check an illegal operation...
1964+
//invalid socket type protocol combination
1965+
let sockfd10 = cage.socket_syscall(AF_INET, SOCK_DGRAM, IPPROTO_TCP);
1966+
assert!(sockfd10 < 0, "Expected an error, got a valid file descriptor");
1967+
1968+
19241969
let mut sockfd = cage.socket_syscall(AF_INET, SOCK_STREAM, 0);
1970+
assert!(sockfd > 0, "Expected a valid file descriptor, got error");
1971+
19251972
let sockfd2 = cage.socket_syscall(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1973+
assert!(sockfd2 > 0, "Expected a valid file descriptor, got error");
19261974

19271975
let sockfd3 = cage.socket_syscall(AF_INET, SOCK_DGRAM, 0);
1976+
assert!(sockfd3 > 0, "Expected a valid file descriptor, got error");
1977+
19281978
let sockfd4 = cage.socket_syscall(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
1979+
assert!(sockfd4 > 0, "Expected a valid file descriptor, got error");
1980+
1981+
19291982

1930-
//checking that the fd's are correct
1931-
assert!(sockfd > 0);
1932-
assert!(sockfd2 > 0);
1933-
assert!(sockfd3 > 0);
1934-
assert!(sockfd4 > 0);
19351983

19361984
//let's check an illegal operation...
1985+
// let sockfd7 = cage.socket_syscall(AF_INET, !0b111 | 0b001, 0);
1986+
// assert!(sockfd7 < 0, "Expected an error, got a valid file descriptor");
1987+
19371988
let sockfddomain = cage.socket_syscall(AF_UNIX, SOCK_DGRAM, 0);
1938-
assert!(sockfddomain > 0);
1989+
assert!(sockfddomain > 0, "Expected a valid file descriptor, got error");
19391990

19401991
sockfd = cage.socket_syscall(AF_INET, SOCK_STREAM, 0);
1941-
assert!(sockfd > 0);
1992+
assert!(sockfd > 0, "Expected a valid file descriptor, got error");
19421993

1943-
assert_eq!(cage.close_syscall(sockfd), 0);
1944-
assert_eq!(cage.exit_syscall(EXIT_SUCCESS), EXIT_SUCCESS);
1994+
assert_eq!(cage.close_syscall(sockfd), 0, "Expected successful close, got error");
1995+
assert_eq!(cage.exit_syscall(EXIT_SUCCESS), EXIT_SUCCESS, "Expected successful exit, got error");
19451996
lindrustfinalize();
19461997
}
19471998

0 commit comments

Comments
 (0)