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:


댓글 달기