How to access kernel parameters in kernel space - linux-kernel

This is one of my lab assignments: I have to create an proc entry here: /proc/sys/kernel/ and I have to write a system call to manipulate a user space variable for different values of the proc entry I just added. For eg: say, user space variable is 1 and proc entry is 0 or 1. Now the system call should increment the user space variable by 1(if proc entry is 0/off) or multiply it by two(if proc entry is 1/on)
I did the following to add the proc entry: I created an entry xxx by adding a struct under the kernel ctl table section in the file in the kernel/sysctl.c. Compiled the kernel and the system boots well with this kernel. The entry is also added into proc directory as /proc/sys/kernel/xxx.
I am now able to read or write to it from user space. I did both cat and echo to read and write resp.
I did the following in the system call: I wrote a system call to read the user space variable. I also completed and tested the access_ok, copy_from user, copy_to_user and all that. I also completed manipulating the user space variable to increment always(for now).
Problem I am facing: Now, I have to add an if condition to check the "xxx" value to decide whether I should increment or multiply the user space variable. This is where I am stuck. Not in writing the system call. I don't know how to read this proc entry "xxx".
Can I use file handling?
If so, should I use open() system call inside my system call? Will it work?
When I checked, there was sysctl system call, but it seems deprecated now. This IBM tutorial talks about reading the proc entry. But create_proc_entry does not apply to parameters inside /proc/sys/kernel directory right? If so, how can I ever use read proc entry function?

"But, now I have to write a system call to read the value of xxx."
I suspect that the term "system call" is being used in a formal sense and that you are being asked to add a new system call to the kernel (similar to open, read, mmap, signal etc) that returns your value.
See Adding a new system call in Linux kernel 3.3

Related

How to Send a Value to Another Driver's Sysfs Attribute

This is all in Linux 4.14.73. I'd upgrade if I could but I cant.
I'm trying to trigger an LED flash in a standard LED class instance from another kernel space driver. I know all about the "bad form" of not accessing files from Kernel Space so I figure there must be some way already defined way for accessing Sysfs attributes from Kernel Space.
The LED is defined here:
/sys/class/leds/fpga_led0
Its trigger is set to [oneshot] so it has a device attribute called "shot" exposed. To get a single LED flash all I need to do from the command line is this:
echo 1 > /sys/class/leds/fpga_led0/shot
I can easily write a User Space program to open the "shot" attribute and write a "1" string to it. There are various published methods of forcing file operations into a kernel driver. Most of them are fairly limited. I've yet to see one that exposes file seek operations which are key to repeatedly writing to an attribute without wasting time opening and closing the file. To be clear, this is not setting values at boot time. In this case I have one driver that needs to send a value to another driver's Sysfs entry at a specific moment in its own operation. Is there a standard, accepted way of sending a value from one running kernel driver to the Sysfs attribute of another kernel driver?

How to display array of structure pointer in user space which is copied from kernel via read call

Depending on the number of processes currently running, by using for_each_process macro call and one simple counter, I have used kmalloc to allocate memory for those processes to store process pid and its parent pid in structure. And use copy_to_user to copy it into the user space segment like below,
copy_to_user(buffer, &data, sizeof(Data) * process_counter);
But the problem is I am not able to figure out how should I suppose to display it on the user space application using read system call.
Is it possible in one read call Or do i need to use while loop for it ?
Thanks in advance.

loader inside the kernel

Assuming I don't care about security, the goal is to write a new system call that given a binary (ELF) can execute it inside the kernel.
Let's say I have a statically compiled binary A whose location in memory is ptr_A, the goal is to instrument the kernel with a new system call
sys_new_loader(ptr_A, ptr_result)
that
executes A inside the kernel, that is it is not possible for user space program to peek into A
returns value at location specified by ptr_result .
How could I go about implement this?
(I understand that exec system call family does a lot of book-keeping before transfering the control to user space. Do I need all those book-keeping, or can I simply jump to the specific location in ptr_A)

How is userspace able to write to sysfs

Recently I was looking through the kernel at kobjects and sysfs.
I know/understand the following..
All kernel objects use addresses > 0x80000000
kobjects should be no exception to this rule
The sysfs is nothing but a hierarchy of kobjects (maybe includes ksets and other k* stuff..not sure)
Given this information, I'm not sure I understand exactly what happens when I run echo ondemand >/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
I can see that the cpufreq module has a function called store_scaling_governor which handles writes to this 'file'..but how does usermode transcend into kernelmode with this simple echo?
When you execute command echo ondemand >/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor, your shell calls write system call, then kernel dispatch it for corresponding handler.
The cpufreq setups struct kobj_type ktype_cpufreq with sysfs_ops. Then cpufreq register it in cpufreq_add_dev_interface(). After that, kernel can get corresponding handler to execute on write syscall.
I can tell you one implementation which I have used for accessing kernel space variables from sysfs (user-space in shell prompt).Basically each set of variables which are exposed to user-space in sys file system appear as a separate file under /sys/.Now when you issue an echo value > /sys/file-path in shell prompt (user-space).When you do so the respective method which gets called in kernel space in .store method.Additionally when you issue cat /sys/file-path the respective method which gets called is .show in kernel.You can see more information about here: http://lwn.net/Articles/31220/

file_operations Question, how do i know if a process that opened a file for writing has decided to close it?

I'm currently writing a simple "multicaster" module.
Only one process can open a proc filesystem file for writing, and the rest can open it for reading.
To do so i use the inode_operation .permission callback, I check the operation and when i detect someone open a file for writing I set a flag ON.
i need a way to detect if a process that opened a file for writing has decided to close the file so i can set the flag OFF, so someone else can open for writing.
Currently in case someone is open for writing i save the current->pid of that process and when the .close callback is called I check if that process is the one I saved earlier.
Is there a better way to do that? Without saving the pid, perhaps checking the files that the current process has opened and it's permission...
Thanks!
No, it's not safe. Consider a few scenarios:
Process A opens the file for writing, and then fork()s, creating process B. Now both A and B have the file open for writing. When Process A closes it, you set the flag to 0 but process B still has it open for writing.
Process A has multiple threads. Thread X opens the file for writing, but Thread Y closes it. Now the flag is stuck at 1. (Remember that ->pid in kernel space is actually the userspace thread ID).
Rather than doing things at the inode level, you should be doing things in the .open and .release methods of your file_operations struct.
Your inode's private data should contain a struct file *current_writer;, initialised to NULL. In the file_operations.open method, if it's being opened for write then check the current_writer; if it's NULL, set it to the struct file * being opened, otherwise fail the open with EPERM. In the file_operations.release method, check if the struct file * being released is equal to the inode's current_writer - if so, set current_writer back to NULL.
PS: Bandan is also correct that you need locking, but the using the inode's existing i_mutex should suffice to protect the current_writer.
I hope I understood your question correctly: When someone wants to write to your proc file, you set a variable called flag to 1 and also save the current->pid in a global variable. Then, when any close() entry point is called, you check current->pid of the close() instance and compare that with your saved value. If that matches, you turn flag to off. Right ?
Consider this situation : Process A wants to write to your proc resource, and so you check the permission callback. You see that flag is 0, so you can set it to 1 for process A. But at that moment, the scheduler finds out process A has used up its time share and chooses a different process to run(flag is still o!). After sometime, process B comes up wanting to write to your proc resource also, checks that the flag is 0, sets it to 1, and then goes about writing to the file. Unfortunately at this moment, process A gets scheduled to run again and since, it thinks that flag is 0 (remember, before the scheduler pre-empted it, flag was 0) and so sets it to 1 and goes about writing to the file. End result : data in your proc resource goes corrupt.
You should use a good locking mechanism provided by the kernel for this type of operation and based on your requirement, I think RCU is the best : Have a look at RCU locking mechanism

Resources