process information at runtime at kernel level - c

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.

Related

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

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.

Autonomically sending a message from kernel-module to user-space application without relying on the invoke of input. from user-space

I will give a detailed exp of the program and lead to the issue regarding the use of netlink socket communication.
The last paragraph asks the actual question I need an answer for, so you might wanna start by peeking it first.
Disclaimer before I start:
- I have made an earlier search before asking here and did not find complete solution / alternative to my issue.
- I know how to initialize a module and insert it to kernel.
- I know to handle communication between module and user-space without using netlink sockets. Meaning using struct file_operations func pointers assignments to later be invoked by the module program whenever a user attempts to read/write etc. and answer to the user using copy_to_user / copy_from_user.
- This topic refers to Linux OS, Mint 17 dist.
- Language is C
Okay, so I am building a system with 3 components:
1. user.c : user application (user types commands here)
2. storage.c : storage device ('virtual' disk-on-key)
3. device.ko : kernel module (used as proxy between 1. and 2.)
The purpose of this system is to be able (as a user) to:
- Copy files to the virtual disk-on-key device (2) - like an "upload" from local directory that belongs to the user.
- Save files from the virtual device on local directory - like "download" from the device storage to the user directory.
Design:
Assuming programs (1),(2) are compiled and running + (3) has successfully inserted using the bash command ' sudo insmod device.ko ' , the following should work like this (simulation ofc):
Step 1 (in user.c) -> user types 'download file.txt'
Step 2 (in device.ko) -> the device recognizes the user have tried to 'write' to it (actually user just passing the string "download file.txt") and invokes the 'write' implementation of the method we set on struct file_operation earlier on module_init().
The device (kernel module) now passes the data (string with a command) to the storage.c application, expecting an answer to later be retrieved to the user.c application.
Step 3 (in storage.c) -> now, lets say this program performs a busy-wait loop of 'readmsg()' and that's how a request from module event is triggered and recognized, the storage device now recognizes that the module has sent a request (string with a command \ data). Now, the storage programs shall perform an implementation of some function 'X' to send the data requested using sendmsg() somewhere inside the function.
Now, here comes the issue.
Usually, on all of the examples I've looked on web, the communication between the kernel-module and a user-space (or the storage.c program in our case) using netlink is triggered by the user-space and not vice versa. Meaning that the sendmsg() function from the user-space invokes the 'request(struct sk_buff *skb)' method (which is set on the module_init() part as following:
struct netlink_kernel_cfg cfg = {
.input = request // when storage.c sends something, it invokes the request function
};
so when the storage.c performs something like:
sendmsg(sock_fd,&msg,0); // send a msg to the module
the module invokes and runs the:
static void request(struct sk_buff *skb) {
char *msg ="Hello from kernel";
msg_size=strlen(msg);
netlink_holder=(struct nlmsghdr*)skb->data;
printk(KERN_INFO "Netlink received msg payload:%s\n",(char*)nlmsg_data(netlink_holder));
pid = netlink_holder->nlmsg_pid; // pid of sending process
skb_out = nlmsg_new(msg_size,0);
if(!skb_out){
printk(KERN_ERR "Failed to allocate new skb\n");
return;
}
netlink_holder=nlmsg_put(skb_out,0,0,NLMSG_DONE,msg_size,0); // add a new netlink message to an skb. more info: http://elixir.free-electrons.com/linux/v3.2/source/include/net/netlink.h#L491
NETLINK_CB(skb_out).dst_group = 0; // not in multicast group
strncpy(nlmsg_data(netlink_holder),msg,msg_size); // assign data as char* (variable msg)
result=nlmsg_unicast(sock_netlink,skb_out,pid); // send data to storage. more info: http://elixir.free-electrons.com/linux/latest/source/include/net/netlink.h#L598
if(result<0)
printk(KERN_INFO "Error while sending bak to user\n");
}
and from all that big chunk, the only thing that im interesting in is actually doing this:
result=nlmsg_unicast(sock_netlink,skb_out,pid); // send data to storage.
BUT I can't use nlmsg_unicast() without having the strcut sk_buff* which is provided automatically for me whenever there's an invoke from storage.c !
To sum up everything:
How do I send a msg from the device.ko (kernel module) to the user-space withtout having to wait for request to invoke / rely on the provided strcut sk_buff parameter from the earlier shown 'request()' method ?
Hope this sums up the point.
Thanks.
The only question here is that you need the user-space program connected to kernel-space first to get the pid of your user-program.
After get the pid, you can manually construct the skb_out and send it out through netlink_unicast or nlmsg_unicast.
The pid is always needed, you can set it as static and let your user-space program connect to your device.ko to make a long-maintained link.
Although this question is asked at 2017, I believe OP has already found the answer :D

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.

Getting user process pid when writing Linux Kernel Module

How can I get the PID of the user process which triggered my Kernel module's file_operation.read routine (i.e., which process is reading /dev/mydev) ?
When your read function is executing, it's doing so in the context of the process that issued the system call. You should thus pe able to use current, i.e. current->pid.
These days, we have some helper functions defined in sched.h. In the case of pid, you can use:
pid = task_pid_nr(current);
to get the current task's pid.
here is the comment taken from include/linux/sched.h as of v3.8.
the helpers to get the task's different pids as they are seen
from various namespaces
task_xid_nr() : global id, i.e. the id seen from the init namespace;
task_xid_vnr() : virtual id, i.e. the id seen from the pid namespace of current.
task_xid_nr_ns() : id seen from the ns specified;
set_task_vxid() : assigns a virtual id to a task;
see also pid_nr() etc in include/linux/pid.h
On a kernel 2.6.39 arm build, if current->pid does not work then it may be done by:
pid_nr(get_task_pid(current, PIDTYPE_PID))
The PIDTYPE_PID can be substituted by PIDTYPE_PGID or PIDTYPE_SID. The header source is at include/linux/pid.h as Yasushi pointed out.
Which of the approaches work depends on what header files the code uses.

Resources