* [Qemu-devel] [PULL 00/16] linux-user before 2.7 hardfreeze
@ 2016-07-19 12:53 riku.voipio
2016-07-19 12:53 ` [Qemu-devel] [PULL 01/16] linux-user: fd_trans_*_data() returns the length riku.voipio
` (15 more replies)
0 siblings, 16 replies; 17+ messages in thread
From: riku.voipio @ 2016-07-19 12:53 UTC (permalink / raw)
To: qemu-devel; +Cc: Riku Voipio
From: Riku Voipio <riku.voipio@linaro.org>
he following changes since commit ad31cd4c6945d7e0f0546d92d29dcd12325b4e4a:
Merge remote-tracking branch 'remotes/jnsnow/tags/ide-pull-request' into staging (2016-07-19 11:47:07 +0100)
are available in the git repository at:
git://git.linaro.org/people/riku.voipio/qemu.git tags/pull-linux-user-20160719
for you to fetch changes up to 29b9f30b1e3a158e0127c45ade959b7d943cf8f8:
linux-user: AArch64 has sync_file_range, not sync_file_range2 (2016-07-19 15:26:37 +0300)
----------------------------------------------------------------
linux-user fixes before 2.7 freeze
----------------------------------------------------------------
Laurent Vivier (6):
linux-user: fd_trans_*_data() returns the length
linux-user: fix netlink memory corruption
linux-user: add fd_trans helper in do_recvfrom()
linux-user: convert sockaddr_ll from host to target
linux-user: add nested netlink types
linux-user: define missing sparc syscalls
Peter Maydell (9):
linux-user: Check sigsetsize argument to syscalls
linux-user: Add loop control ioctls
linux-user: Correct type for BLKSSZGET
linux-user: Correct type for LOOP_GET_STATUS{,64} ioctls
linux-user: Forget about synchronous signal once it is delivered
linux-user: Handle short lengths in host_to_target_sockaddr()
linux-user: Add some new blk ioctls
linux-user: Fix type for SIOCATMARK ioctl
linux-user: AArch64 has sync_file_range, not sync_file_range2
Timothy Pearson (1):
TIOCGPTN and related terminal control ioctls were not converted to the
guest ioctl format on x86_64 targets. Convert these ioctls to enable
terminal functionality on x86_64 guests.
linux-user/aarch64/syscall_nr.h | 3 +-
linux-user/ioctls.h | 41 +++-
linux-user/linux_loop.h | 11 +-
linux-user/signal.c | 8 +-
linux-user/sparc/syscall_nr.h | 3 +
linux-user/syscall.c | 454 ++++++++++++++++++++++++++++++++++++++--
linux-user/syscall_defs.h | 15 ++
linux-user/syscall_types.h | 9 +-
linux-user/x86_64/termbits.h | 12 +-
9 files changed, 516 insertions(+), 40 deletions(-)
--
2.1.4
^ permalink raw reply [flat|nested] 17+ messages in thread
* [Qemu-devel] [PULL 01/16] linux-user: fd_trans_*_data() returns the length
2016-07-19 12:53 [Qemu-devel] [PULL 00/16] linux-user before 2.7 hardfreeze riku.voipio
@ 2016-07-19 12:53 ` riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 02/16] linux-user: fix netlink memory corruption riku.voipio
` (14 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: riku.voipio @ 2016-07-19 12:53 UTC (permalink / raw)
To: qemu-devel; +Cc: Laurent Vivier
From: Laurent Vivier <laurent@vivier.eu>
fd_trans_target_to_host_data() and fd_trans_host_to_target_data() must
return the length of processed data.
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
linux-user/syscall.c | 36 ++++++++++++++++++++++++++++++++----
1 file changed, 32 insertions(+), 4 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 8bf6205..59defff 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -2826,12 +2826,26 @@ static TargetFdTrans target_packet_trans = {
#ifdef CONFIG_RTNETLINK
static abi_long netlink_route_target_to_host(void *buf, size_t len)
{
- return target_to_host_nlmsg_route(buf, len);
+ abi_long ret;
+
+ ret = target_to_host_nlmsg_route(buf, len);
+ if (ret < 0) {
+ return ret;
+ }
+
+ return len;
}
static abi_long netlink_route_host_to_target(void *buf, size_t len)
{
- return host_to_target_nlmsg_route(buf, len);
+ abi_long ret;
+
+ ret = host_to_target_nlmsg_route(buf, len);
+ if (ret < 0) {
+ return ret;
+ }
+
+ return len;
}
static TargetFdTrans target_netlink_route_trans = {
@@ -2842,12 +2856,26 @@ static TargetFdTrans target_netlink_route_trans = {
static abi_long netlink_audit_target_to_host(void *buf, size_t len)
{
- return target_to_host_nlmsg_audit(buf, len);
+ abi_long ret;
+
+ ret = target_to_host_nlmsg_audit(buf, len);
+ if (ret < 0) {
+ return ret;
+ }
+
+ return len;
}
static abi_long netlink_audit_host_to_target(void *buf, size_t len)
{
- return host_to_target_nlmsg_audit(buf, len);
+ abi_long ret;
+
+ ret = host_to_target_nlmsg_audit(buf, len);
+ if (ret < 0) {
+ return ret;
+ }
+
+ return len;
}
static TargetFdTrans target_netlink_audit_trans = {
--
2.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PULL 02/16] linux-user: fix netlink memory corruption
2016-07-19 12:53 [Qemu-devel] [PULL 00/16] linux-user before 2.7 hardfreeze riku.voipio
2016-07-19 12:53 ` [Qemu-devel] [PULL 01/16] linux-user: fd_trans_*_data() returns the length riku.voipio
@ 2016-07-19 12:54 ` riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 03/16] linux-user: add fd_trans helper in do_recvfrom() riku.voipio
` (13 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: riku.voipio @ 2016-07-19 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Laurent Vivier
From: Laurent Vivier <laurent@vivier.eu>
Netlink is byte-swapping data in the guest memory (it's bad).
It's ok when the data come from the host as they are generated by the
host.
But it doesn't work when data come from the guest: the guest can
try to reuse these data whereas they have been byte-swapped.
This is what happens in glibc:
glibc generates a sequence number in nlh.nlmsg_seq and calls
sendto() with this nlh. In sendto(), we byte-swap nlmsg.seq.
Later, after the recvmsg(), glibc compares nlh.nlmsg_seq with
sequence number given in return, and of course it fails (hangs),
because nlh.nlmsg_seq is not valid anymore.
The involved code in glibc is:
sysdeps/unix/sysv/linux/check_pf.c:make_request()
...
req.nlh.nlmsg_seq = time (NULL);
...
if (TEMP_FAILURE_RETRY (__sendto (fd, (void *) &req, sizeof (req), 0,
(struct sockaddr *) &nladdr,
sizeof (nladdr))) < 0)
<here req.nlh.nlmsg_seq has been byte-swapped>
...
do
{
...
ssize_t read_len = TEMP_FAILURE_RETRY (__recvmsg (fd, &msg, 0));
...
struct nlmsghdr *nlmh;
for (nlmh = (struct nlmsghdr *) buf;
NLMSG_OK (nlmh, (size_t) read_len);
nlmh = (struct nlmsghdr *) NLMSG_NEXT (nlmh, read_len))
{
<we compare nlmh->nlmsg_seq with corrupted req.nlh.nlmsg_seq>
if (nladdr.nl_pid != 0 || (pid_t) nlmh->nlmsg_pid != pid
|| nlmh->nlmsg_seq != req.nlh.nlmsg_seq)
continue;
...
else if (nlmh->nlmsg_type == NLMSG_DONE)
/* We found the end, leave the loop. */
done = true;
}
}
while (! done);
As we have a continue on "nlmh->nlmsg_seq != req.nlh.nlmsg_seq",
"done" cannot be set to "true" and we have an infinite loop.
It's why commands like "apt-get update" or "dnf update hangs".
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
linux-user/syscall.c | 32 ++++++++++++++++++++++++--------
1 file changed, 24 insertions(+), 8 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 59defff..491ab55 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3017,13 +3017,22 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
if (send) {
if (fd_trans_target_to_host_data(fd)) {
- ret = fd_trans_target_to_host_data(fd)(msg.msg_iov->iov_base,
+ void *host_msg;
+
+ host_msg = g_malloc(msg.msg_iov->iov_len);
+ memcpy(host_msg, msg.msg_iov->iov_base, msg.msg_iov->iov_len);
+ ret = fd_trans_target_to_host_data(fd)(host_msg,
msg.msg_iov->iov_len);
+ if (ret >= 0) {
+ msg.msg_iov->iov_base = host_msg;
+ ret = get_errno(safe_sendmsg(fd, &msg, flags));
+ }
+ g_free(host_msg);
} else {
ret = target_to_host_cmsg(&msg, msgp);
- }
- if (ret == 0) {
- ret = get_errno(safe_sendmsg(fd, &msg, flags));
+ if (ret == 0) {
+ ret = get_errno(safe_sendmsg(fd, &msg, flags));
+ }
}
} else {
ret = get_errno(safe_recvmsg(fd, &msg, flags));
@@ -3239,6 +3248,7 @@ static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
{
void *addr;
void *host_msg;
+ void *copy_msg = NULL;
abi_long ret;
if ((int)addrlen < 0) {
@@ -3249,23 +3259,29 @@ static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
if (!host_msg)
return -TARGET_EFAULT;
if (fd_trans_target_to_host_data(fd)) {
+ copy_msg = host_msg;
+ host_msg = g_malloc(len);
+ memcpy(host_msg, copy_msg, len);
ret = fd_trans_target_to_host_data(fd)(host_msg, len);
if (ret < 0) {
- unlock_user(host_msg, msg, 0);
- return ret;
+ goto fail;
}
}
if (target_addr) {
addr = alloca(addrlen+1);
ret = target_to_host_sockaddr(fd, addr, target_addr, addrlen);
if (ret) {
- unlock_user(host_msg, msg, 0);
- return ret;
+ goto fail;
}
ret = get_errno(safe_sendto(fd, host_msg, len, flags, addr, addrlen));
} else {
ret = get_errno(safe_sendto(fd, host_msg, len, flags, NULL, 0));
}
+fail:
+ if (copy_msg) {
+ g_free(host_msg);
+ host_msg = copy_msg;
+ }
unlock_user(host_msg, msg, 0);
return ret;
}
--
2.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PULL 03/16] linux-user: add fd_trans helper in do_recvfrom()
2016-07-19 12:53 [Qemu-devel] [PULL 00/16] linux-user before 2.7 hardfreeze riku.voipio
2016-07-19 12:53 ` [Qemu-devel] [PULL 01/16] linux-user: fd_trans_*_data() returns the length riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 02/16] linux-user: fix netlink memory corruption riku.voipio
@ 2016-07-19 12:54 ` riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 04/16] linux-user: convert sockaddr_ll from host to target riku.voipio
` (12 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: riku.voipio @ 2016-07-19 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Laurent Vivier
From: Laurent Vivier <laurent@vivier.eu>
Fix passwd using netlink audit.
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
linux-user/syscall.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 491ab55..f9ce9d8 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3316,6 +3316,9 @@ static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
ret = get_errno(safe_recvfrom(fd, host_msg, len, flags, NULL, 0));
}
if (!is_error(ret)) {
+ if (fd_trans_host_to_target_data(fd)) {
+ ret = fd_trans_host_to_target_data(fd)(host_msg, ret);
+ }
if (target_addr) {
host_to_target_sockaddr(target_addr, addr, addrlen);
if (put_user_u32(addrlen, target_addrlen)) {
--
2.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PULL 04/16] linux-user: convert sockaddr_ll from host to target
2016-07-19 12:53 [Qemu-devel] [PULL 00/16] linux-user before 2.7 hardfreeze riku.voipio
` (2 preceding siblings ...)
2016-07-19 12:54 ` [Qemu-devel] [PULL 03/16] linux-user: add fd_trans helper in do_recvfrom() riku.voipio
@ 2016-07-19 12:54 ` riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 05/16] linux-user: add nested netlink types riku.voipio
` (11 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: riku.voipio @ 2016-07-19 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Laurent Vivier
From: Laurent Vivier <laurent@vivier.eu>
As we convert sockaddr for AF_PACKET family for sendto() (target to
host) we need also to convert this for getsockname() (host to target).
arping uses getsockname() to get the the interface address and uses
this address with sendto().
Tested with:
/sbin/arping -D -q -c2 -I eno1 192.168.122.88
...
getsockname(3, {sa_family=AF_PACKET, proto=0x806, if2,
pkttype=PACKET_HOST, addr(6)={1, 10c37b6b9a76}, [18]) = 0
...
sendto(3, "..." 28, 0,
{sa_family=AF_PACKET, proto=0x806, if2, pkttype=PACKET_HOST,
addr(6)={1, ffffffffffff}, 20) = 28
...
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
linux-user/syscall.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f9ce9d8..919b589 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -100,6 +100,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
#include <linux/route.h>
#include <linux/filter.h>
#include <linux/blkpg.h>
+#include <netpacket/packet.h>
#include <linux/netlink.h>
#ifdef CONFIG_RTNETLINK
#include <linux/rtnetlink.h>
@@ -1383,6 +1384,10 @@ static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
struct sockaddr_nl *target_nl = (struct sockaddr_nl *)target_saddr;
target_nl->nl_pid = tswap32(target_nl->nl_pid);
target_nl->nl_groups = tswap32(target_nl->nl_groups);
+ } else if (addr->sa_family == AF_PACKET) {
+ struct sockaddr_ll *target_ll = (struct sockaddr_ll *)target_saddr;
+ target_ll->sll_ifindex = tswap32(target_ll->sll_ifindex);
+ target_ll->sll_hatype = tswap16(target_ll->sll_hatype);
}
unlock_user(target_saddr, target_addr, len);
--
2.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PULL 05/16] linux-user: add nested netlink types
2016-07-19 12:53 [Qemu-devel] [PULL 00/16] linux-user before 2.7 hardfreeze riku.voipio
` (3 preceding siblings ...)
2016-07-19 12:54 ` [Qemu-devel] [PULL 04/16] linux-user: convert sockaddr_ll from host to target riku.voipio
@ 2016-07-19 12:54 ` riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 06/16] linux-user: Check sigsetsize argument to syscalls riku.voipio
` (10 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: riku.voipio @ 2016-07-19 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Laurent Vivier
From: Laurent Vivier <laurent@vivier.eu>
Nested types are used by the kernel to send link information and
protocol properties.
We can see following errors with "ip link show":
Unimplemented nested type 26
Unimplemented nested type 26
Unimplemented nested type 18
Unimplemented nested type 26
Unimplemented nested type 18
Unimplemented nested type 26
This patch implements nested types 18 (IFLA_LINKINFO) and
26 (IFLA_AF_SPEC).
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
linux-user/syscall.c | 320 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 316 insertions(+), 4 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 919b589..761d8fb 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -104,6 +104,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
#include <linux/netlink.h>
#ifdef CONFIG_RTNETLINK
#include <linux/rtnetlink.h>
+#include <linux/if_bridge.h>
#endif
#include <linux/audit.h>
#include "linux_loop.h"
@@ -1712,6 +1713,33 @@ static abi_long target_to_host_for_each_nlmsg(struct nlmsghdr *nlh,
}
#ifdef CONFIG_RTNETLINK
+static abi_long host_to_target_for_each_nlattr(struct nlattr *nlattr,
+ size_t len, void *context,
+ abi_long (*host_to_target_nlattr)
+ (struct nlattr *,
+ void *context))
+{
+ unsigned short nla_len;
+ abi_long ret;
+
+ while (len > sizeof(struct nlattr)) {
+ nla_len = nlattr->nla_len;
+ if (nla_len < sizeof(struct nlattr) ||
+ nla_len > len) {
+ break;
+ }
+ ret = host_to_target_nlattr(nlattr, context);
+ nlattr->nla_len = tswap16(nlattr->nla_len);
+ nlattr->nla_type = tswap16(nlattr->nla_type);
+ if (ret < 0) {
+ return ret;
+ }
+ len -= NLA_ALIGN(nla_len);
+ nlattr = (struct nlattr *)(((char *)nlattr) + NLA_ALIGN(nla_len));
+ }
+ return 0;
+}
+
static abi_long host_to_target_for_each_rtattr(struct rtattr *rtattr,
size_t len,
abi_long (*host_to_target_rtattr)
@@ -1738,12 +1766,292 @@ static abi_long host_to_target_for_each_rtattr(struct rtattr *rtattr,
return 0;
}
+#define NLA_DATA(nla) ((void *)((char *)(nla)) + NLA_HDRLEN)
+
+static abi_long host_to_target_data_bridge_nlattr(struct nlattr *nlattr,
+ void *context)
+{
+ uint16_t *u16;
+ uint32_t *u32;
+ uint64_t *u64;
+
+ switch (nlattr->nla_type) {
+ /* no data */
+ case IFLA_BR_FDB_FLUSH:
+ break;
+ /* binary */
+ case IFLA_BR_GROUP_ADDR:
+ break;
+ /* uint8_t */
+ case IFLA_BR_VLAN_FILTERING:
+ case IFLA_BR_TOPOLOGY_CHANGE:
+ case IFLA_BR_TOPOLOGY_CHANGE_DETECTED:
+ case IFLA_BR_MCAST_ROUTER:
+ case IFLA_BR_MCAST_SNOOPING:
+ case IFLA_BR_MCAST_QUERY_USE_IFADDR:
+ case IFLA_BR_MCAST_QUERIER:
+ case IFLA_BR_NF_CALL_IPTABLES:
+ case IFLA_BR_NF_CALL_IP6TABLES:
+ case IFLA_BR_NF_CALL_ARPTABLES:
+ break;
+ /* uint16_t */
+ case IFLA_BR_PRIORITY:
+ case IFLA_BR_VLAN_PROTOCOL:
+ case IFLA_BR_GROUP_FWD_MASK:
+ case IFLA_BR_ROOT_PORT:
+ case IFLA_BR_VLAN_DEFAULT_PVID:
+ u16 = NLA_DATA(nlattr);
+ *u16 = tswap16(*u16);
+ break;
+ /* uint32_t */
+ case IFLA_BR_FORWARD_DELAY:
+ case IFLA_BR_HELLO_TIME:
+ case IFLA_BR_MAX_AGE:
+ case IFLA_BR_AGEING_TIME:
+ case IFLA_BR_STP_STATE:
+ case IFLA_BR_ROOT_PATH_COST:
+ case IFLA_BR_MCAST_HASH_ELASTICITY:
+ case IFLA_BR_MCAST_HASH_MAX:
+ case IFLA_BR_MCAST_LAST_MEMBER_CNT:
+ case IFLA_BR_MCAST_STARTUP_QUERY_CNT:
+ u32 = NLA_DATA(nlattr);
+ *u32 = tswap32(*u32);
+ break;
+ /* uint64_t */
+ case IFLA_BR_HELLO_TIMER:
+ case IFLA_BR_TCN_TIMER:
+ case IFLA_BR_GC_TIMER:
+ case IFLA_BR_TOPOLOGY_CHANGE_TIMER:
+ case IFLA_BR_MCAST_LAST_MEMBER_INTVL:
+ case IFLA_BR_MCAST_MEMBERSHIP_INTVL:
+ case IFLA_BR_MCAST_QUERIER_INTVL:
+ case IFLA_BR_MCAST_QUERY_INTVL:
+ case IFLA_BR_MCAST_QUERY_RESPONSE_INTVL:
+ case IFLA_BR_MCAST_STARTUP_QUERY_INTVL:
+ u64 = NLA_DATA(nlattr);
+ *u64 = tswap64(*u64);
+ break;
+ /* ifla_bridge_id: uin8_t[] */
+ case IFLA_BR_ROOT_ID:
+ case IFLA_BR_BRIDGE_ID:
+ break;
+ default:
+ gemu_log("Unknown IFLA_BR type %d\n", nlattr->nla_type);
+ break;
+ }
+ return 0;
+}
+
+static abi_long host_to_target_slave_data_bridge_nlattr(struct nlattr *nlattr,
+ void *context)
+{
+ uint16_t *u16;
+ uint32_t *u32;
+ uint64_t *u64;
+
+ switch (nlattr->nla_type) {
+ /* uint8_t */
+ case IFLA_BRPORT_STATE:
+ case IFLA_BRPORT_MODE:
+ case IFLA_BRPORT_GUARD:
+ case IFLA_BRPORT_PROTECT:
+ case IFLA_BRPORT_FAST_LEAVE:
+ case IFLA_BRPORT_LEARNING:
+ case IFLA_BRPORT_UNICAST_FLOOD:
+ case IFLA_BRPORT_PROXYARP:
+ case IFLA_BRPORT_LEARNING_SYNC:
+ case IFLA_BRPORT_PROXYARP_WIFI:
+ case IFLA_BRPORT_TOPOLOGY_CHANGE_ACK:
+ case IFLA_BRPORT_CONFIG_PENDING:
+ case IFLA_BRPORT_MULTICAST_ROUTER:
+ break;
+ /* uint16_t */
+ case IFLA_BRPORT_PRIORITY:
+ case IFLA_BRPORT_DESIGNATED_PORT:
+ case IFLA_BRPORT_DESIGNATED_COST:
+ case IFLA_BRPORT_ID:
+ case IFLA_BRPORT_NO:
+ u16 = NLA_DATA(nlattr);
+ *u16 = tswap16(*u16);
+ break;
+ /* uin32_t */
+ case IFLA_BRPORT_COST:
+ u32 = NLA_DATA(nlattr);
+ *u32 = tswap32(*u32);
+ break;
+ /* uint64_t */
+ case IFLA_BRPORT_MESSAGE_AGE_TIMER:
+ case IFLA_BRPORT_FORWARD_DELAY_TIMER:
+ case IFLA_BRPORT_HOLD_TIMER:
+ u64 = NLA_DATA(nlattr);
+ *u64 = tswap64(*u64);
+ break;
+ /* ifla_bridge_id: uint8_t[] */
+ case IFLA_BRPORT_ROOT_ID:
+ case IFLA_BRPORT_BRIDGE_ID:
+ break;
+ default:
+ gemu_log("Unknown IFLA_BRPORT type %d\n", nlattr->nla_type);
+ break;
+ }
+ return 0;
+}
+
+struct linkinfo_context {
+ int len;
+ char *name;
+ int slave_len;
+ char *slave_name;
+};
+
+static abi_long host_to_target_data_linkinfo_nlattr(struct nlattr *nlattr,
+ void *context)
+{
+ struct linkinfo_context *li_context = context;
+
+ switch (nlattr->nla_type) {
+ /* string */
+ case IFLA_INFO_KIND:
+ li_context->name = NLA_DATA(nlattr);
+ li_context->len = nlattr->nla_len - NLA_HDRLEN;
+ break;
+ case IFLA_INFO_SLAVE_KIND:
+ li_context->slave_name = NLA_DATA(nlattr);
+ li_context->slave_len = nlattr->nla_len - NLA_HDRLEN;
+ break;
+ /* stats */
+ case IFLA_INFO_XSTATS:
+ /* FIXME: only used by CAN */
+ break;
+ /* nested */
+ case IFLA_INFO_DATA:
+ if (strncmp(li_context->name, "bridge",
+ li_context->len) == 0) {
+ return host_to_target_for_each_nlattr(NLA_DATA(nlattr),
+ nlattr->nla_len,
+ NULL,
+ host_to_target_data_bridge_nlattr);
+ } else {
+ gemu_log("Unknown IFLA_INFO_KIND %s\n", li_context->name);
+ }
+ break;
+ case IFLA_INFO_SLAVE_DATA:
+ if (strncmp(li_context->slave_name, "bridge",
+ li_context->slave_len) == 0) {
+ return host_to_target_for_each_nlattr(NLA_DATA(nlattr),
+ nlattr->nla_len,
+ NULL,
+ host_to_target_slave_data_bridge_nlattr);
+ } else {
+ gemu_log("Unknown IFLA_INFO_SLAVE_KIND %s\n",
+ li_context->slave_name);
+ }
+ break;
+ default:
+ gemu_log("Unknown host IFLA_INFO type: %d\n", nlattr->nla_type);
+ break;
+ }
+
+ return 0;
+}
+
+static abi_long host_to_target_data_inet_nlattr(struct nlattr *nlattr,
+ void *context)
+{
+ uint32_t *u32;
+ int i;
+
+ switch (nlattr->nla_type) {
+ case IFLA_INET_CONF:
+ u32 = NLA_DATA(nlattr);
+ for (i = 0; i < (nlattr->nla_len - NLA_HDRLEN) / sizeof(*u32);
+ i++) {
+ u32[i] = tswap32(u32[i]);
+ }
+ break;
+ default:
+ gemu_log("Unknown host AF_INET type: %d\n", nlattr->nla_type);
+ }
+ return 0;
+}
+
+static abi_long host_to_target_data_inet6_nlattr(struct nlattr *nlattr,
+ void *context)
+{
+ uint32_t *u32;
+ uint64_t *u64;
+ struct ifla_cacheinfo *ci;
+ int i;
+
+ switch (nlattr->nla_type) {
+ /* binaries */
+ case IFLA_INET6_TOKEN:
+ break;
+ /* uint8_t */
+ case IFLA_INET6_ADDR_GEN_MODE:
+ break;
+ /* uint32_t */
+ case IFLA_INET6_FLAGS:
+ u32 = NLA_DATA(nlattr);
+ *u32 = tswap32(*u32);
+ break;
+ /* uint32_t[] */
+ case IFLA_INET6_CONF:
+ u32 = NLA_DATA(nlattr);
+ for (i = 0; i < (nlattr->nla_len - NLA_HDRLEN) / sizeof(*u32);
+ i++) {
+ u32[i] = tswap32(u32[i]);
+ }
+ break;
+ /* ifla_cacheinfo */
+ case IFLA_INET6_CACHEINFO:
+ ci = NLA_DATA(nlattr);
+ ci->max_reasm_len = tswap32(ci->max_reasm_len);
+ ci->tstamp = tswap32(ci->tstamp);
+ ci->reachable_time = tswap32(ci->reachable_time);
+ ci->retrans_time = tswap32(ci->retrans_time);
+ break;
+ /* uint64_t[] */
+ case IFLA_INET6_STATS:
+ case IFLA_INET6_ICMP6STATS:
+ u64 = NLA_DATA(nlattr);
+ for (i = 0; i < (nlattr->nla_len - NLA_HDRLEN) / sizeof(*u64);
+ i++) {
+ u64[i] = tswap64(u64[i]);
+ }
+ break;
+ default:
+ gemu_log("Unknown host AF_INET6 type: %d\n", nlattr->nla_type);
+ }
+ return 0;
+}
+
+static abi_long host_to_target_data_spec_nlattr(struct nlattr *nlattr,
+ void *context)
+{
+ switch (nlattr->nla_type) {
+ case AF_INET:
+ return host_to_target_for_each_nlattr(NLA_DATA(nlattr), nlattr->nla_len,
+ NULL,
+ host_to_target_data_inet_nlattr);
+ case AF_INET6:
+ return host_to_target_for_each_nlattr(NLA_DATA(nlattr), nlattr->nla_len,
+ NULL,
+ host_to_target_data_inet6_nlattr);
+ default:
+ gemu_log("Unknown host AF_SPEC type: %d\n", nlattr->nla_type);
+ break;
+ }
+ return 0;
+}
+
static abi_long host_to_target_data_link_rtattr(struct rtattr *rtattr)
{
uint32_t *u32;
struct rtnl_link_stats *st;
struct rtnl_link_stats64 *st64;
struct rtnl_link_ifmap *map;
+ struct linkinfo_context li_context;
switch (rtattr->rta_type) {
/* binary stream */
@@ -1851,11 +2159,15 @@ static abi_long host_to_target_data_link_rtattr(struct rtattr *rtattr)
map->irq = tswap16(map->irq);
break;
/* nested */
- case IFLA_AF_SPEC:
case IFLA_LINKINFO:
- /* FIXME: implement nested type */
- gemu_log("Unimplemented nested type %d\n", rtattr->rta_type);
- break;
+ memset(&li_context, 0, sizeof(li_context));
+ return host_to_target_for_each_nlattr(RTA_DATA(rtattr), rtattr->rta_len,
+ &li_context,
+ host_to_target_data_linkinfo_nlattr);
+ case IFLA_AF_SPEC:
+ return host_to_target_for_each_nlattr(RTA_DATA(rtattr), rtattr->rta_len,
+ NULL,
+ host_to_target_data_spec_nlattr);
default:
gemu_log("Unknown host IFLA type: %d\n", rtattr->rta_type);
break;
--
2.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PULL 06/16] linux-user: Check sigsetsize argument to syscalls
2016-07-19 12:53 [Qemu-devel] [PULL 00/16] linux-user before 2.7 hardfreeze riku.voipio
` (4 preceding siblings ...)
2016-07-19 12:54 ` [Qemu-devel] [PULL 05/16] linux-user: add nested netlink types riku.voipio
@ 2016-07-19 12:54 ` riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 07/16] linux-user: Add loop control ioctls riku.voipio
` (9 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: riku.voipio @ 2016-07-19 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
From: Peter Maydell <peter.maydell@linaro.org>
Many syscalls which take a sigset_t argument also take an argument
giving the size of the sigset_t. The kernel insists that this
matches its idea of the type size and fails EINVAL if it is not.
Implement this logic in QEMU. (This mostly just means some LTP test
cases which check error cases now pass.)
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
---
linux-user/syscall.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 46 insertions(+), 1 deletion(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 761d8fb..0a99af8 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7978,7 +7978,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
#if defined(TARGET_ALPHA)
struct target_sigaction act, oact, *pact = 0;
struct target_rt_sigaction *rt_act;
- /* ??? arg4 == sizeof(sigset_t). */
+
+ if (arg4 != sizeof(target_sigset_t)) {
+ ret = -TARGET_EINVAL;
+ break;
+ }
if (arg2) {
if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
goto efault;
@@ -8002,6 +8006,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
struct target_sigaction *act;
struct target_sigaction *oact;
+ if (arg4 != sizeof(target_sigset_t)) {
+ ret = -TARGET_EINVAL;
+ break;
+ }
if (arg2) {
if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
goto efault;
@@ -8133,6 +8141,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
int how = arg1;
sigset_t set, oldset, *set_ptr;
+ if (arg4 != sizeof(target_sigset_t)) {
+ ret = -TARGET_EINVAL;
+ break;
+ }
+
if (arg2) {
switch(how) {
case TARGET_SIG_BLOCK:
@@ -8183,6 +8196,17 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_rt_sigpending:
{
sigset_t set;
+
+ /* Yes, this check is >, not != like most. We follow the kernel's
+ * logic and it does it like this because it implements
+ * NR_sigpending through the same code path, and in that case
+ * the old_sigset_t is smaller in size.
+ */
+ if (arg2 > sizeof(target_sigset_t)) {
+ ret = -TARGET_EINVAL;
+ break;
+ }
+
ret = get_errno(sigpending(&set));
if (!is_error(ret)) {
if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
@@ -8216,6 +8240,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_rt_sigsuspend:
{
TaskState *ts = cpu->opaque;
+
+ if (arg2 != sizeof(target_sigset_t)) {
+ ret = -TARGET_EINVAL;
+ break;
+ }
if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
goto efault;
target_to_host_sigset(&ts->sigsuspend_mask, p);
@@ -8233,6 +8262,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
struct timespec uts, *puts;
siginfo_t uinfo;
+ if (arg4 != sizeof(target_sigset_t)) {
+ ret = -TARGET_EINVAL;
+ break;
+ }
+
if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
goto efault;
target_to_host_sigset(&set, p);
@@ -9484,6 +9518,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
}
if (arg4) {
+ if (arg5 != sizeof(target_sigset_t)) {
+ unlock_user(target_pfd, arg1, 0);
+ ret = -TARGET_EINVAL;
+ break;
+ }
+
target_set = lock_user(VERIFY_READ, arg4, sizeof(target_sigset_t), 1);
if (!target_set) {
unlock_user(target_pfd, arg1, 0);
@@ -11303,6 +11343,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
sigset_t _set, *set = &_set;
if (arg5) {
+ if (arg6 != sizeof(target_sigset_t)) {
+ ret = -TARGET_EINVAL;
+ break;
+ }
+
target_set = lock_user(VERIFY_READ, arg5,
sizeof(target_sigset_t), 1);
if (!target_set) {
--
2.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PULL 07/16] linux-user: Add loop control ioctls
2016-07-19 12:53 [Qemu-devel] [PULL 00/16] linux-user before 2.7 hardfreeze riku.voipio
` (5 preceding siblings ...)
2016-07-19 12:54 ` [Qemu-devel] [PULL 06/16] linux-user: Check sigsetsize argument to syscalls riku.voipio
@ 2016-07-19 12:54 ` riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 08/16] linux-user: Correct type for BLKSSZGET riku.voipio
` (8 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: riku.voipio @ 2016-07-19 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
From: Peter Maydell <peter.maydell@linaro.org>
Add support for the /dev/loop-control ioctls:
LOOP_CTL_ADD
LOOP_CTL_REMOVE
LOOP_CTL_GET_FREE
[RV: fixed to apply to new header guards]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
linux-user/ioctls.h | 4 ++++
linux-user/linux_loop.h | 11 ++++++++++-
linux-user/syscall_defs.h | 4 ++++
3 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index e672655..abff6b6 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -327,6 +327,10 @@
IOCTL(LOOP_GET_STATUS64, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info64)))
IOCTL(LOOP_CHANGE_FD, 0, TYPE_INT)
+ IOCTL(LOOP_CTL_ADD, 0, TYPE_INT)
+ IOCTL(LOOP_CTL_REMOVE, 0, TYPE_INT)
+ IOCTL(LOOP_CTL_GET_FREE, 0, TYPE_NULL)
+
IOCTL(MTIOCTOP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_mtop)))
IOCTL(MTIOCGET, IOC_R, MK_PTR(MK_STRUCT(STRUCT_mtget)))
IOCTL(MTIOCPOS, IOC_R, MK_PTR(MK_STRUCT(STRUCT_mtpos)))
diff --git a/linux-user/linux_loop.h b/linux-user/linux_loop.h
index 1f52403..c69fea1 100644
--- a/linux-user/linux_loop.h
+++ b/linux-user/linux_loop.h
@@ -1,4 +1,6 @@
-/* Copied from 2.6.25 kernel headers to avoid problems on older hosts. */
+/* Copied from 2.6.25 kernel headers to avoid problems on older hosts,
+ * and subsequently updated to match newer additions to the API.
+ */
#ifndef LINUX_LOOP_H
#define LINUX_LOOP_H
@@ -92,5 +94,12 @@ struct loop_info64 {
#define LOOP_SET_STATUS64 0x4C04
#define LOOP_GET_STATUS64 0x4C05
#define LOOP_CHANGE_FD 0x4C06
+#define LOOP_SET_CAPACITY 0x4C07
+#define LOOP_SET_DIRECT_IO 0x4C08
+
+/* /dev/loop-control interface */
+#define LOOP_CTL_ADD 0x4C80
+#define LOOP_CTL_REMOVE 0x4C81
+#define LOOP_CTL_GET_FREE 0x4C82
#endif
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index b43966e..096f91c 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -1117,6 +1117,10 @@ struct target_pollfd {
#define TARGET_LOOP_GET_STATUS64 0x4C05
#define TARGET_LOOP_CHANGE_FD 0x4C06
+#define TARGET_LOOP_CTL_ADD 0x4C80
+#define TARGET_LOOP_CTL_REMOVE 0x4C81
+#define TARGET_LOOP_CTL_GET_FREE 0x4C82
+
/* fb ioctls */
#define TARGET_FBIOGET_VSCREENINFO 0x4600
#define TARGET_FBIOPUT_VSCREENINFO 0x4601
--
2.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PULL 08/16] linux-user: Correct type for BLKSSZGET
2016-07-19 12:53 [Qemu-devel] [PULL 00/16] linux-user before 2.7 hardfreeze riku.voipio
` (6 preceding siblings ...)
2016-07-19 12:54 ` [Qemu-devel] [PULL 07/16] linux-user: Add loop control ioctls riku.voipio
@ 2016-07-19 12:54 ` riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 09/16] linux-user: Correct type for LOOP_GET_STATUS{, 64} ioctls riku.voipio
` (7 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: riku.voipio @ 2016-07-19 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
From: Peter Maydell <peter.maydell@linaro.org>
The BLKSSZGET ioctl takes an argument which is a pointer to an int.
We were incorrectly declaring it to take a pointer to a long, which
meant that we would incorrectly write to memory which we should not
if the guest is a 64-bit architecture.
In particular, kpartx uses this ioctl to write to an int on the
stack, which tends to result in it crashing immediately.
Reported-by: Chanho Park <chanho61.park@samsung.com>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
linux-user/ioctls.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index abff6b6..a066d9b 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -76,7 +76,7 @@
IOCTL(BLKFLSBUF, 0, TYPE_NULL)
IOCTL(BLKRASET, 0, TYPE_INT)
IOCTL(BLKRAGET, IOC_R, MK_PTR(TYPE_LONG))
- IOCTL(BLKSSZGET, IOC_R, MK_PTR(TYPE_LONG))
+ IOCTL(BLKSSZGET, IOC_R, MK_PTR(TYPE_INT))
IOCTL(BLKBSZGET, IOC_R, MK_PTR(TYPE_INT))
IOCTL_SPECIAL(BLKPG, IOC_W, do_ioctl_blkpg,
MK_PTR(MK_STRUCT(STRUCT_blkpg_ioctl_arg)))
--
2.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PULL 09/16] linux-user: Correct type for LOOP_GET_STATUS{, 64} ioctls
2016-07-19 12:53 [Qemu-devel] [PULL 00/16] linux-user before 2.7 hardfreeze riku.voipio
` (7 preceding siblings ...)
2016-07-19 12:54 ` [Qemu-devel] [PULL 08/16] linux-user: Correct type for BLKSSZGET riku.voipio
@ 2016-07-19 12:54 ` riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 10/16] linux-user: Forget about synchronous signal once it is delivered riku.voipio
` (6 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: riku.voipio @ 2016-07-19 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
From: Peter Maydell <peter.maydell@linaro.org>
The LOOP_GET_STATUS and LOOP_GET_STATUS64 ioctls were incorrectly
defined as IOC_W rather than IOC_R, which meant we weren't
correctly copying the information back from the kernel to the guest.
The loop_info64 structure definition was also missing a member
and using the wrong type for several 32-bit fields.
In particular, this meant that "kpartx -d image.img" didn't work
and "losetup -a" behaved strangely. Correct the ioctl type definitions.
Reported-by: Chanho Park <chanho61.park@samsung.com>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
linux-user/ioctls.h | 4 ++--
linux-user/syscall_types.h | 9 +++++----
2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index a066d9b..33ede9c 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -322,9 +322,9 @@
IOCTL(LOOP_SET_FD, 0, TYPE_INT)
IOCTL(LOOP_CLR_FD, 0, TYPE_INT)
IOCTL(LOOP_SET_STATUS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info)))
- IOCTL(LOOP_GET_STATUS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info)))
+ IOCTL(LOOP_GET_STATUS, IOC_R, MK_PTR(MK_STRUCT(STRUCT_loop_info)))
IOCTL(LOOP_SET_STATUS64, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info64)))
- IOCTL(LOOP_GET_STATUS64, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info64)))
+ IOCTL(LOOP_GET_STATUS64, IOC_R, MK_PTR(MK_STRUCT(STRUCT_loop_info64)))
IOCTL(LOOP_CHANGE_FD, 0, TYPE_INT)
IOCTL(LOOP_CTL_ADD, 0, TYPE_INT)
diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h
index 1fd4ee0..af79fbf 100644
--- a/linux-user/syscall_types.h
+++ b/linux-user/syscall_types.h
@@ -103,10 +103,11 @@ STRUCT(loop_info64,
TYPE_ULONGLONG, /* lo_inode */
TYPE_ULONGLONG, /* lo_rdevice */
TYPE_ULONGLONG, /* lo_offset */
- TYPE_ULONG, /* lo_number */
- TYPE_ULONG, /* lo_encrypt_type */
- TYPE_ULONG, /* lo_encrypt_key_size */
- TYPE_ULONG, /* lo_flags */
+ TYPE_ULONGLONG, /* lo_sizelimit */
+ TYPE_INT, /* lo_number */
+ TYPE_INT, /* lo_encrypt_type */
+ TYPE_INT, /* lo_encrypt_key_size */
+ TYPE_INT, /* lo_flags */
MK_ARRAY(TYPE_CHAR, 64), /* lo_name */
MK_ARRAY(TYPE_CHAR, 64), /* lo_crypt_name */
MK_ARRAY(TYPE_CHAR, 32), /* lo_encrypt_key */
--
2.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PULL 10/16] linux-user: Forget about synchronous signal once it is delivered
2016-07-19 12:53 [Qemu-devel] [PULL 00/16] linux-user before 2.7 hardfreeze riku.voipio
` (8 preceding siblings ...)
2016-07-19 12:54 ` [Qemu-devel] [PULL 09/16] linux-user: Correct type for LOOP_GET_STATUS{, 64} ioctls riku.voipio
@ 2016-07-19 12:54 ` riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 11/16] linux-user: Handle short lengths in host_to_target_sockaddr() riku.voipio
` (5 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: riku.voipio @ 2016-07-19 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
From: Peter Maydell <peter.maydell@linaro.org>
Commit 655ed67c2a248cf which switched synchronous signals to
benig recorded in ts->sync_signal rather than in a queue
with every other signal had a bug: we failed to clear
the flag indicating that a synchronous signal was pending
when we delivered it. This meant that we would take the signal
again and again every time the guest made a syscall.
(This is a bug introduced in my refactoring of Timothy Baldwin's
original code.)
Fix this by passing in the struct emulated_sigtable* to
handle_pending_signal(), so that we clear the pending flag
in the ts->sync_signal struct when handling a synchronous signal.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
linux-user/signal.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 9d98045..9a4d894 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -5826,7 +5826,8 @@ long do_rt_sigreturn(CPUArchState *env)
#endif
-static void handle_pending_signal(CPUArchState *cpu_env, int sig)
+static void handle_pending_signal(CPUArchState *cpu_env, int sig,
+ struct emulated_sigtable *k)
{
CPUState *cpu = ENV_GET_CPU(cpu_env);
abi_ulong handler;
@@ -5834,7 +5835,6 @@ static void handle_pending_signal(CPUArchState *cpu_env, int sig)
target_sigset_t target_old_set;
struct target_sigaction *sa;
TaskState *ts = cpu->opaque;
- struct emulated_sigtable *k = &ts->sigtab[sig - 1];
trace_user_handle_signal(cpu_env, sig);
/* dequeue signal */
@@ -5937,7 +5937,7 @@ void process_pending_signals(CPUArchState *cpu_env)
sigact_table[sig - 1]._sa_handler = TARGET_SIG_DFL;
}
- handle_pending_signal(cpu_env, sig);
+ handle_pending_signal(cpu_env, sig, &ts->sync_signal);
}
for (sig = 1; sig <= TARGET_NSIG; sig++) {
@@ -5947,7 +5947,7 @@ void process_pending_signals(CPUArchState *cpu_env)
if (ts->sigtab[sig - 1].pending &&
(!sigismember(blocked_set,
target_to_host_signal_table[sig]))) {
- handle_pending_signal(cpu_env, sig);
+ handle_pending_signal(cpu_env, sig, &ts->sigtab[sig - 1]);
/* Restart scan from the beginning */
sig = 1;
}
--
2.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PULL 11/16] linux-user: Handle short lengths in host_to_target_sockaddr()
2016-07-19 12:53 [Qemu-devel] [PULL 00/16] linux-user before 2.7 hardfreeze riku.voipio
` (9 preceding siblings ...)
2016-07-19 12:54 ` [Qemu-devel] [PULL 10/16] linux-user: Forget about synchronous signal once it is delivered riku.voipio
@ 2016-07-19 12:54 ` riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 12/16] linux-user: Add some new blk ioctls riku.voipio
` (4 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: riku.voipio @ 2016-07-19 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
From: Peter Maydell <peter.maydell@linaro.org>
If userspace specifies a short buffer for a target sockaddr,
the kernel will only copy in as much as it has space for
(or none at all if the length is zero) -- see the kernel
move_addr_to_user() function. Mimic this in QEMU's
host_to_target_sockaddr() routine.
In particular, this fixes a segfault running the LTP
recvfrom01 test, where the guest makes a recvfrom()
call with a bad buffer pointer and other parameters which
cause the kernel to set the addrlen to zero; because we
did not skip the attempt to swap the sa_family field we
segfaulted on the bad address.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@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 0a99af8..ca6a2b4 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -1376,12 +1376,19 @@ static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
{
struct target_sockaddr *target_saddr;
+ if (len == 0) {
+ return 0;
+ }
+
target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
if (!target_saddr)
return -TARGET_EFAULT;
memcpy(target_saddr, addr, len);
- target_saddr->sa_family = tswap16(addr->sa_family);
- if (addr->sa_family == AF_NETLINK) {
+ if (len >= offsetof(struct target_sockaddr, sa_family) +
+ sizeof(target_saddr->sa_family)) {
+ target_saddr->sa_family = tswap16(addr->sa_family);
+ }
+ if (addr->sa_family == AF_NETLINK && len >= sizeof(struct sockaddr_nl)) {
struct sockaddr_nl *target_nl = (struct sockaddr_nl *)target_saddr;
target_nl->nl_pid = tswap32(target_nl->nl_pid);
target_nl->nl_groups = tswap32(target_nl->nl_groups);
--
2.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PULL 12/16] linux-user: Add some new blk ioctls
2016-07-19 12:53 [Qemu-devel] [PULL 00/16] linux-user before 2.7 hardfreeze riku.voipio
` (10 preceding siblings ...)
2016-07-19 12:54 ` [Qemu-devel] [PULL 11/16] linux-user: Handle short lengths in host_to_target_sockaddr() riku.voipio
@ 2016-07-19 12:54 ` riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 13/16] TIOCGPTN and related terminal control ioctls were not converted to the guest ioctl format on x86_64 targets. Convert these ioctls to enable terminal functionality on x86_64 guests riku.voipio
` (3 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: riku.voipio @ 2016-07-19 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
From: Peter Maydell <peter.maydell@linaro.org>
Add some new blk ioctls (these are 0x12,119 through
to 0x12,127). Several of these are used by mke2fs; this silences
the warnings:
mke2fs 1.42.12 (29-Aug-2014)
Unsupported ioctl: cmd=0x127b
Unsupported ioctl: cmd=0x127a
warning: Unable to get device geometry for /dev/loop5
Unsupported ioctl: cmd=0x127c
Unsupported ioctl: cmd=0x127c
Unsupported ioctl: cmd=0x1277
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
linux-user/ioctls.h | 29 +++++++++++++++++++++++++++++
linux-user/syscall_defs.h | 11 +++++++++++
2 files changed, 40 insertions(+)
diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index 33ede9c..4b36baa 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -80,6 +80,35 @@
IOCTL(BLKBSZGET, IOC_R, MK_PTR(TYPE_INT))
IOCTL_SPECIAL(BLKPG, IOC_W, do_ioctl_blkpg,
MK_PTR(MK_STRUCT(STRUCT_blkpg_ioctl_arg)))
+
+#ifdef BLKDISCARD
+ IOCTL(BLKDISCARD, IOC_W, MK_PTR(MK_ARRAY(TYPE_ULONGLONG, 2)))
+#endif
+#ifdef BLKIOMIN
+ IOCTL(BLKIOMIN, IOC_R, MK_PTR(TYPE_INT))
+#endif
+#ifdef BLKIOOPT
+ IOCTL(BLKIOOPT, IOC_R, MK_PTR(TYPE_INT))
+#endif
+#ifdef BLKALIGNOFF
+ IOCTL(BLKALIGNOFF, IOC_R, MK_PTR(TYPE_INT))
+#endif
+#ifdef BLKPBSZGET
+ IOCTL(BLKPBSZGET, IOC_R, MK_PTR(TYPE_INT))
+#endif
+#ifdef BLKDISCARDZEROES
+ IOCTL(BLKDISCARDZEROES, IOC_R, MK_PTR(TYPE_INT))
+#endif
+#ifdef BLKSECDISCARD
+ IOCTL(BLKSECDISCARD, IOC_W, MK_PTR(MK_ARRAY(TYPE_ULONGLONG, 2)))
+#endif
+#ifdef BLKROTATIONAL
+ IOCTL(BLKROTATIONAL, IOC_R, MK_PTR(TYPE_SHORT))
+#endif
+#ifdef BLKZEROOUT
+ IOCTL(BLKZEROOUT, IOC_W, MK_PTR(MK_ARRAY(TYPE_ULONGLONG, 2)))
+#endif
+
#ifdef FIBMAP
IOCTL(FIBMAP, IOC_W | IOC_R, MK_PTR(TYPE_LONG))
#endif
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 096f91c..7835654 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -985,6 +985,17 @@ struct target_pollfd {
#define TARGET_BLKGETSIZE64 TARGET_IOR(0x12,114,abi_ulong)
/* return device size in bytes
(u64 *arg) */
+
+#define TARGET_BLKDISCARD TARGET_IO(0x12, 119)
+#define TARGET_BLKIOMIN TARGET_IO(0x12, 120)
+#define TARGET_BLKIOOPT TARGET_IO(0x12, 121)
+#define TARGET_BLKALIGNOFF TARGET_IO(0x12, 122)
+#define TARGET_BLKPBSZGET TARGET_IO(0x12, 123)
+#define TARGET_BLKDISCARDZEROES TARGET_IO(0x12, 124)
+#define TARGET_BLKSECDISCARD TARGET_IO(0x12, 125)
+#define TARGET_BLKROTATIONAL TARGET_IO(0x12, 126)
+#define TARGET_BLKZEROOUT TARGET_IO(0x12, 127)
+
#define TARGET_FIBMAP TARGET_IO(0x00,1) /* bmap access */
#define TARGET_FIGETBSZ TARGET_IO(0x00,2) /* get the block size used for bmap */
#define TARGET_FS_IOC_FIEMAP TARGET_IOWR('f',11,struct fiemap)
--
2.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PULL 13/16] TIOCGPTN and related terminal control ioctls were not converted to the guest ioctl format on x86_64 targets. Convert these ioctls to enable terminal functionality on x86_64 guests.
2016-07-19 12:53 [Qemu-devel] [PULL 00/16] linux-user before 2.7 hardfreeze riku.voipio
` (11 preceding siblings ...)
2016-07-19 12:54 ` [Qemu-devel] [PULL 12/16] linux-user: Add some new blk ioctls riku.voipio
@ 2016-07-19 12:54 ` riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 14/16] linux-user: define missing sparc syscalls riku.voipio
` (2 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: riku.voipio @ 2016-07-19 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Timothy Pearson
From: Timothy Pearson <tpearson@raptorengineering.com>
Signed-off-by: Timothy Pearson <tpearson@raptorengineering.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
linux-user/x86_64/termbits.h | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/linux-user/x86_64/termbits.h b/linux-user/x86_64/termbits.h
index 1c3445c..387e742 100644
--- a/linux-user/x86_64/termbits.h
+++ b/linux-user/x86_64/termbits.h
@@ -209,12 +209,12 @@ struct target_termios {
#define TARGET_TIOCSBRK 0x5427 /* BSD compatibility */
#define TARGET_TIOCCBRK 0x5428 /* BSD compatibility */
#define TARGET_TIOCGSID 0x5429 /* Return the session ID of FD */
-#define TARGET_TCGETS2 _IOR('T',0x2A, struct termios2)
-#define TARGET_TCSETS2 _IOW('T',0x2B, struct termios2)
-#define TARGET_TCSETSW2 _IOW('T',0x2C, struct termios2)
-#define TARGET_TCSETSF2 _IOW('T',0x2D, struct termios2)
-#define TARGET_TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
-#define TARGET_TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
+#define TARGET_TCGETS2 TARGET_IOR('T',0x2A, struct termios2)
+#define TARGET_TCSETS2 TARGET_IOW('T',0x2B, struct termios2)
+#define TARGET_TCSETSW2 TARGET_IOW('T',0x2C, struct termios2)
+#define TARGET_TCSETSF2 TARGET_IOW('T',0x2D, struct termios2)
+#define TARGET_TIOCGPTN TARGET_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
+#define TARGET_TIOCSPTLCK TARGET_IOW('T',0x31, int) /* Lock/unlock Pty */
#define TARGET_FIONCLEX 0x5450 /* these numbers need to be adjusted. */
#define TARGET_FIOCLEX 0x5451
--
2.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PULL 14/16] linux-user: define missing sparc syscalls
2016-07-19 12:53 [Qemu-devel] [PULL 00/16] linux-user before 2.7 hardfreeze riku.voipio
` (12 preceding siblings ...)
2016-07-19 12:54 ` [Qemu-devel] [PULL 13/16] TIOCGPTN and related terminal control ioctls were not converted to the guest ioctl format on x86_64 targets. Convert these ioctls to enable terminal functionality on x86_64 guests riku.voipio
@ 2016-07-19 12:54 ` riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 15/16] linux-user: Fix type for SIOCATMARK ioctl riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 16/16] linux-user: AArch64 has sync_file_range, not sync_file_range2 riku.voipio
15 siblings, 0 replies; 17+ messages in thread
From: riku.voipio @ 2016-07-19 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Laurent Vivier
From: Laurent Vivier <laurent@vivier.eu>
NR_lookup_dcookie, NR_fadvise64, NR_fadvise64_64
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
linux-user/sparc/syscall_nr.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/linux-user/sparc/syscall_nr.h b/linux-user/sparc/syscall_nr.h
index 732b105..e713c9d 100644
--- a/linux-user/sparc/syscall_nr.h
+++ b/linux-user/sparc/syscall_nr.h
@@ -179,6 +179,9 @@
#define TARGET_NR_readahead 205 /* Linux Specific */
#define TARGET_NR_socketcall 206 /* Linux Specific */
#define TARGET_NR_syslog 207 /* Linux Specific */
+#define TARGET_NR_lookup_dcookie 208 /* Linux Specific */
+#define TARGET_NR_fadvise64 209 /* Linux Specific */
+#define TARGET_NR_fadvise64_64 210 /* Linux Specific */
#define TARGET_NR_tgkill 211 /* Linux Specific */
#define TARGET_NR_waitpid 212 /* Linux Specific */
#define TARGET_NR_swapoff 213 /* Linux Specific */
--
2.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PULL 15/16] linux-user: Fix type for SIOCATMARK ioctl
2016-07-19 12:53 [Qemu-devel] [PULL 00/16] linux-user before 2.7 hardfreeze riku.voipio
` (13 preceding siblings ...)
2016-07-19 12:54 ` [Qemu-devel] [PULL 14/16] linux-user: define missing sparc syscalls riku.voipio
@ 2016-07-19 12:54 ` riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 16/16] linux-user: AArch64 has sync_file_range, not sync_file_range2 riku.voipio
15 siblings, 0 replies; 17+ messages in thread
From: riku.voipio @ 2016-07-19 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
From: Peter Maydell <peter.maydell@linaro.org>
The SIOCATMARK ioctl takes an argument which should be a
pointer to an integer where the kernel will write the result.
We were incorrectly declaring it as TYPE_NULL which would mean
it would always fail (with EFAULT) when it should succeed.
Correct the type.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
linux-user/ioctls.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index 4b36baa..7e2c133 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -120,7 +120,7 @@
MK_PTR(MK_STRUCT(STRUCT_fiemap)))
#endif
- IOCTL(SIOCATMARK, 0, TYPE_NULL)
+ IOCTL(SIOCATMARK, IOC_R, MK_PTR(TYPE_INT))
IOCTL(SIOCGIFNAME, IOC_RW, MK_PTR(TYPE_INT))
IOCTL(SIOCGIFFLAGS, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_short_ifreq)))
IOCTL(SIOCSIFFLAGS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_short_ifreq)))
--
2.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PULL 16/16] linux-user: AArch64 has sync_file_range, not sync_file_range2
2016-07-19 12:53 [Qemu-devel] [PULL 00/16] linux-user before 2.7 hardfreeze riku.voipio
` (14 preceding siblings ...)
2016-07-19 12:54 ` [Qemu-devel] [PULL 15/16] linux-user: Fix type for SIOCATMARK ioctl riku.voipio
@ 2016-07-19 12:54 ` riku.voipio
15 siblings, 0 replies; 17+ messages in thread
From: riku.voipio @ 2016-07-19 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
From: Peter Maydell <peter.maydell@linaro.org>
The AArch64 Linux ABI syscall 84 is sync_file_range, not
sync_file_range2 (in the kernel it uses the asm-generic
headers and does not define __ARCH_WANT_SYNC_FILE_RANGE2).
Update our TARGET_NR_* definitions accordingly.
This fixes the sync_file_range syscall which otherwise
gets its arguments in the wrong order.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
linux-user/aarch64/syscall_nr.h | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/linux-user/aarch64/syscall_nr.h b/linux-user/aarch64/syscall_nr.h
index 59511d8..a3c9a3b 100644
--- a/linux-user/aarch64/syscall_nr.h
+++ b/linux-user/aarch64/syscall_nr.h
@@ -86,8 +86,7 @@
#define TARGET_NR_sync 81
#define TARGET_NR_fsync 82
#define TARGET_NR_fdatasync 83
-#define TARGET_NR_sync_file_range2 84
-/* #define TARGET_NR_sync_file_range 84 */
+#define TARGET_NR_sync_file_range 84
#define TARGET_NR_timerfd_create 85
#define TARGET_NR_timerfd_settime 86
#define TARGET_NR_timerfd_gettime 87
--
2.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
end of thread, other threads:[~2016-07-19 12:54 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-07-19 12:53 [Qemu-devel] [PULL 00/16] linux-user before 2.7 hardfreeze riku.voipio
2016-07-19 12:53 ` [Qemu-devel] [PULL 01/16] linux-user: fd_trans_*_data() returns the length riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 02/16] linux-user: fix netlink memory corruption riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 03/16] linux-user: add fd_trans helper in do_recvfrom() riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 04/16] linux-user: convert sockaddr_ll from host to target riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 05/16] linux-user: add nested netlink types riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 06/16] linux-user: Check sigsetsize argument to syscalls riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 07/16] linux-user: Add loop control ioctls riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 08/16] linux-user: Correct type for BLKSSZGET riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 09/16] linux-user: Correct type for LOOP_GET_STATUS{, 64} ioctls riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 10/16] linux-user: Forget about synchronous signal once it is delivered riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 11/16] linux-user: Handle short lengths in host_to_target_sockaddr() riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 12/16] linux-user: Add some new blk ioctls riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 13/16] TIOCGPTN and related terminal control ioctls were not converted to the guest ioctl format on x86_64 targets. Convert these ioctls to enable terminal functionality on x86_64 guests riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 14/16] linux-user: define missing sparc syscalls riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 15/16] linux-user: Fix type for SIOCATMARK ioctl riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 16/16] linux-user: AArch64 has sync_file_range, not sync_file_range2 riku.voipio
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).