]> git.gsnw.org Git - fping.git/commitdiff
Safe memory allocation for event storage.
authorDavid Schweikert <david@schweikert.ch>
Sun, 17 Aug 2025 20:42:45 +0000 (22:42 +0200)
committerDavid Schweikert <david@schweikert.ch>
Tue, 19 Aug 2025 07:36:41 +0000 (09:36 +0200)
- Check calloc return value.
- Make sure that the per-host interval can't be unreasonably low (making the event storage allocation very large).

The issue was reported by David.A.

ci/test-03-forbidden.pl
src/fping.c

index 84a305ffb64e6af81229a08a903fd89912dac81d..7b4659f44bb295da969f8a2b6fc5e9def2da1063 100755 (executable)
@@ -7,8 +7,7 @@ my $cmd1 = Test::Command->new(cmd => "fping -i 0 -T10 -g 127.0.0.1/29");
 $cmd1->exit_is_num(1);
 $cmd1->stdout_is_eq("");
 $cmd1->stderr_is_eq(<<END);
-fping: these options are too risky for mere mortals.
-fping: You need -i >= 1 and -p >= 10
+fping: -i must be >= 1
 END
 
 # fping -p 9
@@ -16,8 +15,7 @@ my $cmd2 = Test::Command->new(cmd => "fping -c3 -p 9 127.0.0.1");
 $cmd2->exit_is_num(1);
 $cmd2->stdout_is_eq("");
 $cmd2->stderr_is_eq(<<END);
-fping: these options are too risky for mere mortals.
-fping: You need -i >= 1 and -p >= 10
+fping: -p must be >= 10
 END
 
 # fping -H 300
index ae207b426196feb7f7c8473a704d6a34a7dca037..dcffd178df922d64387d9b3d656f6e8edf4978e6 100644 (file)
@@ -149,13 +149,16 @@ extern int h_errno;
 /* ICMP Timestamp has a fixed payload size of 12 bytes */
 #define ICMP_TIMESTAMP_DATA_SIZE 12
 
-/* maxima and minima */
 #ifdef FPING_SAFE_LIMITS
-#define MIN_INTERVAL 1 /* in millisec */
-#define MIN_PERHOST_INTERVAL 10 /* in millisec */
+#define MIN_INTERVAL_MS 1 /* in millisec */
+#define MIN_PERHOST_INTERVAL_MS 10 /* in millisec */
 #else
-#define MIN_INTERVAL 0
-#define MIN_PERHOST_INTERVAL 0
+#define MIN_INTERVAL_MS 0
+/* Set a very low limit for the per-host interval, even if safe limits are
+ * disabled, so that the memory allocation of the event storage is not
+ * unreasonably high. 0.001 ms would mean in theory at least 592 mbps of data
+ * sent to a single host, which probably doesn't make sense in any scenario. */
+#define MIN_PERHOST_INTERVAL_MS 0.001
 #endif
 
 /* response time array flags */
@@ -1057,15 +1060,15 @@ int main(int argc, char **argv)
         exit(1);
     }
 
-#ifdef FPING_SAFE_LIMITS
-    if ((interval < (int64_t)MIN_INTERVAL * 1000000 || perhost_interval < (int64_t)MIN_PERHOST_INTERVAL * 1000000)
-        && getuid()) {
-        fprintf(stderr, "%s: these options are too risky for mere mortals.\n", prog);
-        fprintf(stderr, "%s: You need -i >= %u and -p >= %u\n",
-            prog, MIN_INTERVAL, MIN_PERHOST_INTERVAL);
+    if (interval < (float)MIN_INTERVAL_MS * 1000000 && getuid()) {
+        fprintf(stderr, "%s: -i must be >= %g\n", prog, (float)MIN_INTERVAL_MS);
+        exit(1);
+    }
+
+    if (perhost_interval < (float)MIN_PERHOST_INTERVAL_MS * 1000000 && getuid()) {
+        fprintf(stderr, "%s: -p must be >= %g\n", prog, (float)MIN_PERHOST_INTERVAL_MS);
         exit(1);
     }
-#endif
 
     if (ping_data_size > MAX_PING_DATA) {
         fprintf(stderr, "%s: data size %u not valid, must not be larger than %u\n",
@@ -3448,7 +3451,13 @@ void add_addr(char *name, char *host, struct sockaddr *ipaddr, socklen_t ipaddr_
 
     /* allocate event storage */
     p->event_storage_ping = (struct event *)calloc(event_storage_count, sizeof(struct event));
+    if (!p->event_storage_ping) {
+        errno_crash_and_burn("can't allocate event_storage_ping");
+    }
     p->event_storage_timeout = (struct event *)calloc(event_storage_count, sizeof(struct event));
+    if (!p->event_storage_timeout) {
+        errno_crash_and_burn("can't allocate event_storage_timeout");
+    }
 
     /* schedule first ping */
     host_add_ping_event(p, 0, current_time_ns);