Homework 6

22C:116, Spring 1995

Due Friday Mar. 3, 1995, in class

Douglas W. Jones
  1. Background: Consider an operating system where each user has an address map, and the system has a map. Code to map page 5 of the user's address space into page 8 of the system's address space would look like this:
        map[system][8] = map[user][5]
    
    Assume that systop is a variable in the system's address space holding the page number of the last page in the system's map that is currently in use. The following functions may be used to manipulate an address:
        pagesize         -- the number of locations per page
        pagenum(address) -- gives the page field
        offset(address)  -- gives the offset within page
        makeaddr(pagenum(address),offset(address)) = address
    
    After a trap, the variable usersp holds the user's stack pointer, and userfp holds the user's frame pointer, which points to the first parameter pushed onto the stack prior to the call. The stack grows downward in memory, and the stack pointer always points to the empty location beyond the stack top.

    The problem, part A: Write code (in the language of your choice, as long as it's C or Pascal), to implement the following:

    function viewuser( address, length, startpage )
    
    Given address, the virtual address in the user's address space of a block of length consecutive locations, and given startpage, the address of a block of unused pages in the system's address map, where the block contains at least length+pagesize available memory locations, viewuser maps the page(s) of the user's address space holding the block into the system's address map, starting at startpage and returns the address of the block in the system's address space.

    The problem, part B: After a system call, the first parameter on the stack top is the address of a buffer and the second parameter on the stack top is the length of the buffer. Write code using the viewuser function to map the user's buffer into the system's address space and return a pointer to it.

  2. Background: A simplified UNIX file tree might be organized as follows:
    / (the root)                   -- drwxr-xr-x root
       /bin/                       -- drwxr-xr-x root
           /bin/ls                 -- -r-x--x--x root
           /bin/cat                -- -r-x--x--x root
           ...
       /usr/                       -- drwxr-xr-x root
           /usr/jones/             -- drwx--x--x jones
               /usr/jones/handout  -- -rw-r--r-- jones
               /usr/jones/grades   -- -rw------- jones
           /usr/smith/             -- drwx--x--x smith
               /usr/smith/homework -- -rw------- smith
               /usr/smith/project  -- -rw-r--r-- smith
           /usr/root/              -- drwx------ root
    
    The access control lists and ownership are given above as they would be given in the listing printed by the UNIX command ls -l.

    The problem: Design a capability-based directory structure that results in the same access matrix, at least for the leaf files in the directory structure. Furthermore, your capability list based solution should give each user substantially the same rights, as regards to controlling public access to objects owned by that user.

    Hint: You'll end up with three roots to your capability list structure, one for each user. In addition, you'll end up with subdirectories editable by each user in which that user places links to files the user wishes to make publically accessable. In addition, you'll end up with a public directory, linked to all user directories and editable only by root, that allows each user to find the directory each user uses for export.