68 lines
2.7 KiB
Diff
68 lines
2.7 KiB
Diff
From f4f57679b736367716389d05187bab40666b521d Mon Sep 17 00:00:00 2001
|
|
From: Petr Vorel <pvorel@suse.cz>
|
|
Date: Fri, 9 May 2025 11:07:02 +0200
|
|
Subject: [PATCH 1/4] ping: Fix integer overflow in large -s and -l values
|
|
|
|
Maximum of preload value (-l) is 65536, but due multiplication with
|
|
packat size (-s) there can be integer overflow:
|
|
|
|
$ export CFLAGS="-O1 -g -fsanitize=address,undefined -fno-omit-frame-pointer"
|
|
$ meson setup ..
|
|
$ ninja && sudo ./ping/ping -c1 -l 65536 -s 30000 ::1
|
|
../ping/ping_common.c:451:24: runtime error: signed integer overflow: 65536 * 46528 cannot be represented in type 'int'
|
|
PING ::1 (::1) 30000 data bytes
|
|
30008 bytes from ::1: icmp_seq=1 ttl=64 time=0.052 ms
|
|
|
|
Because setsockopt() requires int, instead of making hold and rcvbuf
|
|
variables bigger (long int) limit them to INT_MAX. This will often lead
|
|
to warning about rcvbuf is not enough to hold preload, because on
|
|
current kernel 6.14 and ICMP datagram socket is the max. socket buffer
|
|
size 425984, but probably better not to depend on this value.
|
|
|
|
After fix:
|
|
|
|
$ sudo ./ping/ping -c1 -l 65536 -s 30000 127.0.0.1
|
|
./ping/ping: WARNING: buffer size overflow, reduce packet size or preload
|
|
./ping/ping: WARNING: probably, rcvbuf is not enough to hold preload
|
|
PING 127.0.0.1 (127.0.0.1) 30000(30028) bytes of data.
|
|
30008 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.053 ms
|
|
|
|
Link: https://github.com/iputils/iputils/pull/585#pullrequestreview-2820034501
|
|
Closes: https://github.com/iputils/iputils/pull/586
|
|
Reported-by: Mohamed Maatallah <hotelsmaatallahrecemail@gmail.com>
|
|
Suggested-by: Mohamed Maatallah <hotelsmaatallahrecemail@gmail.com>
|
|
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
|
|
[ pvorel: backport of upstream f30f0e5397542a6ebf6bf1d5f6cd785637293393 to 20221126 ]
|
|
Signed-off-by: Petr Vorel <pvorel@suse.cz>
|
|
---
|
|
ping/ping_common.c | 11 ++++++++++-
|
|
1 file changed, 10 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/ping/ping_common.c b/ping/ping_common.c
|
|
index 687613a..0d0da76 100644
|
|
--- a/ping/ping_common.c
|
|
+++ b/ping/ping_common.c
|
|
@@ -443,9 +443,18 @@ void sock_setbufs(struct ping_rts *rts, socket_st *sock, int alloc)
|
|
rts->sndbuf = alloc;
|
|
setsockopt(sock->fd, SOL_SOCKET, SO_SNDBUF, (char *)&rts->sndbuf, sizeof(rts->sndbuf));
|
|
|
|
- rcvbuf = hold = alloc * rts->preload;
|
|
+ if (alloc > INT_MAX / rts->preload) {
|
|
+ error(0, 0, _("WARNING: buffer size overflow, reduce packet size or preload"));
|
|
+ hold = INT_MAX;
|
|
+ } else {
|
|
+ hold = alloc * rts->preload;
|
|
+ }
|
|
+
|
|
+ rcvbuf = hold;
|
|
+
|
|
if (hold < 65536)
|
|
hold = 65536;
|
|
+
|
|
setsockopt(sock->fd, SOL_SOCKET, SO_RCVBUF, (char *)&hold, sizeof(hold));
|
|
if (getsockopt(sock->fd, SOL_SOCKET, SO_RCVBUF, (char *)&hold, &tmplen) == 0) {
|
|
if (hold < rcvbuf)
|
|
--
|
|
2.49.0
|
|
|