Commit b9403979 authored by Laurent Vivier's avatar Laurent Vivier Committed by Riku Voipio
Browse files

linux-user: don't swap NLMSG_DATA() fields



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: default avatarLaurent Vivier <laurent@vivier.eu>
Signed-off-by: default avatarRiku Voipio <riku.voipio@linaro.org>
Reviewed-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parent 48dc0f2c
Loading
Loading
Loading
Loading
+42 −30
Original line number Diff line number Diff line
@@ -1948,6 +1948,7 @@ static abi_long host_to_target_data_route(struct nlmsghdr *nlh)
    case RTM_NEWLINK:
    case RTM_DELLINK:
    case RTM_GETLINK:
        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);
@@ -1955,22 +1956,27 @@ static abi_long host_to_target_data_route(struct nlmsghdr *nlh)
            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:
        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:
        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,6 +2092,7 @@ static abi_long target_to_host_data_route(struct nlmsghdr *nlh)
        break;
    case RTM_NEWLINK:
    case RTM_DELLINK:
        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);
@@ -2093,23 +2100,28 @@ static abi_long target_to_host_data_route(struct nlmsghdr *nlh)
            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:
        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:
        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;