From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58998) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bGNo5-0000xA-5R for qemu-devel@nongnu.org; Fri, 24 Jun 2016 05:53:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bGNo4-0003Sx-0T for qemu-devel@nongnu.org; Fri, 24 Jun 2016 05:53:49 -0400 Received: from mail-lf0-x234.google.com ([2a00:1450:4010:c07::234]:34776) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bGNo3-0003SD-K1 for qemu-devel@nongnu.org; Fri, 24 Jun 2016 05:53:47 -0400 Received: by mail-lf0-x234.google.com with SMTP id h129so112858245lfh.1 for ; Fri, 24 Jun 2016 02:53:47 -0700 (PDT) From: riku.voipio@linaro.org Date: Fri, 24 Jun 2016 12:53:13 +0300 Message-Id: In-Reply-To: References: Subject: [Qemu-devel] [PULL 18/24] linux-user: don't swap NLMSG_DATA() fields List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Laurent Vivier From: 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 Signed-off-by: Riku Voipio Reviewed-by: Peter Maydell --- 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 b635127..52f88e2 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -1948,29 +1948,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; @@ -2086,30 +2092,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.1.4