*** linux-user/syscall.c 2007-07-09 07:33:46.000000000 -0400 --- linux-user/syscall.c.stu 2007-07-09 07:01:12.000000000 -0400 *************** *** 522,550 **** return ret; } ! static inline long copy_from_user_sockaddr(struct sockaddr *addr, target_ulong target_addr, ! socklen_t len) { long ret = 0; ! struct target_sockaddr *target_saddr = (struct target_sockaddr *)target_addr; ! if( (ret=access_ok(VERIFY_READ,target_saddr,len)) != 0 ) return ret; memcpy(addr, target_saddr, len); addr->sa_family = tswap16(target_saddr->sa_family); return ret; } ! static inline long copy_to_user_sockaddr(target_ulong target_addr, struct sockaddr *addr, ! socklen_t len) { long ret = 0; ! struct target_sockaddr *target_saddr = (struct target_sockaddr *)target_addr; ! if( (ret=access_ok(VERIFY_WRITE,target_saddr,len)) != 0 ) return ret; memcpy(target_saddr, addr, len); target_saddr->sa_family = tswap16(addr->sa_family); return ret; } --- 522,554 ---- return ret; } ! static inline long target_to_host_sockaddr(struct sockaddr *addr, target_ulong target_addr, ! socklen_t len, ! int pg_access) { long ret = 0; ! struct target_sockaddr *target_saddr; ! if( (ret=lock_and_check_user_struct(&target_saddr,target_addr,len,1,pg_access)) != 0 ) return ret; memcpy(addr, target_saddr, len); addr->sa_family = tswap16(target_saddr->sa_family); + unlock_user(target_saddr, target_addr, 0); return ret; } ! static inline long host_to_target_sockaddr(target_ulong target_addr, struct sockaddr *addr, ! socklen_t len, ! int pg_access) { long ret = 0; ! struct target_sockaddr *target_saddr; ! if( (ret=lock_and_check_user_struct(&target_saddr,target_addr,len,1,pg_access)) != 0 ) return ret; memcpy(target_saddr, addr, len); target_saddr->sa_family = tswap16(addr->sa_family); + unlock_user(target_saddr, target_addr, len); return ret; } *************** *** 909,915 **** long ret = 0; void *addr = alloca(addrlen); ! if( (ret=copy_from_user_sockaddr(addr, target_addr, addrlen)) != 0 ) return ret; return get_errno(bind(sockfd, addr, addrlen)); } --- 913,919 ---- long ret = 0; void *addr = alloca(addrlen); ! if( (ret=target_to_host_sockaddr(addr, target_addr, addrlen,PAGE_READ)) != 0 ) return ret; return get_errno(bind(sockfd, addr, addrlen)); } *************** *** 919,925 **** long ret = 0; void *addr = alloca(addrlen); ! if( (ret=copy_from_user_sockaddr(addr, target_addr, addrlen)) != 0 ) return ret; return get_errno(connect(sockfd, addr, addrlen)); } --- 923,929 ---- long ret = 0; void *addr = alloca(addrlen); ! if( (ret=target_to_host_sockaddr(addr, target_addr, addrlen,PAGE_READ)) != 0 ) return ret; return get_errno(connect(sockfd, addr, addrlen)); } *************** *** 944,956 **** msg.msg_namelen = tswap32(msgp->msg_namelen); msg.msg_name = alloca(msg.msg_namelen); if( send ) { ! if( (ret=copy_from_user_sockaddr(msg.msg_name, tswapl(msgp->msg_name), ! msg.msg_namelen)) != 0 ) return ret; } else { ! /* FIXME ! if( (ret=copy_from_user_sockaddr(msg.msg_name, tswapl(msgp->msg_name), msg.msg_namelen,PAGE_WRITE)) != 0 ) return ret; - */ } } else { msg.msg_name = NULL; --- 948,958 ---- msg.msg_namelen = tswap32(msgp->msg_namelen); msg.msg_name = alloca(msg.msg_namelen); if( send ) { ! if( (ret=target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name), ! msg.msg_namelen,PAGE_READ)) != 0 ) return ret; } else { ! if( (ret=target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name), msg.msg_namelen,PAGE_WRITE)) != 0 ) return ret; } } else { msg.msg_name = NULL; *************** *** 991,997 **** ret = get_errno(accept(fd, addr, &addrlen)); if (!is_error(ret)) { ! if( (ret2=copy_to_user_sockaddr(target_addr, addr, addrlen)) != 0 ) return ret2; tput32(target_addrlen, addrlen); } return ret; --- 993,999 ---- ret = get_errno(accept(fd, addr, &addrlen)); if (!is_error(ret)) { ! if( (ret2=host_to_target_sockaddr(target_addr, addr, addrlen, PAGE_WRITE)) != 0 ) return ret2; tput32(target_addrlen, addrlen); } return ret; *************** *** 1010,1016 **** ret = get_errno(getpeername(fd, addr, &addrlen)); if (!is_error(ret)) { ! if( (ret2=copy_to_user_sockaddr(target_addr, addr, addrlen)) != 0 ) return ret2; if( (ret2=page_check_range(target_addrlen,sizeof(socklen_t),PAGE_WRITE)) != 0 ) return ret2; tput32(target_addrlen, addrlen); } --- 1012,1018 ---- ret = get_errno(getpeername(fd, addr, &addrlen)); if (!is_error(ret)) { ! if( (ret2=host_to_target_sockaddr(target_addr, addr, addrlen, PAGE_WRITE)) != 0 ) return ret2; if( (ret2=page_check_range(target_addrlen,sizeof(socklen_t),PAGE_WRITE)) != 0 ) return ret2; tput32(target_addrlen, addrlen); } *************** *** 1030,1036 **** ret = get_errno(getsockname(fd, addr, &addrlen)); if (!is_error(ret)) { ! if( (ret2=copy_to_user_sockaddr(target_addr, addr, addrlen)) ) return ret2; tput32(target_addrlen, addrlen); } return ret; --- 1032,1038 ---- ret = get_errno(getsockname(fd, addr, &addrlen)); if (!is_error(ret)) { ! if( (ret2=host_to_target_sockaddr(target_addr, addr, addrlen, PAGE_WRITE)) ) return ret2; tput32(target_addrlen, addrlen); } return ret; *************** *** 1060,1066 **** if( (ret=lock_and_check_user_struct(&host_msg,msg,len,1,PAGE_READ)) != 0 ) return ret; if (target_addr) { addr = alloca(addrlen); ! if( (ret=copy_from_user_sockaddr(addr, target_addr, addrlen)) != 0 ) return ret; ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen)); } else { ret = get_errno(send(fd, host_msg, len, flags)); --- 1062,1068 ---- if( (ret=lock_and_check_user_struct(&host_msg,msg,len,1,PAGE_READ)) != 0 ) return ret; if (target_addr) { addr = alloca(addrlen); ! if( (ret=target_to_host_sockaddr(addr, target_addr, addrlen, PAGE_READ)) != 0 ) return ret; ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen)); } else { ret = get_errno(send(fd, host_msg, len, flags)); *************** *** 1088,1094 **** } if (!is_error(ret)) { if (target_addr) { ! if( (ret2=copy_to_user_sockaddr(target_addr, addr, addrlen)) != 0 ) return ret2; tput32(target_addrlen, addrlen); } unlock_user(host_msg, msg, len); --- 1090,1096 ---- } if (!is_error(ret)) { if (target_addr) { ! if( (ret2=host_to_target_sockaddr(target_addr, addr, addrlen, PAGE_WRITE)) != 0 ) return ret2; tput32(target_addrlen, addrlen); } unlock_user(host_msg, msg, len);