CS241 Final Exam / Final Project Spring 2021
Part 2 of 3 (100 points, code, 60 minutes) “Memory mapped secrets”
It’s no longer safe and you have only minutes to spare before BigCorp finds you; time for a fast exit.
You’ve put all of your valuable secrets (leaked GME stock prices for next year, unfinished malloc
ideas, ideas for a new solar panel fabrication process, new Meme format) into a single file (it could
be a text file, zip file; whatever), now you just need to get out of here without anyone being able to
discover or decrypt its valuable contents. Fortunately you have your CS241 skills and VM. You
quickly create and use a Linux C99 program helloworld.c using the following – clang -O0 -Wall -Wextra -Werror -Wno-error=unused-parameter -g -std=c99 –
D_GNU_SOURCE -DDEBUG helloworld.c
When your program is run it seems to be the simplest program; it just prints Hello World …
./a.out
(prints “Hello World” without the quotes to standard-out and exits with value 0)
However, if it is renamed to encrypt it creates an encrypted version of your secrets with every byte xor’d with a random value –
./encrypt mystuff.txt 1.bin 2.bin
It opens the file mystuff.txt (using open and mmap) for reading and writing, and creates two new files 1.bin 2.bin. As it processes the bytes of mystuff.txt it also overwrites the contents of mystuff.txt with zero bytes so that the file’s original content is no longer easily recoverable. Output file 1.bin is a sequence of random bytes (read from /dev/urandom). File 2.bin contains the bytes from the original file encrypted by xor-ing each byte with the corresponding byte stored in file 1.bin. Upon completion both output files will be the same length as the original file, the length of the original file is unchanged.
For example if the first byte of mystuff.txt was 0x51 and the first random value read from /dev/urandom was 0x42 then the “1.bin” would start with 0x42, “2.bin” would start with 0x13 and the first byte of mystuff.txt would be overwritten with 0x00.
You head out of town, pausing only to donate your old laptop. You post 1.bin and 2.bin – now on separate USB sticks, together with your program – from two separate locations. Your simple exclusive-or encryption using a one-time pad will still be secure if only one of the files is intercepted. Three days, two flights and a row boat later, you rename your program to decrypt, and recover your secrets –
./decrypt output.txt 1.bin 2.bin
This reads the two files “1.bin and 2.bin (using mmap) and creates the output file “output.txt” (with contents identical to the original mystuff.txt file).
Upon completion it also deletes the files 1.bin and 2.bin from the filesystem.
For example, if the first byte of 1.bin was 0x42 and first byte of 2.bin was 0x13 then the first byte of the output file would be xor(0x42,0x13) = 0x51. The 2nd byte of output is recovered by xor-ing the 2nd bytes of 1.bin and 2.bin etc.
Write one program. When executed if the program name is ./encrypt then encrypt the file, if it
is ./decrypt then decrypt the given files, as described above. If neither is true, or 3 filename arguments are not provided, then innocently print “Hello World” and exit with value 0.
In encryption mode, use stat to verify that the output files do not exist. If not print “Hello World” and exit with value 0.
In decryption mode, use stat to verify that the two input files exist and are the same size. If not print “Hello World” and exit with value 0.
Use open and mmap to read and modify the contents of original file (encryption mode) and read the two random files 1.bin 2.bin (decryption mode).
Use fopen and fputc to create the output files in both encrypt and decrypt modes.
Use stat/fstat to verify if the files exist and/or to determine their size.
The unlink call will also be useful.
All other behaviors, output, handling error conditions etc. are unspecified and are not graded.
Hint: The hexdump program may be useful. Grading Rubric & Submission
Add your netid as a comment to your code. For example, if your netid is angrave, write
// author: angrave
Upload your code, helloworld.c; it should compile using the above clang options on a standard
CS241 VM. It will be graded on-
10 Correctly uses the program’s arguments to change behavior between hello-world, encrypt and decrypt modes basd on the process’ name.
10 Zeros the original file contents so the file is the same length but the content is destroyed 10 Random bytes are sourced from /dev/urandom
10 Implements encryption xor-protocol and generates desired output
10 Original file content can be recreated after encrypting and decrypting
10 Encrypted files are removed from the filesystem after decryption processing is complete 10 Correctly uses mmap for the input file(s)
10 Correctly uses fopen & fputc for output
10 The encrypt mode verifies input files exist before processing
10 The decrypt mode verifies input file sizes are equal before processing
Part 3 of 3 (100 points, code, 60 minutes) “Saving Demo Day (my partner owes me big time)”
It’s demo day but you partner’s JavaScript/C++20/python program keeps randomly crashing due to a segfault. There’s no time to debug. You need a way to keep it running by automatically restarting it when it crashes.
Create a C99 Linux program restart.c using the same clang options as part 2 that automatically restarts the given program if it exits due to a segfault. However if it exits normally with any exit value, it should not restart. Also if the user presses CTRL-C both programs should exit. In the example below, your restart program searches the current PATH environment to find the python3 executable which is then executed as “python3” and passed arguments “MyCode” and ABC
./restart python3 MyCode ABC
Use fork and an appropriate version of exec. If fork or exec fails print a message to stderr and exit with value 1.
Hints: The ps and killall programs may be useful. It is not necessary to parse the arguments; simple pointer arithmetic is sufficient. A suitable choice of exec will search $PATH for the program for you.
Grading Rubric & Submission
Add your netid as a comment to your code. For example, if your netid is angrave, write
// author: angrave
Upload your code restart.c; it should compile using the clang options in Part 2 on a standard
CS241 VM. It will be graded on the following functionality –
10 Uses an exec-function to start the given program
10 Does not create unnecessary processes e.g. if the executable cannot be found 10 Prints to stderr and exits if fork or exec fails
10 Passes multiple (arbitrary number of) arguments to the target program
10 Correctly uses wait/waitpid and the wait macros
10 Only a segfault causes the program to be restarted; other reasons result in both
programs finishing
10 Uses fork to start a new child process
10 Pressing CTRL-C causes the buggy program and the restart program to finish 10 Searches $PATH for the executable
10 Correctly sets the process name of the child process
That’s it – Thank you! We will provide submission details on or before Wednesday. Expect to upload your mp4 video file(s) (or provide a working link), plus restart.c helloworld.c files. If providing a URL link to your video, check that the link works in a browser when not authenticated as yourself.