how to add system call
Any body here can tell how can I add new system call without recompiling the kernel i.e. dynamically at runtime?
|
Quote:
Now that you’ve read and understood my disclaimer, I’ll try to answer your original question: YOU CANNOT ADD A NEW SYSCALL WITHOUT RECOMPILING THE KERNEL! The sycall table is a fixed-size array of pointers to functions (making it incredibly difficult to find and expand in-place). Additionally, __NR_syscall_max is used throughout the magic that makes kernel syscalls work, and it would be difficult to patch the live kernel image to change all occurrences this value (since it is not a symbol but a preprocessor macro). You can, however, do something almost as effective. You see, along the timeline of kernel development (with respect to kernel-userspace relations), system calls have been replaced with newer system calls. But in order to keep a constant userspace API, the system call numbers have been left the same. So what happens to the deprecated system call? Well, for awhile it’s kept and both syscalls can be used simultaneously. Eventually, kernel development catches up with it, and it can no longer be maintained. As such the now-obsolete function is removed from the syscall table. What’s left is a “hole” (a number in the table which corresponds to no function). Nowadays, this hole is made to point to a placeholder function known in kernel-space as sys_ni_syscall(). Since nobody uses any of these holes any longer, the holes can be filled with whatever function you want. The problem is that the holes occur in differing amounts and in different locations depending on the architecture. Additionally, you can always go back to using an old enough kernel in which the hole is no longer a hole. In such a case, it might not really matter unless someone uses it. But if you use an ancient userspace with an ancient kernel, and your module usurps a system call which is not a hole, you will seriously break something. So as a rule of thumb, it would be best to fill the oldest holes first. You to find all holes for a given arch, run a recursive grep of “sys_ni_syscall” from within the arch’s subdir in the kernel tree. For example, in 2.6.22 and i386, we find holes in syscalls numbered 17, 31, 32, 35, 44, 53, 56, 58, 98, 113, 127, 130, 137, 167, 188, 189, 222, 223, 251, 273, and 285. Basically, the hole replacement technique goes something like this: Code:
#define __NR_fill_hole 17 |
Wow. This. Is. Positively. Evil.
Can't wait to try it. |
Another caveat: this becomes much more complicated for archs that implement vsyscalls. For example, on x86_64, you will have to fill a hole in the normal sys_call_table, and you will need to fill a (different numbered hole) in the i386 table conditional on whether the kernel supports them (which it usually does). Then, to access to the system call would depend on whether you use 32-bit or 64-bit assembly.
Here’s a simple example calling the sys_exit syscall from userspace. In the first code sample, we merely call the x86_64 version of sys_exit(0): Code:
.section .text Code:
.section .text |
All times are GMT -5. The time now is 02:58 AM. |