11

I want to add a particular new system call in the linux kernel 3.2.x but as a loadable kernel module (as I don't want to recompile the kernel again and again)

I read through many posts on internet and also on SO, and some places claim that implementing system calls as loadable modules is not possible, while others say it is possible.

Which is it? How is it done if it's possible?

3
  • This question is off-topic here: Unix & Linux is about usage and administration, not about programming. You should ask on Stack Overflow. Don't be so vague: link to the posts you found on Stack Overflow, and explain what you found inconclusive or contradictory. Sep 10, 2012 at 22:19
  • 3
    I believe that this question is much more related to Linux as an OS than to programming itself. It is also quite important to know what are the possibilities of extending our system abilities and what are its limits. This, for example, makes you understand why some features are not possible to implement as loadable module and needs kernel patching. Knowing why it is like this may also give you some ideas of security vs usability kernel developers have to make. Would that question be more on topic if OP would ask only if it's possible and why not and not how to implements this? Sep 16, 2012 at 20:09
  • 1
    There were numerous <stroke>flames</stroke> discussions on the Linux Kernel Mailing List, for example reiserfs used its own syscalls, which wasn't really beloved by some core developers, included Linus. In your case I would simply use ioctl()s for the task, they are easily modularizable. Afaik the main reason behind making this as hard as it is possible that the number of the syscalls is a highly hardcoded thing and nobody wants the chaos what it would get into the picture. But there are numerous kernel interfaces to reach the same functionality, for example sysfs, ioctls or such.
    – peterh
    Sep 2, 2015 at 19:59

2 Answers 2

14

It is not possible because system call table (called sys_call_table) is a static size array. And its size is determined at compile time by the number of registered syscalls. This means there is no space for another one.

You can check implementation for example for x86 architecture in arch/x86/kernel/syscall_64.c file, where sys_call_table is defined. Its size is exactly __NR_syscall_max+1. __NR_syscall_max is defined in arch/x86/kernel/asm-offsets_64.c as sizeof(syscalls) - 1 (it's the number of last syscall), where syscall is a table with all the syscalls.

One possible solution is to reuse some existing (or deprecated one if your architecture has one, see sys_setaltroot for example) syscall number with yours as this won't require more space in memory. Some architectures may also have holes in the syscall table (like 64 bit version of x86) so you can use this too.

You can use this technique if you are developing new syscall and just want to avoid rebooting while experimenting. You will have to define your new system call, find existing entry in syscall table and then replace it from your module.

Doing this from kernel module is not trivial as kernel does not export sys_call_table to modules as of version 2.6 (the last kernel version that had this symbol exported was 2.5.41).

One way to work around this is to change your kernel to export sys_call_table symbol to modules. To do this, you have to add following two lines to kernel/kallsyms.c (don't do this on production machines):

extern void *sys_call_table;
EXPORT_SYMBOL(sys_call_table);

Another technique is to find syscall table dynamically. You iterate over kernel memory, comparing each word with a pointer to known system call function. Since you know the offset of this know syscall in the table, you can compute table beginning address.

0
1

Unfortunately you can't add system calls to kernel as loadable modules. You have to take the pain of compiling the kernel each time you add a new system call.

Not the answer you're looking for? Browse other questions tagged .