Is there a libc in kernel space? - linux

Is there a libc in kernel space? I mean you have to build kernel against some libc right? So Is there a libc (probably statically-linked) sitting within kernel space?
If yes, how is this related to userland glibc? Must they be the same version?

There is actually no libc in kernel space. Libc is user-space library, and you can't use it from kernel-space.
But almost all functions from libc that make sense in kernel space are ported. You can find headers in include/linux/ usually.
As far as I know these two implementations don't share codebase.

Some of the functions that are available in libc are implemented inside the kernel code, for example there's a printf function that works as the normal (at least as far as the kernel code it self requires).
This means that while it looks like the code uses libc (by the functions that seem to be available) there actually no need to link it with a library (AFAIK).

Related

Who zeroes pages while calling calloc() in Linux?

I am aware that an implementer has a choice of whether he wants to zero a malloc page or let OS give him a zeroed page (for more optimization purposes).
My question is simple - in Ubuntu 14.04 LTS which comes with linux kernel 3.16 and gcc 4.8.4, who will zero my pages? Is it in user land or kernel land?
It can depend on where the memory came from. The calloc code is userland, and will zero a memory page that gets re-used by a process. This happens when the memory is previously used and then freed, but not returned to the OS. However, if the page is newly allocated to the process, it will come already cleared to 0 by the OS (for security purposes), and so does not need to be cleared by calloc. This means calloc can potentially be faster than calling malloc followed by memset, since it can skip the memset if it knows it will already by zeroed.
That depends on the implementer of your standard library, not on the host system. It is not possible to give a specific answer for a particular OS, since it may be the build target of multiple compilers and their libraries - including on other systems, if you consider the possibility of cross-compiling (building on one type of system to target another).
Most implementations I've seen of calloc() use a call of malloc() followed by either a call of memset() or (with some implementations that target unix) a legacy function called bzero() - which is, itself, sometimes replaced by a macro call that expands to a call of memset() in a number of recent versions of libraries.
memset() is often hand-optimised. But, again, it is up to the implementer of the library.

How to link kernel functions to user-space program?

I have a user-space program (Capstone). I would like to use it in FreeBSD kernel. I believe most of them have the same function name, semantics and arguments (in FreeBSD, the kernel printf is also named printf). First I built it as libcapstone.a library, and link my program with it. Since the include files are different between Linux user-space and FreeBSD kernel, the library cannot find symbols like sprintf, memset and vsnprintf. How could I make these symbols (from FreeBSD kernel) visible to libcapstone.a?
If directly including header files like <sys/systm.h> in Linux user-space source code, the errors would be like undefined type u_int or u_char, even if I add -D_BSD_SOURCE to CFLAGS.
Additionally, any other better ways to do this?
You also need ; take a look at kernel man pages, eg "man 9 printf". They list required includes at the top.
Note, however, that you're trying to do something really hard. Some basic functions (eg printf) might be there; others differ completely (eg malloc(9)), and most POSIX APIs are simply not there. You won't be able to use open(2), socket(2), or fork(2).

How to invoke newly added system call by the function id without using syscall(__NR_mysyscall)

I am working with Linux-3.9.3 kernel in Ubuntu 10.04. I have added a basic system call in the kernel directory of the linux-3.9.3 source tree. I am able to use it with syscall() by passing my newly system call number in it as an argument. But I want to invoke it directly by using its method name as in the case of getpid() or open() system calls. Can any one help me to add it in GNU C library. I went through few documents but did not get any clear idea of how to accomplish it.
Thanks!!!
Assuming you are on a 64 bits Linux x86-64, the relevant ABI is the x86-64 ABI. Read also the x86 calling conventions wikipage and the linux assembly howto and syscalls(2)
So syscalls are using a different convention than ordinary function calls (e.g. all arguments are passed by registers, error condition could use the carry bit). Hence, you need a C wrapper to make your syscall available to C applications.
You could look into the source code of existing C libraries, like GNU libc or musl libc (so you'll need to make your own library for that syscall).
The MUSL libc source code is very readable, see e.g. its src/unistd/fsync.c as an example.
I would suggest wrapping your new syscall in your own library without patching libc. Notice that some uncommon syscalls are sitting in a different library, e.g. request_key(2) has its C wrapper in libkeyutils

symbols in kernel module

I built linux kernel module with SSP support for mips architecture. I added -fstack-protector-all to compilation flags. But after loading this module I've got undefined references to __stack_chk_guard and __stack_chk_fail. But I added libssp.so to linker. It looks like I should export those symbols in kernel something like this:
EXPORT_SYMBOL(__stack_chk_guard);
Because my kernel is old and didn't contain them yet. But unfortunately I should use this version.
My question is: why user space can use this symbols from toolchain library, but kernel space don't ?
I think, I missed some linux kernel essentials.
You can't link the kernel to shared libraries. If you have a static library of libssp, it MAY work - but it would require that the library isn't calling something else that would cause problems in the kernel.
In general, stack-checking isn't something that you should be doing on the kernel - I'm pretty sure it serves no particularly good purpose [I'm also pretty sure that the kernel uses a "guard page" for each kernel stack].
You cannot use shared libraries anywhere in kernel space (including as part of kernel modules).
You could think of kernel modules themselves as an equivalent of shared libraries in kernel space but with lot of differences.
Kernel modules can depend on exported symbols from other kernel modules.
My question is: why user space can use this symbols from toolchain
library, but kernel space don't ?
Nothing in kernel space has access to the libc C library. Kernel has its own set of builtin standard string manipulation functions, etc. that you could use instead. The toolchain libraries are built on top of libc.
+1 on Mats's answer. You could use a static library as long as it does not depend on standard C libraries like libc

Why can't we use C standard library functions in kernel development?

I just got started with learning kernel development and had a small doubt. Why can't we use c functions in kernel development after linking it with the c library? Why is it that the kernel is never linked with a c library but has its own implementation of some standard c functions like printk() instead of printf(). IF the kernel is written in c and compiled with the help of a c compiler then why can't we use the standard function from the c library?
Because the GNU C Library which you are familiar with is implemented for user mode, not kernel mode. The kernel cannot access a userspace API (which might invoke a syscall to the Linux kernel).
From the KernelNewbies FAQ
Can I use library functions in the kernel ?
System libraries (such as glibc, libreadline, libproplist, whatever) that are typically available to userspace programmers are unavailable to kernel programmers. When a process is being loaded the loader will automatically load any dependent libraries into the address space of the process. None of this mechanism is available to kernel programmers: forget about ISO C libraries, the only things available is what is already implemented (and exported) in the kernel and what you can implement yourself.
Note that it is possible to "convert" libraries to work in the kernel; however, they won't fit well, the process is tedious and error-prone, and there might be significant problems with stack handling (the kernel is limited to a small amount of stack space, while userspace programs don't have this limitation) causing random memory corruption.
Many of the commonly requested functions have already been implemented in the kernel, sometimes in "lightweight" versions that aren't as featureful as their userland counterparts. Be sure to grep the headers for any functions you might be able to use before writing your own version from scratch. Some of the most commonly used ones are in include/linux/string.h.
Whenever you feel you need a library function, you should consider your design, and ask yourself if you could move some or all the code into user-space instead.
If you need to use functions from standard library, you have to re-implement that functionality because of a simple reason - there is no standard C library.
C library is basically implemented on the top of the Linux kernel (or other operating system's kernel).
For instance, C library's mkdir(3) function is basically nothing more than a wrapper for Linux kernel's system call mkdir(2).
http://linux.die.net/man/3/mkdir
http://linux.die.net/man/2/mkdir

Resources