Notice how each device defines its own
write/write_iter, and other functions. It’s those functions that ultimately define what it means to read from such a device.
If you run
grep -R "static const struct file_operations" * in the kernel source directory, you’ll find many, many examples of these file_operations structures used in many of the kernel subsystems. As new devices are added to the kernel, they each define their own
struct file_operations in order to define the behavior of the device. Note, however, that not all functions need to be defined. A device can decide that it doesn’t support certain operations. This is usually done because that operation doesn’t make sense in the context of that device. For example, a driver interacting with a mouse will not need to implement filesystem operations such as flush or mmap.
What does this have to do with security?
Well, this is insightful and all, but I’m sure you’re wondering, “What does all this have to do with stopping the bad guys?” Good question. The answer is that there are a lot of ways to do the same thing on a Linux system, whether you’re a legit user or an adversary, and we need to make sure we aren’t blind to an attack vector when we’re monitoring a system.
Sending data on a TCP socket
Initiating network connections is something that adversaries almost always do—whether performing command and control (C2), exfiltrating data, or installing a backdoor. As defenders, we know this, and so we closely monitor network connections on a given machine. One approach to detecting the creation of a TCP socket is to monitor calls to things like
recv. However, from what we learned today, we know that instead of calling
recv, an adversary could call
write_iter because a socket is just a file. So now we have to monitor those four functions as well—and those four functions are VERY noisy. A better approach would be to actually monitor the calls in the networking subsystem that you are interested in after it has gone through the virtual file system. This will reduce the amount of noise and improve monitoring performance.
This is just one of many tactics adversaries may employ to evade modern threat monitoring tools. Fortunately, Red Canary has developed Linux EDR with all of this in mind, and we take careful precautions to not be fooled by these kinds of tactics.
Every file everywhere, at all once
The design philosophy of “everything is a file” has actually proven to work quite well. It has survived for decades and has stayed the same at its core. New file operations have been created over the years to support new device types and operations for those devices. But the basic idea of how this portion of the VFS functions still exists and remains intact.