* [Qemu-devel] [PATCH 0/3] linux-user: fix corner cases in sendrecvmsg
@ 2016-07-15 13:57 Peter Maydell
2016-07-15 13:57 ` [Qemu-devel] [PATCH 1/3] linux-user: Fix handling of iovec counts Peter Maydell
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Peter Maydell @ 2016-07-15 13:57 UTC (permalink / raw)
To: qemu-devel; +Cc: patches, Riku Voipio
These patches fix some bugs in handling corner cases of
sendrecvmsg; this allows us to pass the LTP 'recvmsg01'
test case.
thanks
-- PMM
Peter Maydell (3):
linux-user: Fix handling of iovec counts
linux-user: Fix errno for sendrecvmsg with large iovec length
linux-user: Allow bad msg_name for recvfrom on connected socket
linux-user/syscall.c | 28 ++++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)
--
1.9.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Qemu-devel] [PATCH 1/3] linux-user: Fix handling of iovec counts
2016-07-15 13:57 [Qemu-devel] [PATCH 0/3] linux-user: fix corner cases in sendrecvmsg Peter Maydell
@ 2016-07-15 13:57 ` Peter Maydell
2016-07-15 13:57 ` [Qemu-devel] [PATCH 2/3] linux-user: Fix errno for sendrecvmsg with large iovec length Peter Maydell
2016-07-15 13:57 ` [Qemu-devel] [PATCH 3/3] linux-user: Allow bad msg_name for recvfrom on connected socket Peter Maydell
2 siblings, 0 replies; 4+ messages in thread
From: Peter Maydell @ 2016-07-15 13:57 UTC (permalink / raw)
To: qemu-devel; +Cc: patches, Riku Voipio
In the kernel the length of an iovec is generally handled as
an unsigned long, not an integer; fix the parameter to
lock_iovec() accordingly.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
linux-user/syscall.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 9dbd711..8d36d6c 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -2647,7 +2647,7 @@ static abi_long do_getsockopt(int sockfd, int level, int optname,
}
static struct iovec *lock_iovec(int type, abi_ulong target_addr,
- int count, int copy)
+ abi_ulong count, int copy)
{
struct target_iovec *target_vec;
struct iovec *vec;
@@ -2660,7 +2660,7 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr,
errno = 0;
return NULL;
}
- if (count < 0 || count > IOV_MAX) {
+ if (count > IOV_MAX) {
errno = EINVAL;
return NULL;
}
@@ -2735,7 +2735,7 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr,
}
static void unlock_iovec(struct iovec *vec, abi_ulong target_addr,
- int count, int copy)
+ abi_ulong count, int copy)
{
struct target_iovec *target_vec;
int i;
@@ -2962,7 +2962,7 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
{
abi_long ret, len;
struct msghdr msg;
- int count;
+ abi_ulong count;
struct iovec *vec;
abi_ulong target_vec;
--
1.9.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [Qemu-devel] [PATCH 2/3] linux-user: Fix errno for sendrecvmsg with large iovec length
2016-07-15 13:57 [Qemu-devel] [PATCH 0/3] linux-user: fix corner cases in sendrecvmsg Peter Maydell
2016-07-15 13:57 ` [Qemu-devel] [PATCH 1/3] linux-user: Fix handling of iovec counts Peter Maydell
@ 2016-07-15 13:57 ` Peter Maydell
2016-07-15 13:57 ` [Qemu-devel] [PATCH 3/3] linux-user: Allow bad msg_name for recvfrom on connected socket Peter Maydell
2 siblings, 0 replies; 4+ messages in thread
From: Peter Maydell @ 2016-07-15 13:57 UTC (permalink / raw)
To: qemu-devel; +Cc: patches, Riku Voipio
The sendmsg and recvmsg syscalls use a different errno to indicate
an overlarge iovec length from readv and writev. Handle this
special case in do_sendrcvmsg_locked() to avoid getting the
default errno returned by lock_iovec().
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
linux-user/syscall.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 8d36d6c..a21ee59 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -2985,6 +2985,15 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
count = tswapal(msgp->msg_iovlen);
target_vec = tswapal(msgp->msg_iov);
+
+ if (count > IOV_MAX) {
+ /* sendrcvmsg returns a different errno for this condition than
+ * readv/writev, so we must catch it here before lock_iovec() does.
+ */
+ ret = -TARGET_EMSGSIZE;
+ goto out2;
+ }
+
vec = lock_iovec(send ? VERIFY_READ : VERIFY_WRITE,
target_vec, count, send);
if (vec == NULL) {
--
1.9.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [Qemu-devel] [PATCH 3/3] linux-user: Allow bad msg_name for recvfrom on connected socket
2016-07-15 13:57 [Qemu-devel] [PATCH 0/3] linux-user: fix corner cases in sendrecvmsg Peter Maydell
2016-07-15 13:57 ` [Qemu-devel] [PATCH 1/3] linux-user: Fix handling of iovec counts Peter Maydell
2016-07-15 13:57 ` [Qemu-devel] [PATCH 2/3] linux-user: Fix errno for sendrecvmsg with large iovec length Peter Maydell
@ 2016-07-15 13:57 ` Peter Maydell
2 siblings, 0 replies; 4+ messages in thread
From: Peter Maydell @ 2016-07-15 13:57 UTC (permalink / raw)
To: qemu-devel; +Cc: patches, Riku Voipio
The POSIX standard mandates that for a connected socket recvfrom()
must ignore the msg_name and msg_namelen fields. This is awkward
for QEMU because we will attempt to copy them from guest address
space. Handle this by not immediately returning a TARGET_EFAULT
if the copy failed, but instead passing a known-bad address
to the host kernel, which can then return EFAULT or ignore the
value appropriately.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
linux-user/syscall.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index a21ee59..33b5cb6 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -2972,7 +2972,14 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
ret = target_to_host_sockaddr(fd, msg.msg_name,
tswapal(msgp->msg_name),
msg.msg_namelen);
- if (ret) {
+ if (ret == -TARGET_EFAULT) {
+ /* For connected sockets msg_name and msg_namelen must
+ * be ignored, so returning EFAULT immediately is wrong.
+ * Instead, pass a bad msg_name to the host kernel, and
+ * let it decide whether to return EFAULT or not.
+ */
+ msg.msg_name = (void *)-1;
+ } else if (ret) {
goto out2;
}
} else {
@@ -3025,7 +3032,7 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
}
if (!is_error(ret)) {
msgp->msg_namelen = tswap32(msg.msg_namelen);
- if (msg.msg_name != NULL) {
+ if (msg.msg_name != NULL && msg.msg_name != (void *)-1) {
ret = host_to_target_sockaddr(tswapal(msgp->msg_name),
msg.msg_name, msg.msg_namelen);
if (ret) {
--
1.9.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2016-07-15 14:24 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-07-15 13:57 [Qemu-devel] [PATCH 0/3] linux-user: fix corner cases in sendrecvmsg Peter Maydell
2016-07-15 13:57 ` [Qemu-devel] [PATCH 1/3] linux-user: Fix handling of iovec counts Peter Maydell
2016-07-15 13:57 ` [Qemu-devel] [PATCH 2/3] linux-user: Fix errno for sendrecvmsg with large iovec length Peter Maydell
2016-07-15 13:57 ` [Qemu-devel] [PATCH 3/3] linux-user: Allow bad msg_name for recvfrom on connected socket Peter Maydell
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).