HW1: Covert Channels

Your assignment is to utilize a covert channel to communicate a single randomly-selected 8-bit value between two processes running on a single machine. The character must not be communicated through direct means like a pipe, shared page, socket, etc. Instead, I recommend using a high-bandwidth and relatively easy-to-control covert channel like a shared cache to accomplish this.

You can work in groups of 2, or do this assignment individually if you wish.

Writing your code

Don’t worry about creating a covert channel that is super reliable or high-bandwidth. My programs communicate at about 10 bits/second - slower channels are easier to make reliable. One tricky part of creating the channel is synchronizing the sender and receiver. You can start both sender and receiver simultaneously and/or leverage the fact that they have access to a shared clock.

Below are some useful C code snippets to get you started. You can use any programming language you want, but I recommend C/C++ as they allow for precise control over memory layout and have minimal extra machinery that can add variability to your program’s behavior.

Generating a random 8-bit value:

#include <stdlib.h>
#include <time.h>
void foo() {
 srand(time(NULL));
 // random character
 char c = (char) rand() & 0x0FF;
}

You’ll want to use a high-resolution timer like gettimeofday() for timing operations:

#include <sys/time.h>
#include <assert.h>
void foo() {
 struct timeval before, after;
 int bad = gettimeofday(&before, NULL);
 assert( !bad );
 // do some operation...
 bad = gettimeofday(&after, NULL);
 assert( !bad );
 // compute elapsed time in microseconds:
 long elapsed_usec = ((after.tv_sec - before.tv_sec)*1000000) + (after.tv_usec - before.tv_usec);
}

Read more at the gettimeofday() man page.

To pin processes to a particular CPU (a hardware context), use the taskset command. Read more at the taskset man page. The commands below will pin the sender program to CPU 0 and the receiver program to CPU 1, which ensures that they execute as two hardware contexts on the same CPU (in a hyperthreaded machine like biglab).

taskset 0 ./sender
taskset 1 ./receiver

Check who else is logged into your biglab machine with the who command, and see what the most CPU-intensive processes are with the top command. Your channels will work best on a quiet machine!

Running your code

You can run your code on any machine you want, but I highly recommend using a quiet machine. We have access to the biglab machines for this purpose. Note that biglab is actually a collection of many physical machines. ssh-ing to biglab.seas.upenn.edu will connect you to a random biglab constituent. You can also ssh to a particular biglab machine, e.g., big10.seas.upenn.edu. Make sure that your two communicating processes are running on the same physical biglab machine!

The biglab machines appear to all be Intel Core i5 650 processors. You can read more about the cache architecture of the i5 650 at cpu-world.com.

What to turn in

Submit your code and a brief (1-2 paragraph) write-up via Canvas. The assignment is called HW1: Covert Channels.

Updates

23 Jan: added information about the taskset command.