So as a part of my GSoC’18 project to implement Kernel Address Sanitizer in the NetBSD kernel, I have been trying to add a KASAN option to the kernel to build it with the Address Sanitizer option. For now what I have done is to create a set of dummy functions to make the build work. I will be modifying these in due course.
Intro
Our aim is to add an option in the kernel which will help us use a specific compiler feature or something similar in the kernel. This is usually done with the kernel config file.
If you are trying to build a amd64 kernel of NetBSD. You will find the conf files in sys/arch/amd64/conf
There will be several config files. For our purpose, we will copy the GENERIC config file and use it.
$ cp GENERIC
If you want to add a feature for all the architectures we can also add the file in sys/kern. You would still require to modify config files of all the architectures. So I recommend that you try it with a single arch and then generalize it.
I am gonna continue this article with amd64 as the architecture and KASAN as the option.
Building the Kernel
Once you have copied the config file, building the kernel requires slight changes.
$ ./build.sh -j4 -u -U -m amd64 -T ../tooldir/ kernel=
Keep in mind that you use ‘-u’ so that it doesn’t rebuild everything every time.
Our Targets
Now we need to identify the files that we need to edit. This depends on the architecture. Once in the conf/ folder of the architecture, you are interested in.
You will notice the following files:
- files.amd64
- Makefile.amd64
Step 1: Adding the option in the Config file
This is pretty simple and requires only adding the following lines.
Makeoptions is used to create a macro in the kernel makefile. Options is roughly translated to -D to the preprocessor.
This will create an option KASAN and initialize it to 1.
Additionaly if the changes minimal you can create a seperate file and include GENERIC file into it. Check out GENERIC_KASAN
Step 2: Adding the Module with the stubs
This requires you to know all the stubs that you might require during compilation. In my case, I ran the build without module and found a lot of undefined reference errors which I used to guide me to help me with creating the stubs.
Once you have the C file with all the functions and structures in it. You need to place it in the amd64/amd64 folder. Here I added kasan.c to the folder.
Sample module:
void __asan_loadN(unsigned long, size_t);
void __asan_loadN(unsigned long addr, size_t size)
{}
Empty functions to make the kernel build but do nothing else.
Step 3: Adding the Module file
Now we need to add the module file/files to the files.amd64 so that they are used during build time.
You might want to take a look at config(9) regarding the build rules. In the file, we need to add a start code to our file.
file arch/amd64/amd64/kasan.c machdep
To add a options header (Commonly used for new features) you can add the following line to the file.
defflag opt_kasan.h KASAN
Refer to config(9) for more information.
Step 4: Modifying the Makefile
Now finally we need to modify the Makefile to add the necessary flags and all there.
We have already defined the KASAN with the conf file. HAVE_GCC is used to check whether we are building with a gcc toolchain.
.if ${KASAN:U0} > 0 && ${HAVE_GCC:U0} > 0
CFLAGS+= -fsanitize=kernel-address
.endif
Here we are checking whether the value of KASAN is greater than 0. If present we are adding the required compiler flags to the compilation process.
Final Steps
Now that’s all of the modifications that are required. Try building the kernel with the new config file.
Hope this was helpful to you.
I am adding a link to the commit I have for reference(These may be not very clean since this in on a private branch).
Excellent tutorial!
LikeLike
Thanks Harry.
LikeLike