git: aa6683207d18 - main - ping: do a better job checking what we receive from the net

From: Maxim Konovalov <maxim_at_FreeBSD.org>
Date: Thu, 17 Sep 2026 00:37:13 UTC
The branch main has been updated by maxim:

URL: https://cgit.FreeBSD.org/src/commit/?id=aa6683207d189a0b58ccf8806bd9f8793914bc45

commit aa6683207d189a0b58ccf8806bd9f8793914bc45
Author:     Maxim Konovalov <maxim@FreeBSD.org>
AuthorDate: 2026-09-16 20:33:18 +0000
Commit:     Maxim Konovalov <maxim@FreeBSD.org>
CommitDate: 2026-09-17 00:31:09 +0000

    ping: do a better job checking what we receive from the net
    
    - zero out a buffer for the incoming icmp message that
      we are about to parse
    - for ICMP_MASKREPLY and ICMP_TSTAMPREPLY responses check their length
      and warn and reject them if they are truncated
    
    Without these checks a part of stack allocated struct icmp icp could
    be printed out which seems low severity since we already dropped root
    privileges by the time icp is allocated.
    
    Reviewed by:    glebius
    MFC after:      1 month
    Found with:     Claude Code Sonnet 5
    
    Differential Revision: https://reviews.freebsd.org/D59555
---
 sbin/ping/ping.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/sbin/ping/ping.c b/sbin/ping/ping.c
index 362264ff2428..5926641a4a50 100644
--- a/sbin/ping/ping.c
+++ b/sbin/ping/ping.c
@@ -1119,6 +1119,7 @@ pr_pack(char *buf, ssize_t cc, struct sockaddr_in *from, struct timespec *tv)
 	struct icmp oicmp;
 	const u_char *oicmp_raw;
 
+	bzero(&icp, sizeof(icp));
 	/*
 	 * Get size of IP header of the received packet.
 	 * The header length is contained in the lower four bits of the first
@@ -1158,6 +1159,20 @@ pr_pack(char *buf, ssize_t cc, struct sockaddr_in *from, struct timespec *tv)
 	if (icp.icmp_type == icmp_type_rsp) {
 		if (icp.icmp_id != ident)
 			return;			/* 'Twas not our ECHO */
+		if (icmp_type_rsp == ICMP_MASKREPLY &&
+		    cc < (ssize_t)(ICMP_MINLEN + MASK_LEN)) {
+			if (options & F_VERBOSE)
+				warnx("truncated mask reply (%zd bytes) from %s",
+				    cc, inet_ntoa(from->sin_addr));
+			return;
+		}
+		if (icmp_type_rsp == ICMP_TSTAMPREPLY &&
+		    cc < (ssize_t)(ICMP_MINLEN + TS_LEN)) {
+			if (options & F_VERBOSE)
+				warnx("truncated timestamp reply (%zd bytes) from %s",
+				    cc, inet_ntoa(from->sin_addr));
+			return;
+		}
 		++nreceived;
 		triptime = 0.0;
 		if (timing) {