lkml.org 
[lkml]   [2019]   [Feb]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 4.14 08/45] ipvs: Fix signed integer overflow when setsockopt timeout
    Date
    From: ZhangXiaoxu <zhangxiaoxu5@huawei.com>

    [ Upstream commit 53ab60baa1ac4f20b080a22c13b77b6373922fd7 ]

    There is a UBSAN bug report as below:
    UBSAN: Undefined behaviour in net/netfilter/ipvs/ip_vs_ctl.c:2227:21
    signed integer overflow:
    -2147483647 * 1000 cannot be represented in type 'int'

    Reproduce program:
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/socket.h>

    #define IPPROTO_IP 0
    #define IPPROTO_RAW 255

    #define IP_VS_BASE_CTL (64+1024+64)
    #define IP_VS_SO_SET_TIMEOUT (IP_VS_BASE_CTL+10)

    /* The argument to IP_VS_SO_GET_TIMEOUT */
    struct ipvs_timeout_t {
    int tcp_timeout;
    int tcp_fin_timeout;
    int udp_timeout;
    };

    int main() {
    int ret = -1;
    int sockfd = -1;
    struct ipvs_timeout_t to;

    sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
    if (sockfd == -1) {
    printf("socket init error\n");
    return -1;
    }

    to.tcp_timeout = -2147483647;
    to.tcp_fin_timeout = -2147483647;
    to.udp_timeout = -2147483647;

    ret = setsockopt(sockfd,
    IPPROTO_IP,
    IP_VS_SO_SET_TIMEOUT,
    (char *)(&to),
    sizeof(to));

    printf("setsockopt return %d\n", ret);
    return ret;
    }

    Return -EINVAL if the timeout value is negative or max than 'INT_MAX / HZ'.

    Signed-off-by: ZhangXiaoxu <zhangxiaoxu5@huawei.com>
    Acked-by: Simon Horman <horms@verge.net.au>
    Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    net/netfilter/ipvs/ip_vs_ctl.c | 12 ++++++++++++
    1 file changed, 12 insertions(+)

    diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
    index 2f45c3ce77ef2..dff4ead3d117c 100644
    --- a/net/netfilter/ipvs/ip_vs_ctl.c
    +++ b/net/netfilter/ipvs/ip_vs_ctl.c
    @@ -2252,6 +2252,18 @@ static int ip_vs_set_timeout(struct netns_ipvs *ipvs, struct ip_vs_timeout_user
    u->tcp_fin_timeout,
    u->udp_timeout);

    +#ifdef CONFIG_IP_VS_PROTO_TCP
    + if (u->tcp_timeout < 0 || u->tcp_timeout > (INT_MAX / HZ) ||
    + u->tcp_fin_timeout < 0 || u->tcp_fin_timeout > (INT_MAX / HZ)) {
    + return -EINVAL;
    + }
    +#endif
    +
    +#ifdef CONFIG_IP_VS_PROTO_UDP
    + if (u->udp_timeout < 0 || u->udp_timeout > (INT_MAX / HZ))
    + return -EINVAL;
    +#endif
    +
    #ifdef CONFIG_IP_VS_PROTO_TCP
    if (u->tcp_timeout) {
    pd = ip_vs_proto_data_get(ipvs, IPPROTO_TCP);
    --
    2.19.1
    \
     
     \ /
      Last update: 2019-02-23 22:22    [W:4.126 / U:0.056 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site