Adding a New System Call in Linux Kernel 3.3

Adding a new system call in Linux kernel 3.3

I think in kernel 3.3 its shifted here

http://lxr.free-electrons.com/source/arch/x86/syscalls/

Adding new System Call in Minix

I figured out what was the problem, so i will post answer if someone needs this in future. I did everything well in this example but i failed to compile kernel.

The location was correct which is usr/src/releasetools, but command needed is make hdboot. Also i figured out my PC somehow wasnt working well with this virtual machines and i had many errors while compiling even though i didn't change anything. When i switched to laptop everything worked fine.

My conclusion is sometimes there is just something wrong on your machine so you should try and test problems on different ones

How to write system calls on debian/ubuntu

This is just example how to write a simple kernel system call.
Consider the following C function system_strcpy() that simply copies one string into another: similar to what strcpy() does.

#include<stdio.h>

long system_strcpy(char* dest, const char* src)
{
int i=0;
while(src[i]!=0)
dest[i]=src[i++];

dest[i]=0;
return i;
}

Before writing, get a kernel source tar and untar it to get a linux-x.x.x directory.

File 1: linux-x.x.x/test/system_strcpy.c
Create a directory within the linux-x.x.x, named test and save this code as file system_strcpy.c in it.

#include<linux/linkage.h>
#include<linux/kernel.h>
asmlinkage long system_strcpy(char*dest, const char* src)
{
int i=0;
while(src[i]!=0)
dest[i]=src[i++];

dest[i]=0;
return i;
}

File 2: linux-x.x.x/test/Makefile
Create a Makefile within the same test directory you created above and put this line in it:

obj-y := system_strcpy.o

File 3: linux-x.x.x/arch/x86/kernel/syscall_table_32.S
Now, you have to add your system call to the system call table.
Append to the file the following line:

.long system_strcpy

NOTE: For Kernel 3.3 and higher versions.

*Refer:linux-3.3.xx/arch/x86/syscalls/syscall_64.tbl*

And in there, now add at the end of the following series of lines:

310 64 process_vm_readv sys_process_vm_readv

311 64 process_vm_writev sys_process_vm_writev

312 64 kcmp sys_kcmp

313 64 system_strcpy system_strcpy

The format for the 3.3 version is in:
number abi name entry point

File 4: linux-x.x.x/arch/x86/include/asm/unistd_32.h

NOTE: This section is redundant for 3.3 and higher kernel versions

In this file, the names of all the system calls will be associated with a unique number. After the last system call-number pair, add a line

#define __NR_system_strcpy 338

(if 337 was the number associated with the last system call in the system call-number pair).

Then replace NR_syscalls value, stating total number of system calls with (the existing number incremented by 1) i.e. in this case the NR_syscalls should've been 338 and the new value is 339.

#define NR_syscalls 339

File 5: linux-x.x.x/include/linux/syscalls.h

Append to the file the prototype of our function.

asmlinkage long system_strcpy(char *dest,char *src);

just before the #endif line in the file.

File 6: Makefile at the root of source directory.

Open Makefile and find the line where core-y is defined and add the directory test to the end of that line.

core-y += kernel/ mm/ fs/ test/

Now compile the kernel. Issue:
make bzImage -j4

Install the kernel by executing the following command as root(or with root permissions):
make install

Reboot the system.

To use the recently created system call use:

syscall(338,dest,src); (or syscall(313,dest,src); for kernel 3.3+) instead of the regular strcpy library function.

#include "unistd.h"
#include "sys/syscall.h"
int main()
{
char *dest=NULL,*src="Hello";
dest=(char*)malloc(strlen(src)+1);
syscall(338,dest,src);//syscall(313,dest,src); for kernel 3.3+
printf("%s \n %s\n",src,dest);
return 0;
}

Instead of numbers like 313,etc in syscall, you can also directly use __NR_system_strcpy

This is a generic example. You will need to do a little experimentation to see what works for your specific kernel version.

undefined reference to system call added to kernel

Search your syscall_64.tbl file for "sys_hello_rana". I am guessing you named your syscall as "sys_hello_rana" in syscall table but you used a different name(sys_husky1) when you defined it.

Is writing kernel memory with system call available?

Let's break your questions down one by one.

Yes you can write to kernel memory via system calls directly if you implemented one that allowed writing to arbitrary locations in memory. Whether or why you would want something like this is another question. Something like this would pose a huge security risk. For example, any process can elevate their privileges or install rootkits in the kernel easily using your system call.

However, Linux does have an interface for reading and writing to kernel memory. Have a look at /dev/kmem. It allows you to open kernel memory as a 'file', seek around and read and write to it.

Implementing Minix 3.3 system call as libc library call

Ok, so I was putting SRCS+=... in libc/sys/Makefile.inc but this Makefile is mostly under a conditional which I just realized is false. I moved over to libc/misc and added everything there and it worked like a charm.



Related Topics



Leave a reply



Submit