Functions available when writing a new system call - c

For a college assignment we have to add a system call to the Linux kernel. I have "Hello, World" done no problem. In terms of adding a more complicated call, I know (or at least think) I can't use C functions like malloc, but I'm wondering can I use syscall() to use other system calls?

The kernel has its own specific calls for pretty much everything. You don't have access to system calls or <sys/xxxx.h> header files.
For your exmaple, yes, you can't use malloc() but you can use kmalloc()
In older versions of the kernel (2.4) you could use syscall() via: syscallN() macros. I'm pretty sure that's been removed.
In general syscalls() from the kernel is not a good idea. Really system calls are just a way of user space going into the kernel to do something, so if you're already in the kernel there should be a better way to do what you're trying to do.

Related

Linux Kernel - Read/Write to a File

I'm working on a LKM which needs to retrieve and write a certain set of information to files. I looked up common ways to do so, but could not find a working one for Linux 4.x. I also found out that it is possible to retrieve system calls from memory and effectively call them.
As I found currently no better way I'd be interested if it'd be feasible to find the system call table, and call open, read/write and close this way.
This is strongly discouraged in most situations.
https://www.linuxjournal.com/article/8110 was a really good read for me the first time I thought I had to do this as well.
From within the Linux kernel, however, reading data out of a file for configuration information is considered to be forbidden. This is due to a vast array of different problems that could result if a developer tries to do this.
Indeed this is possible to do using system calls from within the kernel, but the practice of calling system calls from within the kernel is also generally discouraged. They're designed as interfaces for userspace applications to ask things of the kernel, not for the kernel to get itself to do work.
What kind of files do you want to manipulate from within the kernel? If the kind of file you'd like to manipulate is provided by the proc filesystem or the sysfs filesystem or the dev filesystem, you can modify the contents of the file from within the kernel (since the kernel provides these to userspace itself) -- this should be done NOT with file manipulation calls. If it's a normal userspace file, almost never do you want the kernel to be able to modify it.
If you provide more specifics I'd be interested to hear them, but this is usually a bad idea.

why library functions should not be used in creating an os?

I am planning to study about operating systems. I met with 2 doubts. Why we should not use library functions while creating an operating system?
What is the drawback in it?
Why we should not use library functions while creating an operating system? What is the drawback in it?
It depends on what you mean by "library functions".
You absolutely should try to use someone else's version of the functions from <string.h>, for example. If you're writing an OS, you've got plenty to do, why re-invent the wheel with something simple like strcpy?
You should use whatever open-source code you can that has no dependencies. I mean simple "leaf" functions like strcpy that have no dependencies. If you look at the Linux kernel source code, you will certainly see standard library functions like memcpy, and strlen, etc. But you'll also see things like strncpy_from_user which are adapted to particular uses in the kernel (in this case copying a string from user-space to kernel-space).
What you shouldn't try to use (if it isn't obvious already) are things like fopen. fopen is a wrapper around some code that makes a system call to the kernel to handle the actual opening of a file. Well clearly, if you are the kernel, you can't use this in your kernel.

Catching a system call just before control enters a shared library

I have wrapped a number of system call function like write(), open() etc and LD-PRELOAD is used to override the original system calls. Moreover I have defined a few more functions and made this too a shred library.
I would like to catch all system calls from different application processes to these shared libraries before they enter the shared library. How can i do that?
Thanks
LD_PRELOAD is not necessarily a good way to interpose system calls, because a) it only allows you to intercept library calls and b) it only allows you to intercept library calls. ;)
A) While in general, system calls are wrapped by the shared libC in your system, no one prevents you from calling a system call yourself, e.g., but setting up the right register content and then issuing INT 0x80 on an x86 system. If the program you're interested in does so, you'll never catch those with LD_PRELOAD-based libc-interposition.
B) While in general, most programs use the shared libC in your system to make system calls, sometimes applications are linked statically, which means the libC code is part of the application and does not come from the shared lib. In such cases, LD_PRELOAD also does not help.
A comment already suggested to use strace/ltrace -- my generalized advice would be to have a look at ptrace() which both of these tools use and which should give you what you want without the need of modifying the kernel.
Patch-free User-level Link-time intercepting of system calls and interposing on library functions may do the trick but I have not tested it.
I'm pretty sure the only way you can do this is by modifying the system call table. HIDS systems (such as Samhain) will report this as an intrusion and Linux kernel developers frown upon this, heavily. The implementation details are very specific to the OS (i.e. what works on FreeBSD won't necessarily work on Linux), but the general implementation details are going to be the same. A kernel module might be a better way to go with cleaner, more standardized APIs.

Writing a POSIX-compliant kernel

I've wanted to write a kernel for some time now. I already have a sufficient knowledge of C and I've dabbled in x86 Assembler. You see, I've wanted to write a kernel that is POSIX-compliant in C so that *NIX applications can be potentially ported to my OS, but I haven't found many resources on standard POSIX kernel functions. I have found resources on the filesystem structure, environment variables, and more on the Open Group's POSIX page.
Unfortunately, I haven't found anything explaining what calls and kernel functions a POSIX-compliant kernel must have (in other words, what kind of internal structure must a kernel have to comply with POSIX). If anyone could find that information, please tell me.
POSIX doesn't define the internal structure of the kernel, the kernel-to-userspace interface, or even libc, at all. Indeed, even Windows has a POSIX-compliant subsystem. Just make sure the POSIX interfaces defined at your link there work somehow. Note, however, that POSIX does not require anything to be implemented specifically in the kernel - you can implement things in the C library using simpler kernel interfaces of your own design where possible, if you prefer.
It just so happens that a lot of the POSIX compliant OSes (BSD, Linux, etc) have a fairly close relationship between many of those calls and the kernel layer, but there are exceptions. For example, on Linux, a write() call is a direct syscall, invoking a sys_write() function in the kernel. However on Windows, write() is implemented in a POSIX support DLL, which translates the file descriptor to a NT handle and calls NtWriteFile() to service it, which in turn invokes a corresponding system call in ntoskrnl.exe. So you have a lot of freedom in how to do things - which makes things harder, if anything :)
The opengroup.org leaves the decisions about kernel syscalls to each implmentation.
write(), for example has to look and behave as stated, but what it calls underneath is not defined. A lot of calls like write, read, lseek are free to call whatever entrypoint they want inside the kernel.
So, no, there really is nothing that says you have to have a certain function name with a defined set of semantics available in the kernel. It just has to available in the C runtime library.

What's the difference between "C system calls" and "C library routines"?

There are multiple sections in the manpages. Two of them are:
2 Unix and C system calls
3 C Library routines for C programs
For example there is getmntinfo(3) and getfsstat(2), both look like they do the same thing. When should one use which and what is the difference?
System calls are operating system functions, like on UNIX, the malloc() function is built on top of the sbrk() system call (for resizing process memory space).
Libraries are just application code that's not part of the operating system and will often be available on more than one OS. They're basically the same as function calls within your own program.
The line can be a little blurry but just view system calls as kernel-level functionality.
Libraries of common functions are built on top of the system call interface, but applications are free to use both.
System calls are like authentication keys which have the access to use kernel resources.
Above image is from Advanced Linux programming and helps to understand how the user apps interact with kernel.
System calls are the interface between user-level code and the kernel. C Library routines are library calls like any other, they just happen to be really commonly provided (pretty much universally). A lot of standard library routines are wrappers (thin or otherwise) around system calls, which does tend to blur the line a bit.
As to which one to use, as a general rule, use the one that best suits your needs.
The calls described in section 2 of the manual are all relatively thin wrappers around actual calls to system services that trap to the kernel. The C standard library routines described in section 3 of the manual are client-side library functions that may or may not actually use system calls.
This posting has a description of system calls and trapping to the kernel (in a slightly different context) and explains the underlying mechanism behind system calls with some references.
As a general rule, you should always use the C library version. They often have wrappers that handle esoteric things like restarts on a signal (if you have requested that). This is especially true if you have already linked with the library. All rules have reasons to be broken. Reasons to use the direct calls,
You want to be libc agnostic; Maybe with an installer. Such code could run on Android (bionic), uClibc, and more traditional glibc/eglibc systems, regardless of the library used. Also, dynamic loading with wrappers to make a run-time glibc/bionic layer allowing a dual Android/Linux binary.
You need extreme performance. Although this is probably rare and most likely misguided. Probably rethinking the problem will give better performance benefits and not calling the system is often a performance win, which the libc can occasionally do.
You are writing some initramfs or init code without a library; to create a smaller image or boot faster.
You are testing a new kernel/platform and don't want to complicate life with a full blown file system; very similar to the initramfs.
You wish to do something very quickly on program startup, but eventually want to use the libc routines.
To avoid a known bug in the libc.
The functionality is not available through libc.
Sorry, most of the examples are Linux specific, but the rationals should apply to other Unix variants. The last item is quite common when new features are introduced into a kernel. For example when kqueue or epoll where first introduced, there was no libc to support them. This may also happen if the system has an older library, but a newer kernel and you wish to use this functionality.
If your process hasn't used the libc, then most likely something in the system will have. By coding your own variants, you can negate the cache by providing two paths to the same end goal. Also, Unix
will share the code pages between processes. Generally there is no reason not to use the libc version.
Other answers have already done a stellar job on the difference between libc and system calls.

Resources