# Analyzing Impact and Systemwide Effects of the SlowROS Attack in an Industrial Automation Scenario
## 4 Attack Context and Description
### Kernel Behavior and System Limits in TCP Connection Handling  
Important constraints on the maximum number of concurrent connections a server can support come from the internal logic of the server itself, besides several kernel parameters related to protocol stack resource management. For instance, connections that require a large quantity of server-side memory to be handled may exhaust the total amount of memory allotted to the server well before hitting against any other system limit. Moreover, flaws in the server implementation, like the failure to release sockets upon normal or abnormal connection closure, may lead to premature socket exhaustion. Unfortunately, memory requirements and implementation quality are usually very specific to a certain kind/version of a server, and can hardly be generalized. In addition, while testing the ROS Master implementation, we found no indication of any memory or socket leak. Its memory allocation level stayed well below the upper limit as well. For all these reasons, in this paper, we focus only on system-level limits that depend on the Linux kernel configuration, and hence, impose an upper bound to the number of concurrent TCP connections that a certain server can successfully support, regardless of its  
Figure 2: Analysis of the 3-way handshake procedure during a TCP connection between a client and a ROS Master service. internal structure. While such a choice may represent a limit for slow DoS categories like delayed or long responses DoS, it has no impact on our long request attack [6]. Furthermore, we also assume there is a one-to-one correspondence between established TCP connections and sockets in the ROS Master. This is not strictly true for the _partially_ established TCP connections outlined in Section 4.1, that is, connections that went through the first two stages of the three-way TCP handshake and are waiting for the final ACK from the initiator. For these connections, the in-kernel protocol stack has already allocated a state vector but, since processes are not made aware of incoming connections until they are _fully_ established, no sockets in the user space have been assigned to them yet. However, the net.ipv4.tcp_max_syn_backlog parameter (128 by default on the nodes described in Section 5) determines the maximum number of _partially_ established TCP connections that the kernel allows for the whole system. This limit prevents both crashes and protocol stack memory exhaustion due to this reason. Two other kernel and process parameters apply to the different stages an incoming TCP connection may be in. In particular, we have the following:  
1. When they have been fully established from the TCP/IP protocol stack point of view, incoming connections enter the backlog of the listening socket, waiting to be accepted by the server by means of an accept() system call. The actual limit to the backlog length is primarily set by the server through the second parameter of listen(), but a kernel parameter sets an upper bound to what the server may ask for. The parameter is net.core.somaxconn, and its default value is 4096 on the nodes used in our test bed. 2. As also discussed in Section 4.1, when the server eventually tries to accept an incoming connection, a new socket must be allocated for it within the accept(). Linux, like many other operating systems, represents a socket in user space with a file descriptor. Therefore, the maximum number of connections a server can accept is also limited by the maximum number of open file descriptors the server is allowed to have. Unlike the previous two, the maximum number of file descriptors a process may open is not set by a kernel parameter but is primarily a per-process limit that can be set by means of the setlimit (set resource limit) system call [50]. Resource limits are uniquely identified by a symbolic constant, RLIMIT_NOFILE in this particular case, which becomes the first argument of setlimit. The second argument represents the desired value of the limit being set, encoded in a struct_limit.