Replacing a kernel function by using loadable kernel modules - c

I am trying to replace a kernel function with a kernel module, and come across the following solusion proposed by kmm (https://stackoverflow.com/a/1242232/6438341)
However, it seems that the kernel does not allow copying anything to the address of 'real_printk'. The kernel complains: "BUG: unable to handle kernel paging request at ffffffff81774863", in which ffffffff81774863 is the address of printk that was found in System.map or /proc/kallsyms.
Anyone knows how to fix it?

At a guess, I'd say it's probably because you're running a kernel that write-protects its text pages. You will need to set those pages as writable before modifying them.
HOWEVER, keep in mind that that answer you're looking at is six years old. In the time since it was posted, a number of much better approaches to live kernel patching have emerged, including kpatch, SUSE Live Patching, and KernelCare. (Underneath, there's also ftrace, which can be used to dynamically instrument functions.) You should take a close look at these before trying to build your own patching solution from scratch.

Related

Get /proc/<pid>/map info with sysctl call under mac os

I wanted to use /proc/<pid>/map directory in order to get info about virtual memory of a process (especially about its shared libraries). Since mac os doesn't have one I'm trying to find other ways. One of them seems to be sysctl call but I don't quite understand how to use it for such purpose. Are there any examples? I know it also can be done via some mach_vm interface calls but documentation is quite pour. Maybe you know any other ways of reading process memory? My mac os version is Darwin by the way.
Note: the purpose is to do this without using any utilities or fork/exec calls. I also don't want any pseudofs to be mounted.
macOS' virtual memory subsystem is in the Mach-inherited part of the kernel, so those APIs are definitely the ones to use. For inspecting regions, look at mach_vm_region() (called vm_region in the original Mach - you will find more documentation for that), for reading memory, use mach_vm_read().
You may also find the vmmap command line utility to come in useful for exploration.

File in both KLM and user space

I remembering reading this concept somewhere. I do not remember where though.
I have a file say file.c, which along with other files I compile along with some other files as a library for use by applications.
Now suppose i compile the same file and build it with a Kernel module. Hence now the same file object is in both user space and kernel space and it allows me to access kernel data structures without invoking a system call. I mean i can have api's in the library by which applications can access kernel data structures without system calls. I am not sure if I can write anything into the kernel (which i think is impossile in this manner), but reading some data structures from kernel this way would be fine?
Can anyone give me more details about this approach. I could not find anything in google regarding this.
I believe this is a conceptually flawed approach, unless I misunderstand what you're talking about.
If I understand you correctly, you want to take the same file and compile it twice: once as a module and once as a userspace program. Then you want to run both of them, so that they can share memory.
So, the obvious problem with that is that even though the programs come from the same source code, they would still exist as separate executables. The module won't be its own process: it only would get invoked when the kernel get's going (i.e. system calls). So by itself, it doesn't let you escape the system call nonsense.
A better solution depends on what your goal is: do you simply want to access kernel data structures because you need something that you can't normally get at? Or, are you concerned about performance and want to access these structures faster than a system call?
For (1), you can create a character device or a procfs file. Both of these allow your userspace programs to reach their dirty little fingers into the kernel.
For (2), you are in a tough spot, and the problem gets a lot nastier (and more insteresting). To solve the speed issue, it depends a lot on what exact data you're trying to extract.
Does this help?
There are two ways to do this, the most common being what's called a Character Device, and the other being a Block Device (i.e. something "disk-like").
Here's a guide on how to create drivers that register chardevs.

Making a new filesystem

I'm looking to make a custom filesystem for a project I'm working on. Currently I am looking at writing it in Python combined with fusepy, but it got me wondering how a compiled non-userspace filesystem is made in Linux. Are there specific libraries that you need to work with or functions you need to implement for the mount command to work properly. Overall I'm not sure how the entire process works.
Yup you'd be programming to the kernel interfaces, specifically the VFS layer at a minimum. Edit Better link [1]
'Full' documentation is in the kernel tree: http://www.mjmwired.net/kernel/Documentation/filesystems/vfs.txt. Of course, the fuse kernel module is programmed to exactly the same interface
This, however, is not what you'd call a library. It is a kernel component and intrinsically there, so the kernel doesn't have to know how a filesystem is implemented to work with one.
[1] google was wrong: the first hit wasn't the best :)
If you'd like to write it in Python, fuse is a good option. There are lots of tutorials for this, such as the one here: http://sourceforge.net/apps/mediawiki/fuse/index.php?title=FUSE_Python_tutorial
In short: Linux is a monolithic kernel with some module-loading capabilities. That means that every kernel feature (filesystems, scheduler, drivers, memory management, etc.) is part of the one big program called Linux. Loadable modules are just a specialized way of run-time linking, which allows the user to pick those features as needed, but they're all still developed mostly as a single program.
So, to create a new filesystem, you just add new C source code files to the kernel code, defining the operations your filesystem has to perform. Then, create an initialization function that allocates a new instance of the VFS structure, fills it with the appropriate function pointers and registers with the VFS.
Note that FUSE is nothing more than a userlevel accessible API to do the same, so the FUSE hooks correspond (roughly) to the VFS operations.

Compiling Kernel code in Linux

Okay, I'm reading about Linux kernel development and there are some code snippets using kernel's data structures and stuff. Let's say I'd like to experiment with them, e.g. there's a very simple snippet:
#include <../../linux-2.6.37.1/include/linux/sched.h>
struct task_struct *task;
for_each_process(task) {
printk("%s[%d]\n", task->comm, task->pid);
}
Seems pretty simple, eh? Now then, I can't possibly build the thing. I am using NetBeans. The sched.h is the correct file as if one can CTRL+clicks on it, one is brought to the right file.
Do I need to include somehow my sample file and build the whole kernel from the Makefile? I just wished to see that it builds and possibly that it would work. If I need to build the whole kernel how would I actually test my stuff?
I must be making something really stupid as I am very new to kernel development. I am quite a bit lost.
Thanks guys!
You do not need to compile the whole kernel, but you have to at least create a kernel module, which is far easier to compile. You should have a look at a tutorial, such as this, or even a full blown book like this.
Keep in mind that not all kernel code can be moved to a module - just those that use the public (exported) interfaces of the kernel. Code that is intrinsic to the kernel core parts (e.g. the VM or the scheduler) is probably inaccessible from the rest of the kernel.
Also keep in mind that trying out kernel code on your development machine is not advised - a
slight mistake can easily bring the whole system down. You should look at trying out your kernel code in a separate virtual machine e.g. in VirtualBox.
A detail that makes thing harder: in general you can only insert a module in the kernel that it was built for. A module compiled on the host system can be used on the testing VM if and only if the kernel is identical, i.e. the same kernel package version from the same distribution. Considering that you will want to upgrade your host distribution, in my opinion it is just simpler to build the module on the testing system.
Since you need a full development suite for C, you should probably install one of the popular Linux distrbutions. It should be more stable and you can have access to its user community. If you want to keep its size down, you can just install the base system without an X server or graphical applications.
BTW Netbeans is designed to develop userspace applications. You can probably adapt it for kernel code, but it will never be as suited as it is for userspace programming. As a matter of fact, no IDE is really suitable. Kernel code cannot be run from userspace (let alone using a separate VM), which breaks down the normal edit->compile->run->debug workflow cycle that IDEs automate.
Most kernel developers just use a souped-up editor with syntax highlighting for C, such as Vim or Emacs. Emacs is actually an IDE (and so much more) but, as I mentioned above, you cannot easily use an IDE-based workflow for kernel code development.
You can build a loadable kernel module if you don't want to build the whole kernel - e.g. see http://www.linux-tutorial.info/modules.php?name=Howto&pagename=Module-HOWTO.
All the code you write, compile and run as user programs run as ... well, user programs, in user mode. The kernel runs in kernel mode. Both modes are separated and cannot see each other directly. They communicate through defined interfaces. These interfaces are the C system calls (as opposed to the C library calls).
To be able to access the task_struct structures, your code has to be running in kernel mode. The best choice for this is to write a kernel module, and to load it in the kernel.
Very little kernel code can run outside the kernel in any form. Most kernel code is very 'intertwingled' (to use a phrase I learned from a coworker years ago to describe excessive coupling) with other portions of kernel code. Functions 'know' structure definitions for many many structures away from what they are working on. Typical software engineering people hate code like this:
if (unlikely(inode_init_always(sb, inode))) {
if (inode->i_sb->s_op->destroy_inode)
inode->i_sb->s_op->destroy_inode(inode);
else
kmem_cache_free(inode_cachep, inode);
return NULL;
}
This routine has to know how to destroy inodes through three structures and the calling convention of a function pointer on the other end of the chain. The kernel community knows all these functions very well, and are quite happy to modify member names in structures all throughout the kernel when changes are made, but this sort of tight coupling makes running portions of the kernel in userspace on their own extremely difficult. (And believe me, sometimes I wish I could write tests on my small portions of kernel code that would run in userspace.)
If you want to play around, it's not too hard to get a virtual system up and running these days with qemu+kvm or virtualbox or uml to try making modifications to the kernel. It is pretty hard to just "play" with structures on a live running system, but it is much more feasible than trying to compile portions of the kernel in userspace.
Good luck. :)
You might enjoy using systemtap as a wrapper for small bits of kernel module code:
# stap -g -e 'probe begin { your_function() exit() }
%{
#include <linux/whatever.h>
%}
function your_function() %{
... insert safe c code here ...
%}'
It can automatically cross-compile too (if you use stap --remote=VIRTMACHINE ...).

Windows Mirror Driver for Linux Framebuffer

for a software i'm writing i need to know when the linux framebuffer gets updated.
I need something like Windows Mirror Drivers (for more infos look Mirror_driver on wikipedia).
Looking around i haven't finded anything, so i'm looking a way to accomplish this.
From what i've seen, i need to write a module that gets loaded after framebuffer specific module and that hooks fb ops structure to inject own stuff and catch updates.
Can someone give me an hint? I don't have much experience with kernel module writing.
Thank you!
For general kernel module writing tips, you can read the books:Linux Kernel Development, Linux Kernel in a Nutshell and Linux Device Drivers.
After you understand the basics on how to build & install your own kernel modules, you can read the source code of the kernel to figure out where the framebuffer stuff is (start at Documentation/fb/framebuffer.txt). I'm not sure whether you can just hook up on the framebuffer driver like that, if not, you might need to add the hook support yourself or 'hijack' the main driver's events to simulate hooking. For example, suppose that there's a function that is called whenever there's an update. You find where the pointer to this function is declared, save the value, then modify it with a pointer to your function. Inside your function you call the original function, then your own code to manipulate what you want and return properly.
I don't know much about the framebuffer stuff, so I'm just guessing what your options are. It's possible that there might be a discussion list somewhere specific to the subject of linux-fb. This might me a good start.

Resources