Question

Well, my question is in the title

As we know, an exception handler routine is responsible for switching user mode into kernel mode
This involves certain assembly instructions

And this is claimed to be done in order to prevent the application from using high-privileged instructions and memory areas with restricted access

Can't the user-mode application perform this user-kernel switch by itself ? i.e using those assembly instructions, in a usual function routine within application itself ?

If so, then I cannot understand what's the point of software interrupts and all those security considerations related to user-kernel switch

We simply implement that switch in our program and voila! we are in the kernel mode now

WTH

Was it helpful?

Solution

You make a mistake: the only thing the user can do is call a routine which can execute privileged instructions. This is done by the software interrupt. It is called an interrupt because the original user mode program is stopped while the call is being handled. In this way, the user mode program is completely unable to execute special privileges, but it can call interrupt routines in the kernel which can. Never is the program itself in kernel mode.

OTHER TIPS

The point is security.

Userland applications work in limited environment. They can do their own stuff, but can not read or write anything that is not explicitly assigned to them. This is very important. The point of whole modern OS is to keep applications separated. This is assured mostly by using memory manager unit provided by modern hardware. So typical userland application has no access to any kernel memory and can not "jump in" anywhere. If it were allowed, there would be no way to be sure if application didn't jumped somewhere kernel didn't expected and executed code crashing whole system or stealing your credit card number from another application.

When application requires any functionality that is "outside of it's own box" it must call kernel code to do it for it. But how? From application perspective there is no such thing as kernel code anywhere. That is why there is usually one instruction for "system calls" (syscall). It makes the current code flow jump to one, specified possition that kernel prepared and where it expects to handle all the userland requests. As syscalls are very similar to IRQs, data/prefetch and similar events, the hardware architecture usually models everything just like such events, which are usually called "exceptions". Thus the name "software interrupt".

This is all a bit simplistic, but true. If you want to trully understand it, you have to be familiar with exceptions, virtual memory and similar concepts.

First, I don't quite understand what it is that you want to gain by switching into kernel mode "manually". So, you have switched and then what? What do you want to do next? If you want to access resources that aren't supposed to be accessible in user applications, then that's the whole point of not allowing it because if it was allowed, then your app would be able to easily do nasty things like this:

  • damage the OS and hang or reboot the computer
  • take the computer user hostage and demand ransom
  • turn the computer into a covert spam bot or an remotely-operated attacker of other computers on the network
  • spy on the OS and other apps and steal confidential info
  • tamper with info
  • work around things like DRM and various other licenses
  • impersonate other users of the same computer to possibly incriminate them or steal from them using their banking account or credit card info or their passwords to other resources
  • disable anti-virus software, if any, potentially leading to any or all of the above
  • etc etc

Now, if you are not interested in doing any of the above, then there's no reason for your app to gain kernel privileges.

I admit, there are certain bugs in the OS and things we consider bugs that we'd like to work around by gaining said access, but that is rare and few people can actually "fix" those bugs without breaking something of importance, so the reliability and security concerns outweigh 1000 to 1 the urge to "fix" something that you don't like in the OS.

As for interrupts and exceptions being the way to switch to kernel mode, that's just a common implementation that makes sense.

Interrupts have to be handled in the kernel, which is why they incur a switch when needed. They have to be because only the kernel and device drivers know what to do with the hardware that triggers interrupts. And that's the whole point of the OS, to abstract away hardware differences and provide programs with a unified API to do things that frees them from the burden of knowing how to work with this or that display or sound card or network card or printer, etc etc.

Software interrupts just piggy-back on the same mechanism as hardware interrupts as it's cheap to do so. The primary use of software interrupts is to request some work/assistance from the OS, and, understandably, they need to switch too, which is what hardware interrupts do already.

On the x86 platform, hardware interrupts and the ìnt instruction result in a pretty much identical response in the CPU, they are handled very similarly.

For this system call functionality some CPUs provide special instructions unrelated to interrupts. They may be faster then software interrupts implemented on top of hardware interrupts or they may come with some useful extra functionality that software interrupts don't offer.

This is the case with the x86 instructions sysenter and syscall. They are optimized for fast transitions from user mode to kernel mode.

Some exceptions are of the same nature as hardware interrupts, e.g. the page fault exception. It has to be handled in the kernel as well because that's the mechanism the OS uses to implement virtual on-disk memory. The OS needs to access stuff on the disk in response to page faults and then alter page tables and your app is unlikely to be able to do that itself and it wouldn't be a good thing to let it access those important things like arbitrary locations on the disk or the page tables freely.

Other exceptions are used to control execution of apps and notify the OS of something going wrong, which gives the OS a chance to either fix the problem or terminate the misbehaving application without having to keep it around in a zombi state still consuming valuable resources such as memory. These exceptions also need to be handled in the kernel, it's the only way of doing it.

Now, you may be interested in handling your app's exceptions within the app itself. Some OSes let you do that. Windows implements what it calls Structured Exception Handling (AKA SEH) while Linux and Unix implement signals. Doing either usually still involves first handling the exception in the kernel and only then reflecting it back to where it's come from. It's just how most CPUs are implemented. Such an implementation, when exceptions are first routed into the kernel, is easy and cheap to do and it doesn't disallow anything as the kernel can implement anything on top of this, including SEH and signals.

Anyway, since it's the OS/kernel to provide user apps with functionality and to ensure security and the two more often than not go hand in hand (because the OS/kernel has access to everything and your app isn't supposed to and the OS sometimes accesses those things on behalf of your app, think of courtesy:), both of these things are behind the imaginary fence between user mode and kernel mode.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top