P1 - Add a new system call 🤫

Add a new system call to the kernel

Outcomes:

What to submit:

Procedure:

  1. Start by adding a new system call to your copy of the Linux kernel

    1. Create a new .c file in the kernel directory within the linux repo named kdlp.c

    2. Using the appropriately numbered SYSCALL_DEFINE macro, define a system call entry function for a new kdlp system call in the kdlp.c file that behaves as follows:

      • Takes two arguments, an argument of type char __user * to specify the buffer and an argument of type size_t to specify the size of the buffer

      • Formats a message into a local buffer that includes at least the student's name and the name of the current task that is running on the CPU (see the get_task_comm macro)

      • Determines the amount of data to send: equal to the lesser of the size of the kernel message and how much space the user provided (see min macro)

      • Copies that many bytes from the local message buffer into the user pointer (see the copy_to_user function)

      • Returns a negative error code of -EFAULT (errno 14, bad address) if the copy is not successful

      • Otherwise, returns the amount of data that was copied

    3. The system call implementation should take care to prevent any possibility of a buffer overflow

    4. Modify the Makefile for the kernel subdirectory in kernel/Makefile to add kdlp.o to the list of objects that are always compiled (add it to the end of the obj-y variable)

    5. Add an asmlinkage declaration of sys_kdlp to the bottom of include/linux/syscalls.h (take inspiration from the numerous examples of other system calls in that file)

    6. Add an entry to the system call table for your architecture

      • On aarch64 the list comes from the modern shared table located in include/uapi/asm-generic/unistd.h

        • Find where __NR_syscalls is defined and increment the value

        • Just above that line, add a #define for __NR_kdlp with the next system call number that is free

        • add an invocation of the __SYSCALL macro with the __NR_kdlp number and and the sys_kdlp entry point

        • Take inspiration from the other nearby system calls

      • On x86-64, this is in a special table format located at arch/x86/entry/syscalls/syscall_64.tbl for historical reasons

        • You need to pick a number for it, put it in order with the next highest number after the last common entry in the table

        • Your system call will be common (i.e. shared between 32 and 64 bit userspace programs transparently by the kernel)

        • The name is kdlp and the entry point is sys_kdlp

        • Take inspiration from the other nearby system calls

    7. Update the localversion file to create a distinct release string so you can tell this kernel that has your system call apart from the other kernel you compiled

    8. Update the config using make oldconfig (this should only take a few seconds, and shouldn't require you to answer any questions)

    9. Before compiling the entire kernel, you will find it helpful to compile your new kdlp.c file in isolation using make kernel/kdlp.o

    10. Compile your new kernel with make -j $(nproc)

    11. If the command finishes, make sure it was successful: echo $? should output 0

      • If it does not, re-run make without -j $(nproc) to get a better error message

      • Fix whatever issue you see, and re-run make -j $(nproc)

      • Repeat this process of checking the result and fixing any errors until it compiles successfully

    12. Install your new kernel and its modules sudo make -j $(nproc) modules_install install

  2. Reboot your VM and pick the new kernel

  3. Make a patch out of your kernel code

  4. Write a C program named syscall.c that invokes the new system call

  5. Write an assembly language program named syscall.s that behaves exactly the same as your C program with the following minor differences because you are not using the C standard library:

  6. Test your C program and assembly program

This page should be useful: https://elixir.bootlin.com/linux/latest/ident/get_task_comm

Refer to the Linux kernel documentation about adding system calls for further guidance.

Policies & Procedures


msg = (silence)
whoami = None
singularity v0.6-4-gbe148cb https://github.com/underground-software/singularity