P1 - Add a new syscall 🤫

Add a new system call to the kernel

Outcomes:

What to submit:

Procedure:

  1. Start by adding a new syscall 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 syscall entry function for a new kdlp syscall in the kdlp.c file that behaves as follows:

      • Takes two arguments, an appropriately marked pointer to a buffer from userspace of type char *, an integer specifying the size of the buffer of type size_t.

      • 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.
    3. Otherwise, returns the amount of data that was copied.

    4. The syscall implementation should take care to prevent any possibility of a buffer overflow.

    5. 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).

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

    7. Add an entry to the syscall table for your architecture.

      • 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 syscall 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 syscalls

      • 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 syscall 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 syscalls.

    8. Update the extra version tag in the main kernel Makefile so you can tell this kernel that has your syscall apart from the other kernel you compiled.

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

    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 that invokes the new syscall.

  5. Write an assembly language program 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.

The following pages will be of interest to a student:

Conventions:

  1. Assembly files that must be pre-processed use the extension .S

  2. Assembly files that are ready to be assembled use the extension .s

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

Policies & Procedures


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