I understand that an Operating System forces security policies on users when they use the system and filesystem via the System Calls supplied by stated OS.
Is it possible to circumvent this security by implementing your own hardware instructions instead of making use of the supplied System Call Interface of the OS? Even writing a single bit to a file where you normally have no access to would be enough.
First, for simplicity, I'm considering the OS and Kernel are the same thing.
A CPU can be in different modes when executing code.
Lets say a hypothetical CPU has just two modes of execution (Supervisor and User)
When in Supervisor mode, you are allowed to execute any instructions, and you have full access to the hardware resources.
When in User mode, there is subset of instructions you don't have access to, such has instructions to deal with hardware or change the CPU mode. Trying to execute one of those instructions will cause the OS to be notified your application is misbehaving, and it will be terminated. This notification is done through interrupts. Also, when in User mode, you will only have access to a portion of the memory, so your application can't even touch memory it is not supposed to.
Now, the trick for this to work is that while in Supervisor Mode, you can switch to User Mode, since it's a less privileged mode, but while in User Mode, you can't go back to Supervisor Mode, since the instructions for that are not permitted anymore.
The only way to go back to Supervisor mode is through system calls, or interrupts. That enables the OS to have full control of the hardware.
A possible example how everything fits together for this hypothetical CPU:
The CPU boots in Supervisor mode
Since the CPU starts in Supervisor Mode, the first thing to run has access to the full system. This is the OS.
The OS setups the hardware anyway it wants, memory protections, etc.
The OS launches any application you want after configuring permissions for that application. Launching the application switches to User Mode.
The application is running, and only has access to the resources the OS allowed when launching it. Any access to hardware resources need to go through System Calls.
I've only explained the flow for a single application.
As a bonus to help you understand how this fits together with several applications running, a simplified view of how preemptive multitasking works:
In a real-world situation. The OS will setup an hardware timer before launching any applications.
When this timer expires, it causes the CPU to interrupt whatever it was doing (e.g: Running an application), switch to Supervisor Mode and execute code at a predetermined location, which belongs to the OS and applications don't have access to.
Since we're back into Supervisor Mode and running OS code, the OS now picks the next application to run, setups any required permissions, switches to User Mode and resumes that application.
This timer interrupts are how you get the illusion of multitasking. The OS keeps changing between applications quickly.
The bottom line here is that unless there are bugs in the OS (or the hardware design), the only way an application can go from User Mode to Supervisor Mode is through the OS itself with a System Call.
This is the mechanism I use in my hobby project (a virtual computer) https://github.com/ruifig/G4DevKit.
HW devices are connected to CPU trough bus, and CPU does use to communicate with them in/out instructions to read/write values at I/O ports (not used with current HW too much, in early age of home computers this was the common way), or a part of device memory is "mapped" into CPU address space, and CPU controls the device by writing values at defined locations in that shared memory.
All of this should be not accessible at "user level" context, where common applications are executed by OS (so application trying to write to that shared device memory would crash on illegal memory access, actually that piece of memory is usually not even mapped into user space, ie. not existing from user application point of view). Direct in/out instructions are blocked too at CPU level.
The device is controlled by the driver code, which is either run is specially configured user-level context, which has the particular ports and memory mapped (micro-kernel model, where drivers are not part of kernel, like OS MINIX). This architecture is more robust (crash in driver can't take down kernel, kernel can isolate problematic driver and restart it, or just kill it completely), but the context switches between kernel and user level are a very costly operation, so the throughput of data is hurt a bit.
Or the device drivers code runs on kernel-level (monolithic kernel model like Linux), so any vulnerability in driver code can attack the kernel directly (still not trivial, but lot more easier than trying to get tunnel out of user context trough some kernel bug). But the overall performance of I/O is better (especially with devices like graphics cards or RAID disc clusters, where the data bandwidth goes into GiBs per second). For example this is the reason why early USB drivers are such huge security risk, as they tend to be bugged a lot, so a specially crafted USB device can execute some rogue code from device in kernel-level context.
So, as Hyd already answered, under ordinary circumstances, when everything works as it should, user-level application should be not able to emit single bit outside of it's user sandbox, and suspicious behaviour outside of system calls will be either ignored, or crash the app.
If you find a way to break this rule, it's security vulnerability and those get usually patched ASAP, when the OS vendor gets notified about it.
Although some of the current problems are difficult to patch. For example "row hammering" of current DRAM chips can't be fixed at SW (OS) or CPU (configuration/firmware flash) level at all! Most of the current PC HW is vulnerable to this kind of attack.
Or in mobile world the devices are using the radiochips which are based on legacy designs, with closed source firmware developed years ago, so if you have enough resources to pay for a research on these, it's very likely you would be able to seize any particular device by fake BTS station sending malicious radio signal to the target device.
Etc... it's constant war between vendors with security researchers to patch all vulnerabilities, and hackers to find ideally zero day exploit, or at least picking up users who don't patch their devices/SW fast enough with known bugs.
Not normally. If it is possible it is because of an operating system software error. If the software error is discovered it is fixed fast as it is considered to be a software vulnerability, which equals bad news.
"System" calls execute at a higher processor level than the application: generally kernel mode (but system systems have multiple system level modes).
What you see as a "system" call is actually just a wrapper that sets up registers then triggers a Change Mode Exception of some kind (the method is system specific). The system exception hander dispatches to the appropriate system server.
You cannot just write your own function and do bad things. True, sometimes people find bugs that allow circumventing the system protections. As a general principle, you cannot access devices unless you do it through the system services.
I am trying to write a network device driver for Linux. The device that I have has an API available that allows me to access all of the features I need through a shared object that exists in userspace.
I want to write a network driver such that I can make the device show up as a CAN interface. However, in order to interact with the device I need to use a specific shared object that exists in userspace.
The reason that I need a network device driver is to expose a CAN Interface that can be interacted with via the SocketCAN utilities.
Is there a way that I can write a network device driver in userspace? Or what would the best way for me to architect a solution?
Tl;Dr
Need to write a device driver for a device which can only be interacted with from userspace via a supplied shared object which exposes the API. I need the device to show up as a network interface in order to utilize the SocketCAN utilities and other applications that communicate with CAN interfaces in Linux.
What are my options here? What can I do?
Thanks!
So you are saying that there is no driver for your network device in kernel at all, and it can be only accessed via some user-space library? In that case shared library you mentioned should be communicating with your network device by memory mapping your /dev/mem file, in order to be able to read/write to hardware registers. Or perhaps by using some UIO.
So your driver should be also developed in user-space then... Then the actual question you should ask is how to use kernel CAN API from user-space? And is it possible at all in the first place? For answers I guess you should look at Documentation/networking/can.txt. And if the answer is "no" (means you can't expose CAN interface from user-space), then you should develop also some kernel driver which would interact with your user-space part, exposing CAN interface.
In ideal world the whole driver architecture would look like this:
But you need to use some (proprietary, if I understand correctly) shared library API to interact with your device. So I propose you to use next driver architecture, which depicted on the image below:
blue color stands for parts that need to be developed
magenta is for already existing code
In a nutshell, your app and driver both make a shim between SocketCAN API and shared library API.
So you need to develop 2 components:
Driver (on kernel side). It's in charge of:
talking to SocketCAN utilities
talking to your user-space application
Application (in user-space); it's probably should be a daemon, as it's gonna be running constantly. It's in charge of:
talking to shared library
talking to your driver
The last question remains is which kernel API to use to interact between your kernel space driver and user-space application (marked as IPC on picture). It strictly depends on which kind of data you are going to send between two, and how much of data you will want to send, and which way of sending is most appropriate for your task. It may also depend on your shared library API: you probably don't want to spend much of CPU time to convert messages format (as you already have triple context switching with this driver architecture, which is not really nice for performance). So it's probably should be something packet-oriented, like Netlink.
Next reading can be useful to figure out which IPC to use:
Kernel Space - User Space Interfaces
Linux kernel interfaces
In Windows for instance, and all operating systems, file priveleges exist that "prevent" a file from being written to if that rule is set.
This is hard to describe but please listen. People coding in a C language obviously would use some form of framework to easily modify a file. Using the built-in .Net framework, Microsoft obviously would put prevention into their classes checking file permissions before writing to a file. Since file permissions are stored via software and not hardware, what really prevents a file from being tampered with?
Let's hop over to Assembly. Suppose I create an Assembly program that directly accesses hard drive data and changes the bytes of a file. How could file permissions possibly prevent me from doing this? I guess what I am trying to ask is how a file permission really stays secure if the compiled program does not check for file permissions before writing to a file?
Suppose I create an Assembly program that directly accesses hard drive data and changes the bytes of a file. How could file permissions possibly prevent me from doing this?
If you write in assembly, your assembly is still run in a CPU mode that prevents direct access to memory and devices.
CPU modes … place restrictions on the type and scope of operations that can be performed by certain processes being run by the CPU. This design allows the operating system to run with more privileges than application software.
Your code still needs to issue system calls to get the OS to interact with memory not owned by your process and devices.
a system call is how a program requests a service from an operating system's kernel. This may include hardware related services (e.g. accessing the hard disk), creating and executing new processes, and communicating with integral kernel services (like scheduling).
The OS maintains security by monopolizing the ability to switch CPU modes and by crafting system calls so that they are safe for user-land code to initiate.
Here's the scenario:
A central machine running Linux is a "data store" for a number of instruments.
The instruments each have a PC, and each one has a remote mount (SMB) on the data store to which it write data files captured by the instrument.
The instrument PCs run a wide range of operating system including some really old ones.
The instrument PCs hardware clocks are not synchronized, and synchronizing would be problematic for a number of reasons.
Various other fixes (e.g. not using SMB, upgrading instrument operating systems, developing stuff to run on the instruments) are likewise problematic.
What we want to write is a "grabber" application that notices when an instrument writes a file to the data store via its remote mount, and then quickly copies the file somewhere else. The current plan is to use the Linux inotify subsystem to watch for file system events on the directories / trees that the files are likely to arrive in, and then do the copying.
My concern is that the fact the fact that we don't have synchronized clocks is going to be a problem. Is this concern justified?
The concern is not justified.
Linux inotify is an user space API that exposes the Linux fsnotify sub-system. This kernel file system is wired into the general file system layer of the kernel (called VFS). It gets the notification of a creation of a new file directly from the file system code by a callback function, and not by comparing the creation or access dates of the files in a directory. As such, it will not be influenced at all by the time stamps on the files, so the clocks on the different client machine would not matter at all.
To be sure you audit the code for the inotify_should_send_event() send event function, that checks whether an event needs to sent for a tracked file or directory (see here: http://lxr.linux.no/linux+v3.0.4/fs/notify/inotify/inotify_fsnotify.c#L144). Note there is no reference whatsoever to time. In the same spirit the main fsnotify function (http://lxr.linux.no/linux+v3.0.4/fs/notify/fsnotify.c#L296) in the kernel does not reference time stamps anywhere, so clocks will not affect this interface at all.
I hope this helps.
I have been working with an Windows application which reads from the 'nonpaged pool' to increase performance. In this case the nonpaged pool is the area of memory where the network drivers write data as they grab it off the wire.
How does Linux handle memory which network drivers (or other drivers) which require high speed exclusive access to RAM and does the question 'how do I read directly from nonpaged pool?' even make sense when applied to Linux?
Many thanks
related question
Some networks like Infiniband support RDMA, which requires being able to prevent paging for some of the pages in a process. See the mlock(), mlockall(), munlock(), munlockall() functions.
Other than that, I don't think there is a concept of "nonpaged pool", per se. Generally, kernel memory is AFAIK not pageable, but all user memory except that locked with mlock() or such is.