Question: Access Control Only the root user may call the creation and deletion system calls below. All other system calls may be called by any process

Access Control

Only the root user may call the creation and deletion system calls below. All other system calls may be called by any process that would be allowed and in any user context. If a regular user account attempts to call either of the prohibited system calls, then they should be given an error indicating that they have been denied that permission such as -EPERM.

Encryption

Your IPC mechanism will implement a very simple encryption algorithm which each mailbox will support optionally. By optionally, I mean that on mailbox creation it will be specified whether encryption is used or not you must implement the encryption algorithm if it is requested on mailbox creation it is not an optional part of this assignment to implement the encryption scheme. The encryption algorithm that you will be implementing is exceedingly simple. What you will be implementing is a very simple XOR cipher. Your cipher will process data in 32-bit blocks -- that is to say that the key you will be encrypting and decrypting with is 32-bits in size. Messages should be padded (virtually) to 32-bit increments when encrypting. You are not required to (nor should you) store any encrypted padding bytes truncate messages back to the original message size before storing them. See here for another description of how an XOR cipher works (which is geared directly to your project).

If the mailbox is specified to use encryption, each message in the mailbox will have a separate key that is passed in to the kernel when the message is input into the system. In order for the data to come out in the clear, the same key must be passed in when retrieving the message. You must not store this key along with the message in your IPC system's data structures in the kernel.

As a brief example of how this cipher works, please refer to the following:

Data Passed in (6 bytes): 0xDE 0xAD 0xBE 0xEF 0x12 0x34 Key: 0x1BADC0DE Data stored: 0xC5 0x00 0x7E 0x31 0x09 0x99

New System Calls

You will add a few new system calls for managing mailboxes of IPC messages. The mailboxes and their contents all exist only in the Kernel address space. You will develop the system calls specified below in order to access the boxes and their contents by user processes.

Each mailbox should be identified by an unsigned long value, which is passed in at creation time. Each mailbox can store an "unlimited" number of messages, each of which can be of "unlimited" length. Upon creation, the user will specify how messages are to be stored.

Each mailbox will store its messages in FIFO order. That is to say that each mailbox should be seen as a queue.

Please keep in mind that these functions may well be called from multiple different processes simultaneously. You must provide for appropriate locking to ensure concurrent access to these functions works properly.

As this code will be part of the kernel itself, correctness and efficiency should be of primary concern to you in the implementation. Particularly inefficient (memory-wise, algorithmic, or poor locking choices) solutions to the problem at hand may be penalized in grading. In regard to correctness, you will probably find that the majority of your code for this assignment will be spent in ensuring that arguments and other such information passed in from user-space is valid. If in doubt, assume that the data passed in is invalid. Users tend to do a lot of really stupid things, after all. Crashing the kernel because a NULL or otherwise invalid pointer is passed in will result in a significant deduction of points.

Finally, you are to implement this system on your own. The IPC systems within the kernel already will not be helpful to you in implementing this assignment.

The signature and semantics for your system calls must be:

long sys_create_mbox_421(unsigned long id, int enable_crypt): creates a new empty mailbox with ID id, if it does not already exist, and returns 0. The queue should be flagged for encryption if the enable_crypt option is set to anything other than 0. If enable_crypt is set to zero, then the key parameter in any functions including it should be ignored.

long sys_remove_mbox_421(unsigned long id): removes mailbox with ID id, if it is empty, and returns 0. If the mailbox is not empty, this system call should return an appropriate error and not remove the mailbox.

long sys_count_mbox_421(void): returns the number of existing mailboxes.

long sys_list_mbox_421(unsigned long __user *mbxes, long k): returns a list of up to k mailbox IDs in the user-space variable mbxes. It returns the number of IDs written successfully to mbxes on success and an appropriate error code on failure.

long sys_send_msg_421(unsigned long id, unsigned char __user *msg, long n, unsigned long key): encrypts the message msg (if appropriate), adding it to the already existing mailbox identified. Returns the number of bytes stored (which should be equal to the message length n) on success, and an appropriate error code on failure. Messages with negative lengths shall be rejected as invalid and cause an appropriate error to be returned, however messages with a length of zero shall be accepted as valid.

long sys_recv_msg_421(unsigned long id, unsigned char __user *msg, long n, unsigned long key): copies up to n characters from the next message in the mailbox id to the user-space buffer msg, decrypting with the specified key (if appropriate), and removes the entire message from the mailbox (even if only part of the message is copied out). Returns the number of bytes successfully copied (which should be the minimum of the length of the message that is stored and n) on success or an appropriate error code on failure.

long sys_peek_msg_421(unsigned long id, unsigned char __user *msg, long n, unsigned long key): performs the same operation as recv_msg_421() without removing the message from the mailbox.

long sys_count_msg_421(unsigned long id): returns the number of messages in the mailbox id on success or an appropriate error code on failure.

long sys_len_msg_421(unsigned long id): returns the lenth of the next message that would be returned by calling sys_recv_msg_421() with the same id value (that is the number of bytes in the next message in the mailbox). If there are no messages in the mailbox, this should return an appropriate error value.

So, for instance, the sys_send_msg_421 syscall from the list below would defined as follows:

SYSCALL_DEFINE4(send_msg_421, unsigned long, id, unsigned char __user *, msg, long, n, unsigned long, key) { /* Code goes here */ }

Each system call returns an appropriate non-negative integer on success, and a negative integer on failure which indicative of the error that occurred. See the header file for a list of error codes. Suggested error codes for several error conditions are listed below:

-EPERM: Permission denied

-ENOMEM: Out of memory during an allocation

-EFAULT: Supplied an invalid pointer or one that cannot be read/written for the entire requested length

-ENOENT: Invalid mailbox id specified

-EEXIST: Mailbox already exists on creation

-ENOTEMPTY: Mailbox not empty on deletion

The kernel must be very careful with memory access. Remember that users often don't properly error check their code very well and that malicious users do also exist. You should be very careful in your code to ensure that any pointers that come in from user-space (all marked with __user above are checked sufficiently. Also, you should ensure to not leak private information outside the kernel, such as encrypted messages. All of your encryption and decryption MUST occur in memory within the kernel's memory space not in any user-space memory. Also, it is up to the user to provide the key for both encryption and decryption. You MUST NOT store the key with the messages in the kernel. If the user specifies a different encryption key for encryption and decryption, the user should expect to get a scrambled message back. Finally, 0 is a perfectly valid encryption key mathematically it just won't change the message at all.

User-space driver program(s)

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 proj1tests to include your test case program(s). Be sure to include a Makefile to build them and instructions on how to run them in a README file within this directory. Your README for the test programs should also describe your general strategy for testing the system calls.

It is strongly suggested that you additionally build a separate program for each system call to be implemented to simply call that system call with user-provided arguments. For the data to be sent as a message, you might consider allowing the user to specify a file of data to send or a string on the command line. These programs will likely prove to be invaluable in debugging.

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Databases Questions!