提交 738e06fc 编写于 作者: H Hui Wang 提交者: Xie XiuQi

ip_vs: fix signed integer overflow while set timeout

euler inclusion
category: bugfix
bugzilla: 5380
CVE: NA

-------------------------------------------------

when do syzkallor test, there is a BUG report as blew:

================================================================================
UBSAN: Undefined behaviour in net/netfilter/ipvs/ip_vs_ctl.c:3133:21
signed integer overflow:
2147483647 * 1000 cannot be represented in type 'int'
CPU: 17 PID: 44410 Comm: syz-executor Tainted: G    B   W      ---- -------   3.10.0-#1
Hardware name: Huawei Technologies Co., Ltd. Tecal RH2285 V2-12L/BC11SRSC1, BIOS RMISV060 06/07/2013
Call Trace:
 [<ffffffffb97113e6>] dump_stack+0x1e/0x20 lib/dump_stack.c:18
 [<ffffffffb97114a3>] ubsan_epilogue+0x12/0x55 lib/ubsan.c:164
 [<ffffffffb9712988>] handle_overflow+0x1ba/0x215 lib/ubsan.c:195
 [<ffffffffb9712a6f>] __ubsan_handle_mul_overflow+0x2a/0x31 lib/ubsan.c:219
 [<ffffffffc1d54d89>] ip_vs_set_timeout+0x1e9/0x270 [ip_vs]
 [<ffffffffc1d61f10>] do_ip_vs_set_ctl+0xad0/0xfa0 [ip_vs]
 [<ffffffffb94c539f>] nf_sockopt net/netfilter/nf_sockopt.c:111 [inline]
 [<ffffffffb94c539f>] nf_setsockopt+0xaf/0xf0 net/netfilter/nf_sockopt.c:118
 [<ffffffffb94f45dc>] ip_setsockopt+0xac/0xc0 net/ipv4/ip_sockglue.c:1121
 [<ffffffffb956457a>] udp_setsockopt+0x4a/0x90 net/ipv4/udp.c:1935
 [<ffffffffb93e9616>] sock_common_setsockopt+0x76/0xc0 net/core/sock.c:2523
 [<ffffffffb93e6d65>] SYSC_setsockopt net/socket.c:1896 [inline]
 [<ffffffffb93e6d65>] SyS_setsockopt+0x155/0x270 net/socket.c:1872
 [<ffffffffb973bb1b>] system_call_fastpath+0x22/0x27
================================================================================

tcp_timeout can be set by ipvsadm command, while in ipvsadm, max
timeout is 86400*31, check below:
https://git.kernel.org/pub/scm/utils/kernel/ipvsadm/ipvsadm.git/tree/ipvsadm.c

in kernel, it will be multiplied by HZ that can be 1000, then the max
value of tcp_timeout, tcp_fin_timeout and udp_timeout would be 2678400000,
which is beyond 2147483647.

So, if set the timeout with 31 days, the effect value is the INT_MAX ms.
Signed-off-by: NHui Wang <john.wanghui@huawei.com>
Signed-off-by: NZhang Xiaoxu <zhangxiaoxu5@huawei.com>
Reviewed-by: NWei Yongjun <weiyongjun1@huawei.com>
Signed-off-by: NZhang Xiaoxu <zhangxiaoxu5@huawei.com>
[yyl: backport from rh7.5]
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 c01d923a
......@@ -2223,22 +2223,34 @@ static int ip_vs_set_timeout(struct netns_ipvs *ipvs, struct ip_vs_timeout_user
#ifdef CONFIG_IP_VS_PROTO_TCP
if (u->tcp_timeout) {
pd = ip_vs_proto_data_get(ipvs, IPPROTO_TCP);
pd->timeout_table[IP_VS_TCP_S_ESTABLISHED]
= u->tcp_timeout * HZ;
if (u->tcp_timeout >= INT_MAX / HZ) {
pd->timeout_table[IP_VS_TCP_S_ESTABLISHED] = INT_MAX;
printk(KERN_WARNING "tcp_timeout * HZ overflowed, use INT_MAX as tcp_timeout instead\n");
} else
pd->timeout_table[IP_VS_TCP_S_ESTABLISHED]
= u->tcp_timeout * HZ;
}
if (u->tcp_fin_timeout) {
pd = ip_vs_proto_data_get(ipvs, IPPROTO_TCP);
pd->timeout_table[IP_VS_TCP_S_FIN_WAIT]
= u->tcp_fin_timeout * HZ;
if (u->tcp_fin_timeout >= INT_MAX / HZ) {
pd->timeout_table[IP_VS_TCP_S_FIN_WAIT] = INT_MAX;
printk(KERN_WARNING "tcp_fin_timeout * HZ overflowed, use INT_MAX as tcp_fin_timeout instead\n");
} else
pd->timeout_table[IP_VS_TCP_S_FIN_WAIT]
= u->tcp_fin_timeout * HZ;
}
#endif
#ifdef CONFIG_IP_VS_PROTO_UDP
if (u->udp_timeout) {
pd = ip_vs_proto_data_get(ipvs, IPPROTO_UDP);
pd->timeout_table[IP_VS_UDP_S_NORMAL]
= u->udp_timeout * HZ;
if (u->udp_timeout >= INT_MAX / HZ) {
pd->timeout_table[IP_VS_UDP_S_NORMAL] = INT_MAX;
printk(KERN_WARNING "udp_timeout * HZ overflowed, use INT_MAX as udp_timeout instead\n");
} else
pd->timeout_table[IP_VS_UDP_S_NORMAL]
= u->udp_timeout * HZ;
}
#endif
return 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册