All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/2] linux-user: netlink cleanup
@ 2016-06-16 19:01 Laurent Vivier
  2016-06-16 19:01 ` [Qemu-devel] [PATCH 1/2] linux-user: fd_trans_host_to_target_data() must process only received data Laurent Vivier
  2016-06-16 19:01 ` [Qemu-devel] [PATCH 2/2] linux-user: don't swap NLMSG_DATA() fields Laurent Vivier
  0 siblings, 2 replies; 6+ messages in thread
From: Laurent Vivier @ 2016-06-16 19:01 UTC (permalink / raw)
  To: Riku Voipio; +Cc: qemu-devel, Laurent Vivier

Some cleanup to avoid memory corruption while netlink
helpers are processing data stream.

Laurent Vivier (2):
  linux-user: fd_trans_host_to_target_data() must process only received
    data
  linux-user: don't swap NLMSG_DATA() fields

 linux-user/syscall.c | 74 ++++++++++++++++++++++++++++++----------------------
 1 file changed, 43 insertions(+), 31 deletions(-)

-- 
2.5.5

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Qemu-devel] [PATCH 1/2] linux-user: fd_trans_host_to_target_data() must process only received data
  2016-06-16 19:01 [Qemu-devel] [PATCH 0/2] linux-user: netlink cleanup Laurent Vivier
@ 2016-06-16 19:01 ` Laurent Vivier
  2016-06-16 21:05   ` Peter Maydell
  2016-06-16 19:01 ` [Qemu-devel] [PATCH 2/2] linux-user: don't swap NLMSG_DATA() fields Laurent Vivier
  1 sibling, 1 reply; 6+ messages in thread
From: Laurent Vivier @ 2016-06-16 19:01 UTC (permalink / raw)
  To: Riku Voipio; +Cc: qemu-devel, Laurent Vivier

if we process the whole buffer, the netlink helpers can try
to swap invalid data.

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 linux-user/syscall.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 0b937ca..3c30437 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -2987,7 +2987,7 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
             len = ret;
             if (fd_trans_host_to_target_data(fd)) {
                 ret = fd_trans_host_to_target_data(fd)(msg.msg_iov->iov_base,
-                                                       msg.msg_iov->iov_len);
+                                                       len);
             } else {
                 ret = host_to_target_cmsg(msgp, &msg);
             }
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [Qemu-devel] [PATCH 2/2] linux-user: don't swap NLMSG_DATA() fields
  2016-06-16 19:01 [Qemu-devel] [PATCH 0/2] linux-user: netlink cleanup Laurent Vivier
  2016-06-16 19:01 ` [Qemu-devel] [PATCH 1/2] linux-user: fd_trans_host_to_target_data() must process only received data Laurent Vivier
@ 2016-06-16 19:01 ` Laurent Vivier
  2016-06-16 21:09   ` Peter Maydell
  1 sibling, 1 reply; 6+ messages in thread
From: Laurent Vivier @ 2016-06-16 19:01 UTC (permalink / raw)
  To: Riku Voipio; +Cc: qemu-devel, Laurent Vivier

If the structure pointed by NLMSG_DATA() is bigger
than the size of NLMSG_DATA(), don't swap its fields
to avoid memory corruption.

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 linux-user/syscall.c | 72 ++++++++++++++++++++++++++++++----------------------
 1 file changed, 42 insertions(+), 30 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 3c30437..a0a3e65 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -1944,29 +1944,35 @@ static abi_long host_to_target_data_route(struct nlmsghdr *nlh)
     case RTM_NEWLINK:
     case RTM_DELLINK:
     case RTM_GETLINK:
-        ifi = NLMSG_DATA(nlh);
-        ifi->ifi_type = tswap16(ifi->ifi_type);
-        ifi->ifi_index = tswap32(ifi->ifi_index);
-        ifi->ifi_flags = tswap32(ifi->ifi_flags);
-        ifi->ifi_change = tswap32(ifi->ifi_change);
-        host_to_target_link_rtattr(IFLA_RTA(ifi),
-                                   nlmsg_len - NLMSG_LENGTH(sizeof(*ifi)));
+        if (nlh->nlmsg_len >= NLMSG_LENGTH(sizeof(*ifi))) {
+            ifi = NLMSG_DATA(nlh);
+            ifi->ifi_type = tswap16(ifi->ifi_type);
+            ifi->ifi_index = tswap32(ifi->ifi_index);
+            ifi->ifi_flags = tswap32(ifi->ifi_flags);
+            ifi->ifi_change = tswap32(ifi->ifi_change);
+            host_to_target_link_rtattr(IFLA_RTA(ifi),
+                                       nlmsg_len - NLMSG_LENGTH(sizeof(*ifi)));
+        }
         break;
     case RTM_NEWADDR:
     case RTM_DELADDR:
     case RTM_GETADDR:
-        ifa = NLMSG_DATA(nlh);
-        ifa->ifa_index = tswap32(ifa->ifa_index);
-        host_to_target_addr_rtattr(IFA_RTA(ifa),
-                                   nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)));
+        if (nlh->nlmsg_len >= NLMSG_LENGTH(sizeof(*ifa))) {
+            ifa = NLMSG_DATA(nlh);
+            ifa->ifa_index = tswap32(ifa->ifa_index);
+            host_to_target_addr_rtattr(IFA_RTA(ifa),
+                                       nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)));
+        }
         break;
     case RTM_NEWROUTE:
     case RTM_DELROUTE:
     case RTM_GETROUTE:
-        rtm = NLMSG_DATA(nlh);
-        rtm->rtm_flags = tswap32(rtm->rtm_flags);
-        host_to_target_route_rtattr(RTM_RTA(rtm),
-                                    nlmsg_len - NLMSG_LENGTH(sizeof(*rtm)));
+        if (nlh->nlmsg_len >= NLMSG_LENGTH(sizeof(*rtm))) {
+            rtm = NLMSG_DATA(nlh);
+            rtm->rtm_flags = tswap32(rtm->rtm_flags);
+            host_to_target_route_rtattr(RTM_RTA(rtm),
+                                        nlmsg_len - NLMSG_LENGTH(sizeof(*rtm)));
+        }
         break;
     default:
         return -TARGET_EINVAL;
@@ -2082,30 +2088,36 @@ static abi_long target_to_host_data_route(struct nlmsghdr *nlh)
         break;
     case RTM_NEWLINK:
     case RTM_DELLINK:
-        ifi = NLMSG_DATA(nlh);
-        ifi->ifi_type = tswap16(ifi->ifi_type);
-        ifi->ifi_index = tswap32(ifi->ifi_index);
-        ifi->ifi_flags = tswap32(ifi->ifi_flags);
-        ifi->ifi_change = tswap32(ifi->ifi_change);
-        target_to_host_link_rtattr(IFLA_RTA(ifi), nlh->nlmsg_len -
-                                   NLMSG_LENGTH(sizeof(*ifi)));
+        if (nlh->nlmsg_len >= NLMSG_LENGTH(sizeof(*ifi))) {
+            ifi = NLMSG_DATA(nlh);
+            ifi->ifi_type = tswap16(ifi->ifi_type);
+            ifi->ifi_index = tswap32(ifi->ifi_index);
+            ifi->ifi_flags = tswap32(ifi->ifi_flags);
+            ifi->ifi_change = tswap32(ifi->ifi_change);
+            target_to_host_link_rtattr(IFLA_RTA(ifi), nlh->nlmsg_len -
+                                       NLMSG_LENGTH(sizeof(*ifi)));
+        }
         break;
     case RTM_GETADDR:
     case RTM_NEWADDR:
     case RTM_DELADDR:
-        ifa = NLMSG_DATA(nlh);
-        ifa->ifa_index = tswap32(ifa->ifa_index);
-        target_to_host_addr_rtattr(IFA_RTA(ifa), nlh->nlmsg_len -
-                                   NLMSG_LENGTH(sizeof(*ifa)));
+        if (nlh->nlmsg_len >= NLMSG_LENGTH(sizeof(*ifa))) {
+            ifa = NLMSG_DATA(nlh);
+            ifa->ifa_index = tswap32(ifa->ifa_index);
+            target_to_host_addr_rtattr(IFA_RTA(ifa), nlh->nlmsg_len -
+                                       NLMSG_LENGTH(sizeof(*ifa)));
+        }
         break;
     case RTM_GETROUTE:
         break;
     case RTM_NEWROUTE:
     case RTM_DELROUTE:
-        rtm = NLMSG_DATA(nlh);
-        rtm->rtm_flags = tswap32(rtm->rtm_flags);
-        target_to_host_route_rtattr(RTM_RTA(rtm), nlh->nlmsg_len -
-                                    NLMSG_LENGTH(sizeof(*rtm)));
+        if (nlh->nlmsg_len >= NLMSG_LENGTH(sizeof(*rtm))) {
+            rtm = NLMSG_DATA(nlh);
+            rtm->rtm_flags = tswap32(rtm->rtm_flags);
+            target_to_host_route_rtattr(RTM_RTA(rtm), nlh->nlmsg_len -
+                                        NLMSG_LENGTH(sizeof(*rtm)));
+        }
         break;
     default:
         return -TARGET_EOPNOTSUPP;
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] [PATCH 1/2] linux-user: fd_trans_host_to_target_data() must process only received data
  2016-06-16 19:01 ` [Qemu-devel] [PATCH 1/2] linux-user: fd_trans_host_to_target_data() must process only received data Laurent Vivier
@ 2016-06-16 21:05   ` Peter Maydell
  0 siblings, 0 replies; 6+ messages in thread
From: Peter Maydell @ 2016-06-16 21:05 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: Riku Voipio, QEMU Developers

On 16 June 2016 at 20:01, Laurent Vivier <laurent@vivier.eu> wrote:
> if we process the whole buffer, the netlink helpers can try
> to swap invalid data.
>
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> ---
>  linux-user/syscall.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 0b937ca..3c30437 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -2987,7 +2987,7 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
>              len = ret;
>              if (fd_trans_host_to_target_data(fd)) {
>                  ret = fd_trans_host_to_target_data(fd)(msg.msg_iov->iov_base,
> -                                                       msg.msg_iov->iov_len);
> +                                                       len);
>              } else {
>                  ret = host_to_target_cmsg(msgp, &msg);
>              }

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] [PATCH 2/2] linux-user: don't swap NLMSG_DATA() fields
  2016-06-16 19:01 ` [Qemu-devel] [PATCH 2/2] linux-user: don't swap NLMSG_DATA() fields Laurent Vivier
@ 2016-06-16 21:09   ` Peter Maydell
  2016-06-16 22:09     ` Laurent Vivier
  0 siblings, 1 reply; 6+ messages in thread
From: Peter Maydell @ 2016-06-16 21:09 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: Riku Voipio, QEMU Developers

On 16 June 2016 at 20:01, Laurent Vivier <laurent@vivier.eu> wrote:
> If the structure pointed by NLMSG_DATA() is bigger
> than the size of NLMSG_DATA(), don't swap its fields
> to avoid memory corruption.
>
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> ---

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

Can this actually happen in normal operation?

thanks
-- PMM

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] [PATCH 2/2] linux-user: don't swap NLMSG_DATA() fields
  2016-06-16 21:09   ` Peter Maydell
@ 2016-06-16 22:09     ` Laurent Vivier
  0 siblings, 0 replies; 6+ messages in thread
From: Laurent Vivier @ 2016-06-16 22:09 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Riku Voipio, QEMU Developers



Le 16/06/2016 à 23:09, Peter Maydell a écrit :
> On 16 June 2016 at 20:01, Laurent Vivier <laurent@vivier.eu> wrote:
>> If the structure pointed by NLMSG_DATA() is bigger
>> than the size of NLMSG_DATA(), don't swap its fields
>> to avoid memory corruption.
>>
>> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
>> ---
> 
> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
> 
> Can this actually happen in normal operation?

Yes, I've detected that debugging "apt-get update" on debian jessie with
qemu-s390x. This is the first call to netlink:

00 00 00 14     nlmsg_len=20
00 16           nlmsg_type=RTM_GETADDR
03 01           nlmsg_flags=0x0301
57 62 b7 fb     nlmsg_seq=0x5762b7fb
00 00 00 00     nlmsg_pid=0
00 00 00 00	NLMSG_DATA() = struct ifaddrmsg

struct ifaddrmsg {
        __u8            ifa_family;
        __u8            ifa_prefixlen;
        __u8            ifa_flags;
        __u8            ifa_scope;
        __u32           ifa_index;
};

Laurent

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2016-06-16 22:10 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-16 19:01 [Qemu-devel] [PATCH 0/2] linux-user: netlink cleanup Laurent Vivier
2016-06-16 19:01 ` [Qemu-devel] [PATCH 1/2] linux-user: fd_trans_host_to_target_data() must process only received data Laurent Vivier
2016-06-16 21:05   ` Peter Maydell
2016-06-16 19:01 ` [Qemu-devel] [PATCH 2/2] linux-user: don't swap NLMSG_DATA() fields Laurent Vivier
2016-06-16 21:09   ` Peter Maydell
2016-06-16 22:09     ` Laurent Vivier

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.