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

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.

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.

How to debug cgi program written in C and running in Apache2?

I have a complex cgi executable written in C, I configured in Apache2 and now it is running succesfully. How can I debug this program in the source code, such as set break points and inspect variables? Any tools like gdb or eclipse? Any tutorial of how to set up the debugging environment?
Thanks in advance!!
The CGI interface basically consists in passing the HTTP request to the executable's standard input and getting the response on the standard output. Therefore you can write test requests to files and manually execute your CGI without having to use Apache. The debugging can then be done with GDB :
gdb ./my_cgi
>> break some_func
>> run < my_req.txt
with my_req.txt containing the full request:
GET /some/func HTTP/1.0
Host: myhost
If you absolutely need the CGI to be run by Apache it may become tricky to attach GDB to the right process. You can for example configure Apache to have only one worker process, attach to it with gdb -p and use set follow-fork-mode child to make sure it switches to the CGI process when a request arrives.
I did this: in cgi main i added code to look for an existing file, like /var/tmp/flag. While existing, i run in a loop. Time enough to attach to cgi process via gdb. After then i delete /var/tmp/flag and from now I can debug my cgi code.
bool file_exists(const char *filename)
{
ifstream ifile(filename);
return ifile;
}
int cgiMain()
{
while (file_exists ("/var/tmp/flag"))
sleep (1);
...
your code
Unless FastCGI or SCGI is used, the CGI process is short-lived and you need to delay its exit to have enough time to attach the debugger while the process is still running. For casual debugging the easiest option is to simply use sleep() in an endless loop at the breakpoint location and exit the loop with the debugger once it is attached to the program.
Here's a small example CGI program:
#include <stdio.h>
#include <unistd.h>
void wait_for_gdb_to_attach() {
int is_waiting = 1;
while (is_waiting) {
sleep(1); // sleep for 1 second
}
}
int main(void) {
wait_for_gdb_to_attach();
printf("Content-Type: text/plain;charset=us-ascii\n\n");
printf("Hello!");
return 0;
}
Suppose it is compiled into cgi-debugging-example, this is how you would attach the debugger once the application enters the endless loop:
sudo cgdb cgi-debugging-example $(pgrep cgi-debugging)
Next you need to exit the infinite loop and wait_for_gdb_to_attach() function to reach the "breakpoint" in your application. The trick here is to step out of sleep functions until you reach wait_for_gdb_to_attach() and set the value of the variable is_waiting with the debugger so that while (is_waiting) exits:
(gdb) finish
Run till exit from 0x8a0920 __nanosleep_nocancel () at syscall-template.S:81
0x8a07d4 in __sleep (seconds=0) at sleep.c:137
(gdb) finish
Run till exit from 0x8a07d4 in __sleep (seconds=0) at sleep.c:137
wait_for_gdb_to_attach () at cgi-debugging-example.c:6
Value returned is $1 = 0
(gdb) set is_waiting = 0 # <<<<<< to exit while
(gdb) finish
Run till exit from wait_for_gdb_to_attach () cgi-debugging-example.c:6
main () at cgi-debugging-example.c:13
Once you are out of wait_for_gdb_to_attach(), you can continue debugging the program or let it run to completion.
Full example with detailed instructions here.
I'm not sure how to use gdb or other frontends in eclipse, but I just debugged my CGI program with gdb. I'd like to share something that other answers didn't mention, that CGIs usually need to read request meta-variables defined in RFC 3875#4.1 with getenv(3). Popular request variables in my mind are:
SCRIPT_NAME
QUERY_STRING
CONTENT_LENGTH
CONTENT_TYPE
REMOTE_ADDR
There variables are provided by http servers such as Apache. When debugging with gdb, we need to set these values by our own with set environment. In my case, there're only a few variables neededa(and the source code is very old, it still uses SCRIPT_URL instead of SCRIPT_NAME), so here's my example:
gdb cgi_name
set environment SCRIPT_URL /path/to/sub/cgis
set environment QUERY_STRING p1=v1&p2=v2
break foo.c:42
run
For me both solutions for debugging the CGI in gdb without web server presented above didn't work.
Maybe the second solution works for a GET Request.
I needed a combination of both, first setting the environment variables from rfc3875 (not sure if all of them are really neded).
Then I was able to pass only the params (not the compltete request) via STDIN from a file.
gdb cgi_name
set environment REQUEST_METHOD=POST
set environment CONTENT_LENGTH=1337
set environment CONTENT_TYPE=application/json
set environment SCRIPT_NAME=my.cgi
set environment REMOTE_ADDR=127.0.0.1
run < ./params.txt
With params.txt:
{"user":"admin","pass":"admin"}

How to change device (LCD) parameters dynamically on Android Linux ARM device [duplicate]

Problem: I have to configure various LCD displays to be used by Android Platform. Almost in all cases there are no electrical specifications freely available for LCD displays on interest. But through experience and reverse engineering the parameters can be guessed reasonably well. I am trying to use Loadable Kernel Modules to fine tune the display parameters (any other suggestions are welcome too). Please find the relevant information below.
HW: Atmel SAMA5D31-EK (ARM 5 processor)
SW: Andriod Linux (Target), Ubuntu (Host System), Sourcery CodeBench (Cross Compiler)
Code Snippets from board-dt.c file
static struct fb_videomode at91_tft_vga_modes[] = {
.....
.xres =435;
.yres =235;
....
}
static struct fb_monspecs at91fb_default_monspecs = {
.........
.modedb = at91_tft_vga_modes,
......
}
static struct atmel_lcd_fb_info __initdata ek_lcdc_data = {
..........
.default_monspecs = & at91fb_default_monspecs;
.........
}
I added this code so the Loadable Kernel Module has access to lcdc_data structure
extern void set_fb_video(struct fb_videomode *mg_set_tft_vga_modes)
{
ek_lcdc_data.default_monspecs->modedb->xres = mg_set_tft_vga_modes->xres;
}
EXPORT_SYMBOL(set_fb_video);
When I execute the loadable kernel module I don’t notice any change in the display. I suspect although I am changing the variable (memory) but registers are not been affected.
Question: What am I missing? I have read about making calls to platform_driver_register() and platform_driver_unregister().
Thank you for your help in advance.

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.

Override libc functions called from another libc function with LD_PRELOAD

I've a project aiming to run php-cgi chrooted for mass virtual hosting (more than 10k virtual host), with each virtual host having their own chroot, under Ubuntu Lucid x86_64.
I would like to avoid creating the necessary environment inside each chroot for things like /dev/null, /dev/zero, locales, icons... and whatever which could be needed by php modules thinking that they run outside chroot.
The goal is to make php-cgi run inside a chroot, but allowing him access to files outside the chroot as long as those files are (for most of them) opened in read-only mode, and on an allowed list (/dev/log, /dev/zero, /dev/null, path to the locales...)
The obvious way seems to create (or use if it exists) a kernel module, which could hook and redirect trusted open() paths, outside of the chroot.
But I don't think it's the easiest way:
I've never done a kernel module, so I do not correctly estimate the difficulty.
There seems to be multiple syscall to hook file "open" (open, connect, mmap...), but I guess there is a common kernel function for everything related to file opening.
I do want to minimize the number of patchs to php or it's module, to minimize the amount of work needed each time I will update our platform to the latest stable PHP release (and so update from upstream PHP releases more often and quickly), so I find better to patch the behavior of PHP from the outside (because we have a particular setup, so patching PHP and propose patch to upstream is not relevant).
Instead, I'm currently trying an userland solution : hook libc functions with LD_PRELOAD, which works well in most cases and is really quick to implement, but I've encountered a problem which I'm unable to resolve alone.
(The idea is to talk to a daemon running outside the chroot, and get file descriptor from it using ioctl SENDFD and RECVFD).
When I call syslog() (without openlog() first), syslog() calls connect() to open a file.
Example:
folays#phenix:~/ldpreload$ strace logger test 2>&1 | grep connect
connect(3, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
connect(3, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
connect(1, {sa_family=AF_FILE, path="/dev/log"}, 110) = 0
So far so good, I've tried to hook the connect() function of libc, without success.
I've also tried to put some flags to dlopen() inside the _init() function of my preload library to test if some of them could make this work, without success
Here is the relevant code of my preload library:
void __attribute__((constructor)) my_init(void)
{
printf("INIT preloadz %s\n", __progname);
dlopen(getenv("LD_PRELOAD"), RTLD_NOLOAD | RTLD_DEEPBIND | RTLD_GLOBAL |
RTLD_NOW);
}
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
printf("HOOKED connect\n");
int (*f)() = dlsym(RTLD_NEXT, "connect");
int ret = f(sockfd, addr, addrlen);
return ret;
}
int __connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
printf("HOOKED __connect\n");
int (*f)() = dlsym(RTLD_NEXT, "connect");
int ret = f(sockfd, addr, addrlen);
return ret;
}
But the connect() function of the libc still takes precedence over mine:
folays#phenix:~/ldpreload$ LD_PRELOAD=./lib-preload.so logger test
INIT preloadz logger
[...] no lines with "HOOKED connect..." [...]
folays#phenix:~/ldpreload$
Looking at the code of syslog() (apt-get source libc6 , glibc-2.13/misc/syslog.c), it seems to call openlog_internal, which in turn call __connect(), at misc/syslog.c line 386:
if (LogFile != -1 && !connected)
{
int old_errno = errno;
if (__connect(LogFile, &SyslogAddr, sizeof(SyslogAddr))
== -1)
{
Well, objdump shows me connect and __connect in the dynamic symbol table of libc:
folays#phenix:~/ldpreload$ objdump -T /lib/x86_64-linux-gnu/libc.so.6 |grep -i connec
00000000000e6d00 w DF .text 000000000000005e GLIBC_2.2.5 connect
00000000000e6d00 w DF .text 000000000000005e GLIBC_2.2.5 __connect
But no connect symbol in the dynamic relocation entries, so I guess that it explains why I cannot successfully override the connect() used by openlog_internal(), it probably does not use dynamic symbol relocation, and probably has the address of the __connect() function in hard (a relative -fPIC offset?).
folays#phenix:~/ldpreload$ objdump -R /lib/x86_64-linux-gnu/libc.so.6 |grep -i connec
folays#phenix:~/ldpreload$
connect is a weak alias to __connect:
eglibc-2.13/socket/connect.c:weak_alias (__connect, connect)
gdb is still able to breakpoint on the libc connect symbol of the libc:
folays#phenix:~/ldpreload$ gdb logger
(gdb) b connect
Breakpoint 1 at 0x400dc8
(gdb) r test
Starting program: /usr/bin/logger
Breakpoint 1, connect () at ../sysdeps/unix/syscall-template.S:82
82 ../sysdeps/unix/syscall-template.S: No such file or directory.
in ../sysdeps/unix/syscall-template.S
(gdb) c 2
Will ignore next crossing of breakpoint 1. Continuing.
Breakpoint 1, connect () at ../sysdeps/unix/syscall-template.S:82
82 in ../sysdeps/unix/syscall-template.S
(gdb) bt
#0 connect () at ../sysdeps/unix/syscall-template.S:82
#1 0x00007ffff7b28974 in openlog_internal (ident=<value optimized out>, logstat=<value optimized out>, logfac=<value optimized out>) at ../misc/syslog.c:386
#2 0x00007ffff7b29187 in __vsyslog_chk (pri=<value optimized out>, flag=1, fmt=0x40198e "%s", ap=0x7fffffffdd40) at ../misc/syslog.c:274
#3 0x00007ffff7b293af in __syslog_chk (pri=<value optimized out>, flag=<value optimized out>, fmt=<value optimized out>) at ../misc/syslog.c:131
Of course, I could completely skip this particular problem by doing an openlog() myself, but I guess that I will encounter the same type of problem with some others functions.
I don't really understand why openlog_internal does not use dynamic symbol relocation to call __connect(), and if it's even possible to hook this __connect() call by using simple LD_PRELOAD mechanism.
The others way I see how it could be done:
Load libc.so from an LD_PRELOAD with dlopen, get the address of the libc's __connect with dlsym() and then patch the function (ASM wise) to get the hook working. It seems really overkill and error prone.
Use a modified custom libc for PHP to fix those problems directly at the source (open / connect / mmap functions...)
Code a LKM, to redirect file access where I want. Pros : no need of ioctl(SENDFD) and no daemon outside the chroot.
I would really appreciate to learn, if it is ever possible, how I could still hook the call to __connect() issued by openlog_internal, suggestions, or links to kernel documentation related to syscall hooking and redirection.
My google searches related to "hook syscalls" found lot of references to LSM, but it seems to only allow ACLs answering "yes" or "no", but no redirection of open() paths.
Thanks for reading.
It's definitely not possible with LD_PRELOAD without building your own heavily-modified libc, in which case you might as well just put the redirection hacks directly inside. There are not necessarily calls to open, connect, etc. whatsoever. Instead there may be calls to a similar hidden function bound at library-creation time (not dynamically rebindable) or even inline syscalls, and this can of course change unpredictably with the version.
Your options are either a kernel module, or perhaps using ptrace on everything inside the "chroot" and modifying the arguments to syscalls whenever the tracing process encounters one that needs patching up. Neither sounds easy...
Or you could just accept that you need a minimal set of critical device nodes and files to exist inside a chroot for it to work. Using a different libc in place of glibc, if possible, would help you minimize the number of additional files needed.

Resources