sys_socket안에서 Data 앞에 해더 붙이기에서 문제입니다.
글쓴이: goro14 / 작성시간: 토, 2005/10/29 - 12:13오후
현재 sys_socket안에서 kmalloc을 사용해서 data+해더크기만큼 할당 하구구요 그앞에 해더 붙이고 send하고 recv한 data에서 해더크기 만큼 짤라내서
user영역으로 data를 보내는 거 하고 있는데요 알수없는 오류가 남니다. kmalloc에서는 괜찮은데 data에 해더를 붙이고 제거하면 부팅과정에서
loopback에서 멈쳐버립니다. 그래서 recv 과정에서 잘못 잡았는가 해서 여기저기 넣어보고 해도 안되네요...
sys_recvmsg를 잘못수정한것같기도하고.. 고수님들 도와주세요~
/* * BSD recvmsg interface */ asmlinkage long sys_recvmsg(int fd, struct msghdr *msg, unsigned int flags) { struct socket *sock; struct iovec iovstack[UIO_FASTIOV]; struct iovec *iov=iovstack; struct msghdr msg_sys; unsigned long cmsg_ptr; int err, iov_size, total_len, len; /* kernel mode address */ char addr[MAX_SOCK_ADDR]; /* user mode address pointers */ struct sockaddr *uaddr; int *uaddr_len; ////////////////////////////////////////////////// char *Temp; PROTO proto; int OurCount; ////////////////////////////////////////////////// err=-EFAULT; if (copy_from_user(&msg_sys,msg,sizeof(struct msghdr))) goto out; sock = sockfd_lookup(fd, &err); if (!sock) goto out; err = -EMSGSIZE; if (msg_sys.msg_iovlen > UIO_MAXIOV) goto out_put; /* Check whether to allocate the iovec area*/ err = -ENOMEM; iov_size = msg_sys.msg_iovlen * sizeof(struct iovec); if (msg_sys.msg_iovlen > UIO_FASTIOV) { iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL); if (!iov) goto out_put; } /* * Save the user-mode address (verify_iovec will change the * kernel msghdr to use the kernel address space) */ uaddr = msg_sys.msg_name; uaddr_len = &msg->msg_namelen; err = verify_iovec(&msg_sys, iov, addr, VERIFY_WRITE); if (err < 0) goto out_freeiov; total_len=err; /////////////////////////////////////////////////////////////////// Temp = kmalloc(iov_size, GFP_KERNEL); memset(Temp, 0, iov_size); memset(&proto, 0, sizeof(PROTO)); memcpy((void*)Temp, msg_sys.msg_iov->iov_base, iov_size); // Temp로 iov 저장 if(Temp[0] == (char)PROTO_SOF) { memcpy((void*)&proto, (void*)Temp, sizeof(PROTO)); printk("Unattach Header!!\n"); for(OurCount = 4; OurCount<iov_size; OurCount++) Temp[OurCount-4] = Temp[OurCount]; for(OurCount = iov_size-1; OurCount > iov_size-5; OurCount--) Temp[OunCount]=0; memcpy(msg_sys.msg_iov->iov_base, (void*)Temp, iov_size); } kfree(Temp); /////////////////////////////////////////////////////////////////// cmsg_ptr = (unsigned long)msg_sys.msg_control; msg_sys.msg_flags = 0; if (sock->file->f_flags & O_NONBLOCK) flags |= MSG_DONTWAIT; err = sock_recvmsg(sock, &msg_sys, total_len, flags); if (err < 0) goto out_freeiov; len = err; if (uaddr != NULL) { err = move_addr_to_user(addr, msg_sys.msg_namelen, uaddr, uaddr_len); if (err < 0) goto out_freeiov; } err = __put_user(msg_sys.msg_flags, &msg->msg_flags); if (err) goto out_freeiov; err = __put_user((unsigned long)msg_sys.msg_control-cmsg_ptr, &msg->msg_controllen); if (err) goto out_freeiov; err = len; out_freeiov: if (iov != iovstack) sock_kfree_s(sock->sk, iov, iov_size); out_put: sockfd_put(sock); out: return err; }
Forums:
댓글 달기