Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C and resource protection in memory

When we compile a C program, it just generates some machine-understandable code. This code can directly run on the hardware, telling from this question.

So my questions are:

  1. If a C program can directly run on the hardware, how can the kernel handle the resource allocation for this program?

  2. If the executable generated from the compiler is in pure machine-understandable form, then how do the privileged and non-privileged modes work?

  3. How does the kernel manage the permission of hardware resources if a program can directly run on the hardware not through the kernel?

like image 572
shiv garg Avatar asked Oct 21 '15 17:10

shiv garg


2 Answers

If a C program can directly run on the hardware how can kernel handle the resource allocation to this program.

The kernel is responsible for managing the resources of the computer as a whole, including resources like the hardware. This means that, for user-level applications to be able to access things like hardware devices, write to a terminal, or read a file, they have to ask the kernel for permission. This is done by using the system calls exposed by the OS, as mentioned by @Marcus.

However, I wouldn't say that the program runs directly on hardware in the sense that it does not interact with the hardware directly, as a kernel module/driver would. A client program will set up the arguments for a system call and then interrupt the kernel and wait until the kernel services the interrupt request the program made.

This is why OSes today are said to run in protected mode, as opposed to the old days when they ran in real mode and a program could, for example, mess around with hardware resources directly --and potentially screw things up.

This distinction becomes very clear if you try writing a trivial "hello world" program in x86 assembly. I wrote and documented this one several years ago, reproduced below:

;
; This program runs in 32-bit protected mode.
;  build: nasm -f elf -F stabs name.asm
;  link:  ld -o name name.o
;
; In 64-bit long mode you can use 64-bit registers (e.g. rax instead of eax, rbx instead of ebx, etc.)
; Also change "-f elf " for "-f elf64" in build command.
;
section .data                           ; section for initialized data
str:     db 'Hello world!', 0Ah         ; message string with new-line char at the end (10 decimal)
str_len: equ $ - str                    ; calcs length of string (bytes) by subtracting the str's start address
                                            ; from this address ($ symbol)

section .text                           ; this is the code section
global _start                           ; _start is the entry point and needs global scope to be 'seen' by the
                                            ; linker --equivalent to main() in C/C++
_start:                                 ; definition of _start procedure begins here
    mov eax, 4                   ; specify the sys_write function code (from OS vector table)
    mov ebx, 1                   ; specify file descriptor stdout --in gnu/linux, everything's treated as a file,
                                             ; even hardware devices
    mov ecx, str                 ; move start _address_ of string message to ecx register
    mov edx, str_len             ; move length of message (in bytes)
    int 80h                      ; interrupt kernel to perform the system call we just set up -
                                             ; in gnu/linux services are requested through the kernel
    mov eax, 1                   ; specify sys_exit function code (from OS vector table)
    mov ebx, 0                   ; specify return code for OS (zero tells OS everything went fine)
    int 80h                      ; interrupt kernel to perform system call (to exit)

Notice how the program sets up the write system call, sys_write, and then specifies the file descriptor of where to write, being stdout, the string to write, and so on.

In other words, the program itself does not perform the write operation; it sets things up and asks the kernel to do it on its behalf by using a special interrupt, int 80h.

A possible analogy here might be when you go to a restaurant. The server will take your order, but the chef is the one that will do the cooking. In this analogy, you are the user-level application, the server taking your food order is the system call, and the chef in the kitchen is the OS kernel.

If the executable generated from the gcc is in pure machine understandable form then how do the privileged and non-privileged mode work?

Keying off from the previous section, user level programs always run in user mode. When the program needs access to something (e.g. terminal, read a file, etc.), it sets things up, as with the sys_write example above, and asks the kernel to do it on its behalf with an interrupt. The interrupt causes the program to go into kernel mode and remains there until the kernel has completed servicing the client's request --which may include denying it altogether (e.g. trying to read a file the user has no privilege to read).

Internally, it's the system call that's responsible for issuing the int 80h instruction. User-level applications just see the system call, which is the common interface between the client and the OS.

How does the kernel manage the permission of hardware resources when a program can directly run on hardware not through the kernel?

If you followed the previous explanations, you can now see that the kernel acts as a gatekeeper and that programs "knock" on this gate by using the int 80h instruction.

like image 166
code_dredd Avatar answered Sep 27 '22 23:09

code_dredd


Whilst the program is in machine code, to do anything not within its own memory region, it will need to call the kernel via syscalls.

The CPU actually has a notion of the privilege of code. Unprivileged code can't directly access physical memory etc; it has to go through the OS and ask it to give access.

Hence, every program does directly run on the CPU, but that doesn't mean it can do anything with the hardware – there's hardware measurements against that. The privilege that you'd need to do certain things is one of these.

like image 45
Marcus Müller Avatar answered Sep 27 '22 23:09

Marcus Müller