You are expected to understand this. CS 111 Operating Systems Principles, Spring 2006
You are here: CS111: [[2006spring:notes:lec2]]
 
 
 

CS111

Scribe notes for Week1, Lecture2

Main objective: Discussing Interfaces:

Recall from last lecture, we were discussing:

  • OS Kernels
  • Processes
  • File Interface

Mouse button example: (Continued)

.:mouse-example.jpg

SOLUTION:

When the mouse button is pressed down, we write '1' into memory address 0x00, otherwise we write '0'.

This solution uses a method called Direct Memory Access (DMA), which means the application continuously polls for changes on the inputs.

PROBLEM WITH ABOVE SOLUTION

The problem with using DMA is busy waiting. Busy waiting is when the cpu is busy waiting doing nothing because it cannot do anything else while waiting for inputs.

ALTERNATE SOLUTION

We see that we need some mechanism that allows the cpu to be notified when an event happens. We need "Interrupts", or we need to use "Interrupt Driven I/O"

Solution to polling: Use Interrupts -> Save process's status, jump to interrupt handler.

On Interrupt:

During the following steps, interrupts are disabled, but WHY?.

 fetch mouse position with program I/O
 if (mouse position is on start button)
     wake_up_kitty();
 Re-enable interrupts and return to previouse program.

WHY IS INTERRUPT DISABLED?

Interupts are disbled to avoid denial of service, or livelock when many interrupt handlers must be priviledged.

Processors provide 2 modes:

  1. Supervisor Mode: All instructions are available.
  2. User Mode: Not all instructions are available. Some dangerouse instructions can cause protection fault.

User level programs cannot:

  • Install interupt handlers
  • Disable interrupts
    • This is to ensure robustness.

Recap: To avoid the problem of busy waiting associated with polling, we make use of interrupts. In order to have the most control over our interrupt, our interrupt handler must run in supervisor mode. Which leads to the following.

KERNEL

In order to run in supervisor mode, we need a Kernel. The kernel is that O.S. software that runs at supervisor mode.

  • It always runs underneath applications.
  • It provides abstractions for programs (defines abstract machine)
  • Device drivers connect applications to hardware.
  • Multitasking/Time sharing meant running many applications at once.

User level programs are processes. A process is a running instance of a program, it features:

  • Program
  • Memory state
  • O.S. resources
  • Security attributes, which includes:
    • User ID of process owner
    • Processor registers
    • State
    • Process ID

Note: The kernel keep track of the processor registers because we want each of the processes to think that it has its own machine.

Question: How can a process communicate with a kernel? Answer: Through system call interface. A system call interface is an user level process that communicates with the kernel. It is implemented with traps (software interrupts), they look like function calls. Example:

 pid_t getpid(); // get process id

Let us write a function that waits until the mouse is clicked.

 wait_until_mouse_clicked (int * pos)
   systemcall
   current process goes to sleep
   kernel runs other processes until mouse button clicked
   mouse position is stored in *pos, pos[1]

Problem: This is not a neutral solution because it is only for one application; it needs to let the process to wait for more things.

Solution: Let us come up with a more general interface for mouse and move.

First solution:

 wait();
       /*process sleeps until some event happens.*/
 event(event description, function pointer);
       /*registers in kernel when event description(ed) happens, if process is in wait(), call f().
           ed - event description.
           fd - function pointer. 
       */

Second solution:

 wait(bitmask);// process sleeps until event named in bitmask. 

How do we name events?

  • Random numbers
  • Fixed numbers (for mouse)
  • Strings
  • File names

UNIX is one big idea, it express all system resource interrupts of FILES. data file: a stream of bytes. (often w/length)

  • operations:
    1. read.
    2. write
    3. rename
    4. remove

Usually stored in directories, and directories can be hierarchical. See picture below:

Example: UNIX file and directory structure.

.:linuxdirectory.jpg

Time-Of-Check-To-Time-Of-Use bug.(TOCTTOU)

Let us define the following file interface. (not real)

  • read(filename, buffer, position, length);
  • rename(oldname, newname)
  • unlink(name)

Example:

The following picture shows how unlinking file A, and renaming file B to A cause the TOCTTOU error in the result.

.:scribe-fixed.jpg

The problem: After process A has read(1) from file a, process B unlinks file a and renames file b to file a. When process A reads from file a again(2), it is actually reading from file b.

A real life example that exploits the TOCTTOU:

Let /tmp be the folder that contains temporary files, and it has the following attribute and property:

  • world writable
  • gradually collects garbage

So how are the garbage removed?

  • let us have a "cleaner" process that removes garbage periodically.

The following steps demonstrate that TOCTTOU can allow the cleaner process to remove system files. Let us have /tmp/evil/passwd, which is garbage in /tmp that needs to be removed.

  1. (CLEANER STEP1) Cleaner process check if /tmp/evil is a directory.
  2. (EVIL STEP1) Remove /tmp/evil
  3. (EVIL STEP2) Make a link from /tmp/evil to /etc
  4. (CLEANER STEP2) Remove files in /tmp/evil, particularly, it removes /tmp/evil/passwd.

We see that while the cleaner thinks it has removed /tmp/evil/passwd, but it has actually removed /etc/passwd.(BAD!!)

One solution for the TOCTTOU bug is as follows:

In UNIX, what really happens is before reading from a file, we need to open it. This results in a file descriptor being returned.

 file_descriptor open(filename, flags);
   /*The file descriptor identifies with the file named "filename" after the call. This gives 
     a resource handle for that file.*/

Thus we have the following file interface:

 fd = open(name, flags, [mode])
 read(fd, buffer, length)
 write(fd, buffer, length)
 close(fd);

We see how the TOCTTOU bug is avoided by handling files with file descriptors instead of file names.

/dev/mouse

  • kernel "write" to /dev/mouse when:
  1. mouse clicks
  2. user moves the mouse

<<END OF LECTURE TWO>>


Notes on notation: whenever a type's name is followed by "_t", it simply means that it is a kind of int.

 typedef int foo_t;
 foo_t money = 2;

which is same as:

 int money;
 money = 2;
 
2006spring/notes/lec2.txt · Last modified: 2006/09/26 11:42 (external edit)
 
Recent changes RSS feed Driven by DokuWiki