Principles of Operating Systems

CMSC 421-04 - Spring 2016


Project 2

Due by 11:59PM EDT on Thursday May 5, 2016

Changelog:

April 22, 2016: Added note about netfilter.
Fixed prototypes to match what was described in class

April 12, 2016: Added note clarifying dir and proto arguments

April 5, 2016: Initial Version

Introduction/Objectives

In this project, you will create a new version of the Linux kernel that adds a few security features to the system to help protect it from external attacks. These features will be implemented by way of modifying existing kernel systems to hook into your code, as well as system calls that will be used to set up and maintain your new security system.

To implement the functionality described in this project, you will need to find the code in the kernel responsible for handling network-related system calls and modify it. You will not be able to use iptables or netfilter to implement the functionality of the project as described. Please do not try. Using either of these will result in heavy point reductions for not actually implementing the functionality asked for.

It is highly suggested that you plan out how you wish to complete this project ahead of time and allocate your time accordingly. This project will take a significant effort to complete. You are being given over a month to complete this project — there will be absolutely no extensions given on the due date of this project!

Before you begin, be sure to create your new GitHub repository for Project 2 by using the link posted on the course Piazza page. Then, follow the same steps you did in Project 0 to clone this new repository (obviously, substitute project-2 for project-0 from the earlier instructions). You may remove any previous vanilla project code directories from your VM to clear up space. In addition, if you haven't done so already, you may also remove the /usr/src/project0 directory from your VM.

As a first step, change the version string of the new kernel to reflect that it is for Project 2. That is, make the version string read 4.4.1-cmsc421project2-USERNAME (substituting your username where appropriate).

As with Project 1, the various links to resources on the course website will be helpful for what you are doing.

System Description

Your task in this project is to design and implement a firewall system inside the Linux kernel. This firewall system will be configured and managed by way of new system calls that you must implement. In particular, you may not use any existing firewall-like functionality in the kernel (such as iptables) to implement your project.

The firewall system you are are to design must be able to block requests on a network port level, and dependent on what protocol is in use as well (UDP or TCP). The firewall should work with both IPv4 and IPv6 connections (you don't have to worry about anything like IPX or other obscure network protocols).

Requests to block or unblock a port must be sent only by the root user account. This is to prevent regular users from violating the rules put in place by a system administrator. The default status of the firewall should be that all ports are unblocked on boot, and a user-space program should be able to then set up the firewall at a later time (or as a boot script or something similar).

Requests to block ports will be accompanied by which transport layer protocol to examine (TCP or UDP) and which direction (incoming or outgoing) to block, as well as the port (of course).

Your firewall must be able to block an "unlimited" number of ports (within reason, since it there are only 65,536 ports available on each of TCP and UDP). You may choose how to store data in the kernel, but you should consider the efficiency of whatever method you choose (not only in speed, but also in memory usage). Particularly efficient implementations may result in extra credit being given on the assignment, whereas particularly inefficient implementations may result in lost points.

This project will involve finding the portions of the code responsible for network communications and modifying them. It is suggested that this be done at the system call level (i.e, find the system call(s) responsible for binding to a port for incoming connections and block things there, find the system call(s) responsible for connecting to a remote port and block things there). This will provide the most general solution to the project, and avoid unnecessarily changing things in multiple places for supporting multiple protocols.

New System Calls

You will add a few new system calls for managing your security system. All system calls that change the state of the security system must only be run by the root user (the user with a UID of 0). You are responsible for denying access to these system calls for regular users (they should just return -EPERM to regular users to give them a permission denied error).

As with Project 1, the system calls must be added in the same order as is specified here and must have the same argument lists. The signature and semantics for your system calls must be:

For proto in all of these, the value will either be IPPROTO_TCP or IPPROTO_UDP. Outgoing implies a dir of 0, where incoming implies a dir of 1.

Each system call returns an appropriate non-negative integer on success, and a negative integer on failure which indicative of the error that occurred.

As it is possible that the system may be in-use when a request to block, unblock, or reset comes in, you must provide adequate locking in these functions to prevent race conditions.

/proc Filesystem Driver

In addition to the system calls above, the firewall must maintain some information in the /proc filesystem. Your code should create a file in /proc that will report the list of ports that are blocked (along with the protocol and direction), and how many requests have been blocked when it is queried for read as textual data. The file in /proc should not allow any writes to it. Any user should be able to access this file, and it must be named /proc/fw421_stats.

Your /proc entry must also follow proper locking, as it is possible that the system may be in-use when you are trying to read statistics.

Extra Credit

As mentioned above, extra credit may be awarded for particularly efficient solutions to the project may result in extra credit being awarded.

Another avenue for potential extra credit is if you implement the system in a dyanmically loadable kernel module. Note that this will require significant effort, and should not be attempted before you have completed the rest of the project. In particular, it is very difficult to add new system calls in a kernel module, so you may (if you choose to pursue this extra credit opportunity) provide stub versions of the system calls in the kernel and modify the system call table on module load to point to the real versions of the system calls in your module. You should note that the kernel's system call table is not writable from modules normally, so you must make some changes to the kernel in order to attempt this.

If you think you deserve extra credit for your assignment, please describe why in your README.p2 file. This includes if you think your approach is significantly efficient or if you implement the system as a kernel module. In addition, if there is any other (valid) reason that you feel that the grader should award extra credit to your assignment that is not covered above, feel free to describe that as well. If you do not describe anything related to extra credit in your README.p2 file, then you will not receive any extra credit, even if you implement the system as a kernel module.

No instructor aid will be provided for extra credit, beyond the resources provided on the course website. If you wish to pursue the extra credit portion of the assignment, you are on your own.

User-space driver programs

You must provide three simple programs to manipulate the firewall system. The programs should be named the same as the system calls, and should essentially do nothing more than parse the arguments and call the system calls you have provided. Here is an example of how these should work (all of which would be run as root, otherwise they should report an error without calling the system call):

    ./fw421_reset
    ./fw421_block_port tcp in 1337
    ./fw421_unblock_port udp out 31337

These programs should be placed in a proj2driver directory in your kernel source tree. There should be a Makefile provided to build all of the programs (that is to say that running make in the proj2driver directory should result in the three programs specified being built and available in that directory).

In addition, you must adequately test your kernel changes to ensure that they work under all sorts of situations (including in error cases). You should build one or more testing drivers and include them in your sources submitted. Create a new directory in the Linux kernel tree called proj2tests to include your test case program(s). Be sure to include a Makefile to build them. In addition, provide a README in this directory describing your approach to testing your code.

Submission Instructions

You should follow the same basic set of instructions for submitting Project 2 that you did for Project 0. That is to say, you should do a git status to ensure that any files you modified are detected as such, then do a git add and a git commit to add each modified/newly created file or directory to the local git repository. Then do a git push origin master to push the changes up to your GitHub account.

Be sure to include not only your modified kernel files, but also your driver and test program files. Also, please include a file named README.p2 in the root of the kernel tree describing your approach to the kernel changes and additions needed for this project.

You should also verify that your changes are reflected in the GitHub repository by viewing your repository in your web browser.


What to do if you want to get a 0 on this project

Any of the following will cause a significant point loss on this project. Items marked with a * will result in a 0.

Please do not make us take off points for any of these things!


Last modified Tuesday, 01-Sep-2020 18:43:36 EDT