Can't unload the Linux kernel module after BUG() call - c

Here my basic kernel module code.
#include <linux/kernel.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
static int test_bug_init(void)
{
printk(KERN_INFO"%s: In init\n", __func__);
BUG();
return 0;
}
static void test_bug_exit(void)
{
printk(KERN_INFO"%s: In exit\n", __func__);
}
module_init(test_bug_init);
module_exit(test_bug_exit);
When I load this module it was successfully loaded but, while unloading time gets the message like "Module in use".
So, why we can't unload the module after BUG() call? Is there another way to unload the module?

In kernel sources you can see that BUG() code eventually invokes unreachable() macro:
# define unreachable() do { } while (1)
Hence your init function test_bug_init() is in use because of infinite loop in it - it cannot return. Verify this by adding something like
//...
BUG();
printk(KERN_INFO "%s: After BUG()\n", __func__);
So you won't see this print in log.
Read also: BUG() FAQ
Is there another way to unload the module?
You can't unload it, because it is 'in use' and you can't make it not in use somehow (can't stop using it). Just reboot.

Related

What's the equivalent of raise(SIGTRAP) in Linux kernel module?

I am developing a loadable Linux kernel module. I want to break the execution into a remote GDB debugger if the code encounters an unknown error.
Say, my module has a function as follows:
void hello()
{
// ...
if (something_occured)
{
// raise(SIGTRAP) or __asm__ __volatile__("int 3"); ???
// What should be put here ???
}
}
Can raise(SIGTRAP) be used in kernel mode. Is there the equivalence of raise(SIGTRAP) in kernel mode?
What would you like your code to do if there IS no remote debugger running? Do that, and set a breakpoint on it.
It might be BUG, BUG_ON, or WARN_ON or a custom function of your own.

FreeBSD : Definition of BUS_TEARDOWN_INTR not found

In source code of FreeBSD, a method bus_teardown_intr in sys/kern/subr_bus.c is calling "BUS_TEARDOWN_INTR". What does BUS_TEARDOWN_INTR do? I am unable to find the definition of it.
I am attaching part of the code for reference
int
bus_teardown_intr(device_t dev, device_t child, struct resource *irq,
void *cookie)
{
if (dev->parent)
return (EINVAL);
return (BUS_TEARDOWN_INTR(dev->parent, child, irq, cookie));
}
Here is the link to the code " fxr.watson.org/fxr/source/kern/subr_bus.c ",
line number 4177 corresponds to the above code.
It is a generated function by sys/tools/makeobjops.awk. Look at sys/kern/bus_if.m for the source.
You can see the generated code in GENERIC/bus_if.h in your object directory after a kernel build. (or substitute your kernel name for GENERIC if you've changed it.)
The function also has a man page. type:
man 9 BUS_TEARDOWN_INTR
To read the documentation.

insmod: error when inserting kernel module

I am trying to implement a kernel module, which can access the task_struct of a user process, whose Process ID is already known to me. I am using find_get_pid and pid_task to get the task_struct of the process:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/pid.h>
#include <linux/pid_namespace.h>
int init_module( void )
{
//Declaring the variables
int p_id = 6980; //6980 is the process ID of my user process
struct pid *pid_struct;
struct task_struct *task;
// Trying to access the variables of the p_id
pid_struct = find_get_pid(p_id);
task = pid_task(pid_struct, PIDTYPE_PID);
//Printing the info from the task_struct
printk( KERN_INFO "*** [%d]\n",task->pid);
return 0;
}
void cleanup_module( void )
{
return;
}
It is getting compiled successfully and I am getting *.ko file, but when I am trying to insert it in the kernel, it is giving me an error:
insmod: error inserting 'main.ko': -1 Unknown symbol in module
Dmesg is giving me the following output:
main: Unknown symbol find_get_pid (err 0)
I dont know how to proceed, it would be really appreciated if anyone can help me.
Check carefully what the functions you want to use are called.
Also remember that much of what is "core kernel" (that presumably includes frob_task_by_pid_hardand its ilk) is GPL-only, so unless you declare your module's licence as GPL you won't go anywhere. Also be so kind to fill in the other boilerplate data on the module: MODULE_AUTHOR, MODULE_DESCRIPTION, MODULE_LICENSE at least.
There could be another reason for failure while loading kernel module like if it shows error as "insmod :ERROR: .ko operation not permitted". your kernel is booting with secure boot option on latest PC which must be disabled to avoid failure in loading/inserting a kernel module.this can be done by using below commands.
sudo apt install mokutil
sudo mokutil --disable-validation
or you can search for How to disable secure boot option for your specific OS.

process information at runtime at kernel level

I am working on a linux kernel module which would take care of all the processes that are running for a specific task. Is it possible to know if the certain process named 'X' is still running or not and whats its current state???
well the code is ready.. you can try this..
#include<linux/init.h>
#include<linux/module.h>
#include<linux/sched.h>
MODULE_LICENSE("GPL");
static int info_init(void)
{
struct task_struct *iTask;
for_each_process(iTask) {
printk(KERN_INFO "Process Info \nName: %s\nState:%ld\n",iTask->comm, iTask->state);
}
return 0;
}
static void info_exit(void)
{
printk(KERN_INFO "Tata Bye-bye from Anshul");
}
module_init(info_init);
module_exit(info_exit);
~
After executing it run a
dmesg
command and you can see all the process namess and their states.
Every Task in Linux is being represented by a structure (PCB/TCB) i.e. process/task control block. This is implemented as struct task_struct. It contains all the information about a process. All the PCBs are arranged in a link list and you can traverse through it and extract necessary information.
Inside your module you can initiate a kernel thread as a helper to do this work for you.

What to do when FreeLibrary API call fails?

Question
I have a third-party DLL that throws an unhandled exception when attempting to unload it from my native C application. This results in the call to FreeLibrary failing, and the module remaining loaded in my process.
Are there any options to forceably unload the library?
What do you do when the FreeLibrary calls?
Additional Background
When using load-time dynamic linking this is annoying enough, but ultimately the application gets torn down by the OS. The problem comes when using run-time dynamic linking. I load up this DLL, use it, and then in some instances I need to unload it from my process's virtual address space and then continue running. When I call FreeLibrary on the third-party library, it does some cleanup work (i.e. in DllMain when DLL_PROCESS_DETACH is called). While it's doing it's cleanup, it causes an exception to be thrown which it doesn't handle, and bubbles up as an unhandled exception to FreeLibrary. This results in the call failing and the module remaining loaded.
I've put a ticket in with the vendor so hopefully I can get a fix which will allow this specific library to unload successfully. In case I don't however, and for the general case of this issue, I'm curious as to what the options are.
If you are after only unloading dll from the memory you can use
UnmapViewOfFile
providing bases address of your loaded dll as an argument.
Example:
HINSTANCE hInst = LoadLibrary( "path_to_dll" );
if( !FreeLibrary( hInst ) )
{
fprintf( stderr, "Couldn't unload library. Error Code: %02X\n. Attempting to unmap...", GetLastError() );
if( !UnmapViewOfFile( hInst ) )
{
fprintf( stderr, "Couldn't unmap the file! Error Code: %02X\n", GetLastError( ) );
}
}
Or if it's a library that you didn't explicitly load (e.g. a library dependency that was loaded by a library that you loaded) and you don't have the handle, then use GetModuleHandle:
HINSTANCE hInst = GetModuleHandle( "dllname_you_didn't_load" );
if( hInst != NULL )
{
if( !UnmapViewOfFile( hInst ) )
{
fprintf( stderr, "Couldn't unmap the file! Error Code: %02X\n", GetLastError( ) );
}
}
I think there is only one possible solution - interop with dll through dedicated thread. So in time you need to unload dll you just exit (or may be kill) that thread and all associated with it resources will be freed. In this case you are not guaranteed about memory leaks, but I suggest this solution as temporary, till 3d party fixes bugs in dll
This is probably not the issue you're experience, but in case it is:
When using linker support for run-time dynamic linking, don't forget to use the /Delay:Unload argument.

Resources