* [Qemu-devel] [PATCH] linux-user/syscall: check some parameters for some socket syscalls.
@ 2009-06-18 11:43 Arnaud Patard
0 siblings, 0 replies; only message in thread
From: Arnaud Patard @ 2009-06-18 11:43 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 527 bytes --]
This patch is fixing following issues :
- commit 8fea36025b9d6d360ff3b78f88a84ccf221807e8 was applied to
do_getsockname instead of do_accept.
- Some syscalls were not checking properly the memory addresses passed
as argument
- Add check before syscalls made for cases like do_getpeername() where
we're using the address parameter after doing the syscall
- Fix do_accept to return EINVAL instead of EFAULT when parameters
invalid to match with linux behaviour
Signed-off-by: Arnaud Patard <arnaud.patard@rtp-net.org>
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: net_syscall_parameters_check.patch --]
[-- Type: text/x-diff, Size: 3505 bytes --]
Index: qemu/linux-user/syscall.c
===================================================================
--- qemu.orig/linux-user/syscall.c
+++ qemu/linux-user/syscall.c
@@ -1499,13 +1499,17 @@ static abi_long do_bind(int sockfd, abi_
socklen_t addrlen)
{
void *addr;
+ abi_long ret;
if (addrlen < 0)
return -TARGET_EINVAL;
addr = alloca(addrlen+1);
- target_to_host_sockaddr(addr, target_addr, addrlen);
+ ret = target_to_host_sockaddr(addr, target_addr, addrlen);
+ if (ret)
+ return ret;
+
return get_errno(bind(sockfd, addr, addrlen));
}
@@ -1514,13 +1518,17 @@ static abi_long do_connect(int sockfd, a
socklen_t addrlen)
{
void *addr;
+ abi_long ret;
if (addrlen < 0)
return -TARGET_EINVAL;
addr = alloca(addrlen);
- target_to_host_sockaddr(addr, target_addr, addrlen);
+ ret = target_to_host_sockaddr(addr, target_addr, addrlen);
+ if (ret)
+ return ret;
+
return get_errno(connect(sockfd, addr, addrlen));
}
@@ -1544,8 +1552,12 @@ static abi_long do_sendrecvmsg(int fd, a
if (msgp->msg_name) {
msg.msg_namelen = tswap32(msgp->msg_namelen);
msg.msg_name = alloca(msg.msg_namelen);
- target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
+ ret = target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
msg.msg_namelen);
+ if (ret) {
+ unlock_user_struct(msgp, target_msg, send ? 0 : 1);
+ return ret;
+ }
} else {
msg.msg_name = NULL;
msg.msg_namelen = 0;
@@ -1587,12 +1599,19 @@ static abi_long do_accept(int fd, abi_ul
void *addr;
abi_long ret;
+ if (target_addr == 0)
+ return get_errno(accept(fd, NULL, NULL));
+
+ /* linux returns EINVAL if addrlen pointer is invalid */
if (get_user_u32(addrlen, target_addrlen_addr))
- return -TARGET_EFAULT;
+ return -TARGET_EINVAL;
if (addrlen < 0)
return -TARGET_EINVAL;
+ if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
+ return -TARGET_EINVAL;
+
addr = alloca(addrlen);
ret = get_errno(accept(fd, addr, &addrlen));
@@ -1618,6 +1637,9 @@ static abi_long do_getpeername(int fd, a
if (addrlen < 0)
return -TARGET_EINVAL;
+ if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
+ return -TARGET_EFAULT;
+
addr = alloca(addrlen);
ret = get_errno(getpeername(fd, addr, &addrlen));
@@ -1637,15 +1659,15 @@ static abi_long do_getsockname(int fd, a
void *addr;
abi_long ret;
- if (target_addr == 0)
- return get_errno(accept(fd, NULL, NULL));
-
if (get_user_u32(addrlen, target_addrlen_addr))
return -TARGET_EFAULT;
if (addrlen < 0)
return -TARGET_EINVAL;
+ if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
+ return -TARGET_EFAULT;
+
addr = alloca(addrlen);
ret = get_errno(getsockname(fd, addr, &addrlen));
@@ -1689,7 +1711,11 @@ static abi_long do_sendto(int fd, abi_ul
return -TARGET_EFAULT;
if (target_addr) {
addr = alloca(addrlen);
- target_to_host_sockaddr(addr, target_addr, addrlen);
+ ret = target_to_host_sockaddr(addr, target_addr, addrlen);
+ if (ret) {
+ unlock_user(host_msg, msg, 0);
+ return ret;
+ }
ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
} else {
ret = get_errno(send(fd, host_msg, len, flags));
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2009-06-18 11:38 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-06-18 11:43 [Qemu-devel] [PATCH] linux-user/syscall: check some parameters for some socket syscalls Arnaud Patard
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).