System Calls: Difference between revisions

From COMP15212 Wiki
gravatar W81054ch [userbureaucratinterface-adminsysopPHRhYmxlIGNsYXNzPSJ0d3BvcHVwIj48dHI+PHRkIGNsYXNzPSJ0d3BvcHVwLWVudHJ5dGl0bGUiPkdyb3Vwczo8L3RkPjx0ZD51c2VyPGJyIC8+YnVyZWF1Y3JhdDxiciAvPmludGVyZmFjZS1hZG1pbjxiciAvPnN5c29wPGJyIC8+PC90ZD48L3RyPjwvdGFibGU+] (talk | contribs)
m (1 revision imported)
gravatar U05730dg [userPHRhYmxlIGNsYXNzPSJ0d3BvcHVwIj48dHI+PHRkIGNsYXNzPSJ0d3BvcHVwLWVudHJ5dGl0bGUiPkdyb3Vwczo8L3RkPjx0ZD51c2VyPGJyIC8+PC90ZD48L3RyPjwvdGFibGU+] (talk | contribs)
mNo edit summary
 
Line 86: Line 86:
*<code>time()</code> and <code>putc()</code> are wrappers around  system calls.
*<code>time()</code> and <code>putc()</code> are wrappers around  system calls.
**<code>time()</code> returns a ‘private’ value maintained by the OS (the number of seconds since a fixed date); the application has no clock internally.
**<code>time()</code> returns a ‘private’ value maintained by the OS (the number of seconds since a fixed date); the application has no clock internally.
**<code>putc()</code> sends a character to the [[Streams|default output] (the screen, in most cases)
**<code>putc()</code> sends a character to the [[Streams|default output]] (the screen, in most cases)
*<code>ctime()</code> is a conversion utility and can run in user mode.  It returns a pointer to a string (of known, constant length in this case) stored in user data space … as is demonstrated by the application’s ability to read this directly as an array.  (You could print the addresses if unconvinced.)
*<code>ctime()</code> is a conversion utility and can run in user mode.  It returns a pointer to a string (of known, constant length in this case) stored in user data space … as is demonstrated by the application’s ability to read this directly as an array.  (You could print the addresses if unconvinced.)
*<code>printf()</code> is a user library but must determine how many times and then make the appropriate number of <code>putc()</code> (equivalent) system calls.
*<code>printf()</code> is a user library but must determine how many times and then make the appropriate number of <code>putc()</code> (equivalent) system calls.

Latest revision as of 14:01, 9 May 2024

On path: Exceptions 1: Exceptions • 2: Reset • 3: System Calls • 4: Software Exceptions • 5: Emulator traps • 6: Memory Fault • 7: Interrupts • 8: Unix Signals
Depends on ExceptionsLibraries

As much as possible, each user process is deliberately kept apart from the others in an abstract machine. One service an operating system provides is a set of system services. For example, if your application process wants to output a character it needs to interface with some hardware. A user application is not trusted (does not have sufficient privilege) to access hardware devices; it must use trustworthy code through a well defined interface.

From a language interface there will be a library call which connects the application to the appropriate operating system call. The library is still user code however.

System calls

The operating system call is a specific means of requesting a service. It is a member of the class of exceptions. It acts in the same way as a normal procedure/function/method/<latest name here> call except:

  • it raises the privilege level during the call
  • it executes code starting at particular addresses which cannot be modified by the application (assuming the memory protection has been set up appropriately).

Thus the system call can do ‘sensitive’ things but the user application can’t ‘hack’ into the OS calls. The call provides the service as required and reverts the privilege level as part of its return process.

System calls too

Different manufacturers use different names for system calls, including:

  • Supervisor Call
  • Software Interrupt
  • Trap
  • Break

but the principle is the same.

A minor, but important feature of the system call – and its complementary return – is that the actions are (necessarily) atomic. The call switches execution to the operating system address space and enters privilege mode simultaneously; similarly the return switch and restoration of the previous mode are inseparable.   Puzzle: what problem(s) could be caused if the operations required separate machine instructions?

Answer

On a call, if the privilege switch was allowed first then the user could then decide to omit the call; a user cannot arbitrarily increase the privilege level, otherwise there would be no protection. On the other hand, if the move to executing operating system code came first the processor would have to execute part of that code whilst still in user mode; this will be forbidden if the memory protection is properly set up, so the code will not execute: it will ‘trap’ with a privilege violation.

On returning, if the privilege is reduced first a trap will result preventing any further execution (and thus the return). A return retaining privilege places trust in the user application to downgrade the privilege level – an obvious security ‘hole’.

The only solution is to ensure these operations are ‘atomic’; processors provide special instructions for these roles.

  Puzzle: all the code inside the system call should be run from memory which applications cannot write to. If a write was possible, what risk would there be?

Answer

The user could plant a simple “JUMP” back to the application, then TRAP and come straight out whilst retaining operating system privilege.


Note that, whilst system call instructions are chiefly intended for the user application to gain (controlled) access to operating system facilities, it is usually possible (in principle) to ‘nest’ calls in the usual way; thus the OS can also make system calls. A call returns to both where it was called from in the code and the privilege it was called from.

Aside: in some unusual circumstances this behaviour is slightly modified; see, for example exercises including fork() (called once, returns twice) and exit() (called but does not return as process is terminated).


Example services from system calls

It’s tricky to say exactly which services will be provided by a system call (i.e. in privileged code). As a general guide, system calls are used for:


In Unix some of the system calls are only ‘thinly wrapped’ in the libraries. The wrapping interfaces the (portable) application with the (particular) operating system.

Example: have a look at clk.c; (there is a download link at the top of this article). This uses four different C library calls.

  • time() and putc() are wrappers around system calls.
    • time() returns a ‘private’ value maintained by the OS (the number of seconds since a fixed date); the application has no clock internally.
    • putc() sends a character to the default output (the screen, in most cases)
  • ctime() is a conversion utility and can run in user mode. It returns a pointer to a string (of known, constant length in this case) stored in user data space … as is demonstrated by the application’s ability to read this directly as an array. (You could print the addresses if unconvinced.)
  • printf() is a user library but must determine how many times and then make the appropriate number of putc() (equivalent) system calls.

In Windows the philosophy is slightly different: the true system calls are more deeply buried in the ‘libraries’ (API) and subject to change between versions rather than being permanently supported.

Whichever version is in use, though, there will be some system call operations internally to raise the privilege level when necessary.


System calls are one example of a means of requesting service from the OS. They are, perhaps, the most obvious case, but not the only way to do this. There are a number of other exceptions which can require (or allow) operating system entry. These typically act as ‘call’ operations with the intention – or at least the possibility – of ‘return’ing.


For extreme enthusiasts only

  • You can peruse the list of Unix system calls; everyone else is better off with the language interfaces.
  • See for yourself: the strace system utility runs a command and intercept the system calls, outputting details to stderr. Try things like strace ls to see what happens. To quote the Linux man page:

    “Students, hackers and the overly-curious will find that a great deal can be learned about a system and its system calls by tracing even ordinary programs.”


Also refer to: Operating System Concepts, 10th Edition: Chapter 2.3, pages 62-74


Articles on IO
Cacheability • Device Drivers • Direct Memory Access (DMA) • IO • Interprocess Communication • Interrupt Controller • Interrupt Service Routines (ISRs) • Interrupts • Libraries • Peripheral devices • Pipes • Queues • Queues Extra • Resources • Shell • Sockets • Spooling and Buffering • Starvation • Streams • System Calls • Thrashing • Timers • Using Peripherals • Virtualisation • Write Buffer
Articles on User
"Everything is a File" • Application Binary Interface (ABI) • Arrays • Boot • Buffer Overflow • Containers • Daemons • Disk Partition • Dynamic Memory Allocation • Emulator traps • Environment Variables • Errors • Exceptions • File Attributes • File Locking • File Permissions • Introduction to Operating Systems • Journalling File System • Links • Locks • Man(ual pages in Unix) • Memory Mapped Files • Monitoring • Network File System (NFS) • PATH • Pipes • Pointers • Relocatable Code • Reset • SETUID • Shell • Sockets • Spooling and Buffering • Streams • Structures • Superuser • System Calls • Unix Signals • User • Using Peripherals