$ man tshabbic.projects.lkb-sysc
LKB-SYSC(8)Linux Kernel Based System Call ImplementationLKB-SYSC(8)
Name

lkb-sysc -- Linux Kernel Based System Call Implementation

Synopsis

syscall(451, char* buf)

Description

Replaces all the vowels of a given string with the capitalized first letter of the author's login name (T). Note that the strings passed into the system call must be mutable, meaning of type char[], or in other words, defined in virtual memory regions .data (Read/Write), .bss, or in a function's call stack all, otherwise the system call will fail to modify the string as the virtual memory page that houses said string does not have the "Write" bit enabled, unlike the former three regions.

This was built and tested on Debian 12 (Bookworm), x86_64 system. Before touching anything, I booted my "known good" kernel (6.1.0-17) and recorded its version with uname -r, so that a panic in my custom kernel would leave me something to revert to. After installing the build dependencies and linux-source, the source was extracted into pa2 (the second programming assignment of our OS course), the known good kernel's config was copied from /boot as .config, and the local version string was set to -tshabbic-pa2 through make menuconfig, so the custom kernel could not be confused with the known good one at the GRUB menu or in uname -r.

A parallel make -j $(nproc) compiled the kernel, which took a bit over 10 minutes on an i9-13900K, after which modules_install and make install placed everything in /boot and updated GRUB. As a warm-up, a small loadable module (tshabbic.c, built with obj-m) logged a greeting on load and the current PID and process name on unload, which showed a new PID every time since each rmmod is a fresh process.

The system call lives in my_syscall/my_syscall.c, built directly into the kernel with obj-y rather than as a module. Defined with SYSCALL_DEFINE1, it returns -1 for a NULL pointer or a string over 32 characters (measured with strnlen_user), otherwise using copy_from_user to bring the string into kernel space, logging it with printk, replacing each lowercase vowel with T, logging the result, and copying it back with copy_to_user, returning the number of replacements. Registering it took three edits: adding my_syscall/ to the core-y line of the top-level Makefile, a 451 entry in syscall_64.tbl, and a prototype in syscalls.h. After rebuilding and rebooting, grep tshabbic /proc/kallsyms confirmed the kernel knew about it.

With no libc wrapper available, a small C program called it through syscall with number 451, using one local char array over 32 characters and one under. With dmesg -w open alongside, the long string returned -1 untouched, while the short one returned its vowel count along with matching before: and after: lines in the kernel log.


Screenshot of the syscall's output and the kernel log
History

This assignment was completed during the Spring 2024 semester for CS 492 - Operating Systems @ Stevens Institute of Technology.

A system call with numeric identifier 451, cachestat, was added in Linux Kernel version 6.5 in August 27 2023. This was a non-issue for this assignment due to the kernel version Debian 12 shipped with at the time being 6.1.0-17.