From: Yixin Wei <[email protected]>

host_to_target_for_each_rtattr() uses "len > sizeof(struct rtattr)"
as its loop condition. When the last rtattr in a netlink message has
exactly sizeof(struct rtattr) (4) bytes remaining, the loop exits
without byte-swapping its rta_len and rta_type. A big-endian guest
then reads rta_len in the wrong byte order and fails validation.

The companion function target_to_host_for_each_rtattr() correctly
uses ">=" (added in commit fa2229dbf8). The kernel's RTA_OK macro
also uses ">=". Fix the host_to_target direction to match.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2485
Signed-off-by: Yixin Wei <[email protected]>
Fixes: 6c5b5645ae0 ("linux-user: add rtnetlink(7) support")
Reviewed-by: Philippe Mathieu-Daudé <[email protected]>
Signed-off-by: Helge Deller <[email protected]>
Cc: [email protected]
(cherry picked from commit 029f10e852780da846d3e7f1691c495474683b73)
Signed-off-by: Michael Tokarev <[email protected]>

diff --git a/linux-user/fd-trans.c b/linux-user/fd-trans.c
index f83d1f79d5..1045ae7b1a 100644
--- a/linux-user/fd-trans.c
+++ b/linux-user/fd-trans.c
@@ -482,7 +482,7 @@ static abi_long host_to_target_for_each_rtattr(struct 
rtattr *rtattr,
     unsigned short aligned_rta_len;
     abi_long ret;
 
-    while (len > sizeof(struct rtattr)) {
+    while (len >= sizeof(struct rtattr)) {
         rta_len = rtattr->rta_len;
         if (rta_len < sizeof(struct rtattr) ||
             rta_len > len) {
-- 
2.47.3


Reply via email to