Lab #9: Filesystems
Date: March 22, 2007

Wrapfs

We'll start by building and testing the wrapfs stackable filesytem. This filesystem layer simply passes filenames and file data to and from the user and VFS layers without making any changes. Building wrapfs and reading the code for it will help you understand how the stackable filesystem layer works, so that you can add capabilities to your filesystem in the second part of the lab.

  1. Download wrapfs and compile it.
    tar zxf wrapfs.tar.gz
    cd wrapfs
    make
    
  2. Create a tags file for wrapfs.
    ctags *.[ch]
    
  3. Add wrapfs support to the kernel.
    cat /proc/filesystems                   # List of supported filesystems
    insmod wrapfs.ko                        # Load wrapfs kernel module
    cat /proc/filesystems                   # Old list of filesystems + wrapfs
    
  4. Mount your swap partition as /mnt/lower. If you have problems, check what you did in the last part of lab8. Check that the mount succeeded with df.
    mkdir /mnt/lower
    mount /dev/sda5 /mnt/lower
    df
    
  5. Mount the wrapfs filesystem on top of the ext2 filesystem mounted on /mnt/lower.
    mkdir /mnt/wrapfs
    mount -t wrapfs -o dir=/mnt/lower,debug=1 /mnt/lower /mnt/wrapfs
    df
    
  6. Create a test file on the wrapfs filesystem.
    echo "abbabaab" >/mnt/wrapfs/a
    
  7. Verify that the test file exists and has identical contents on both the wrapfs filesystem and the lower filesystem it is stacked on top of. The diff command should return nothing if there are no differences between the two files.
    ls -l /mnt/wrapfs /mnt/lower
    cat /mnt/wrapfs/a
    cat /mnt/lower/a
    diff /mnt/wrapfs/a /mnt/lower/a
    
  8. Create a test directory on the wrapfs filesystem.
    mkdir /mnt/wrapfs/dir1
    
  9. Verify that the directory exists on both wrapfs and the lower filesystem.
    ls -l /mnt/wrapfs /mnt/lower
    
  10. Create a test file in the new directory and verify that it exists on both filesystems.
    echo "baababba" >/mnt/wrapfs/dir1/a
    ls -l /mnt/wrapfs/dir1 /mnt/lower/dir1
    

A Simple Encrypting Filesystem

Now let's modify wrapfs to create caesarfs, a filesystem that encrypts file data using a Caesar cipher. The Caesar cipher encrypts each character individually by substituting each letter of the alphabet with a later letter of the alphabet. For example, in Caesar's original cipher, each letter was replaced with a letter three places later in the alphabet, with letters at the end of the alphabet being rotated to the beginning as follows:

Plaintext Alphabet:  abcdefghijklmnopqrstuvwxyz
Ciphertext Alphabet: defghijklmnopqrstuvwxyzabc
The encryption and decryption functions can be given as
E(x) = (x + n) % 26
D(x) = (x - n) % 26
where x is a the number of a letter from 0 ('a') through 25 ('z') and n is the key of the cipher (3 in the example above.) Only uppercase and lowercase letters are encrypted. Non-alphabetic characters are left unchanged by the cipher.
  1. Unmount wrapfs
    umount /mnt/wrapfs
    
  2. Clean the wrapfs source directory.
    make clean
    
  3. Find the wrapfs_encode_block and wrapfs_decode_block functions. This is where you'll do your encryption. You can store your encryption key in the header file of this C file. If you have configured a specific tag file in your .vimrc, you'll need to comment that out to use the tag file you created under wrapfs.
    gvim -t wrapfs_encode_block
    
  4. Which functions call the encoding and decoding functions? Can you determine which system calls start these code paths?
    grep -2 wrapfs_encode_block *.[ch]
    grep -2 wrapfs_decode_block *.[ch]
    
  5. Change the wrapfs part of each filename to caesarfs.
    mv ... ...                      # One mv per file with wrapfs in the filename
    perl -pi -e 's/wrapfs/caesarfs/g' *.[ch] Makefile
    
  6. Modify fist_caesarfs.c to do Caesar cipher encoding and decoding.
    gvim fist_caesarfs.c
    
  7. Build and install the module.
    make
    su
    insmod caesarfs.ko
    cat /proc/filesystems
    
  8. Mount your encrypting filesystem.
    mount -t caesarfs -o dir=/mnt/lower,debug=1 /mnt/lower /mnt/caesarfs
    
  9. Test your encrypting filesystem. Encryption should be transparent, so reads and writes to /mnt/caesarfs files should appear unchanged. However, viewing files on the lower level filesystem will reveal the ciphertext actually stored on disk.
    echo "abbabaab" >/mnt/caesarfs/a
    ls -l /mnt/caesarfs /mnt/lower
    cat /mnt/caesarfs/a
    cat /mnt/lower/a
    
  10. Find the key used in your caesarfs filesystem with a chosen ciphertext attack.
    echo "abcdefghijklmnopqrstuvwxyz" >/mnt/caesarfs/alphabet
    cat /mnt/caesarfs/alphabet
    cat /mnt/lower/alphabet
    
 

©2007 James Walden, Ph.D.