The branch main has been updated by oshogbo:

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

commit e15be258bbf2978dfc62b5483d86c76884eb8576
Author:     Mariusz Zaborski <[email protected]>
AuthorDate: 2026-06-16 17:02:02 +0000
Commit:     Mariusz Zaborski <[email protected]>
CommitDate: 2026-06-16 17:02:02 +0000

    ping6: fix outpack overflow in pattern fill loop
    
    The fill loop was bounded by packlen, which is sized for the receive
    buffer (datalen + IP6LEN + ICMP6ECHOLEN + EXTRA), not for outpack.
    With large datalen the loop wrote past outpack[MAXPACKETLEN].
    
    Bound it to the actual data area in outpack instead.
    
    Reported by:    Oculytic
    Reviewed by:    des, markj
    Differential Revision:  https://reviews.freebsd.org/D57441
---
 sbin/ping/ping6.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/sbin/ping/ping6.c b/sbin/ping/ping6.c
index b00b00ac8ce1..48f376ac6e5c 100644
--- a/sbin/ping/ping6.c
+++ b/sbin/ping/ping6.c
@@ -238,7 +238,7 @@ static struct iovec smsgiov;
 static char *scmsg = 0;
 
 static cap_channel_t *capdns_setup(void);
-static void     fill(char *, char *);
+static void     fill(char *, size_t, char *);
 static int      get_hoplim(struct msghdr *);
 static int      get_pathmtu(struct msghdr *);
 static struct in6_pktinfo *get_rcvpktinfo(struct msghdr *);
@@ -273,7 +273,8 @@ ping6(int argc, char *argv[])
        struct sockaddr_in6 from, *sin6;
        struct addrinfo hints, *res;
        struct sigaction si_sa;
-       int cc, i;
+       int cc;
+       size_t i;
        int almost_done, ch, hold, packlen, preload, optval, error;
        int nig_oldmcprefix = -1;
        u_char *datap;
@@ -483,7 +484,8 @@ ping6(int argc, char *argv[])
                        break;
                case 'p':               /* fill buffer with user pattern */
                        options |= F_PINGFILLED;
-                       fill((char *)datap, optarg);
+                       fill((char *)datap,
+                           sizeof(outpack) - (datap - outpack), optarg);
                                break;
                case 'q':
                        options |= F_QUIET;
@@ -762,7 +764,7 @@ ping6(int argc, char *argv[])
        if (!(packet = (u_char *)malloc((u_int)packlen)))
                err(1, "Unable to allocate packet");
        if (!(options & F_PINGFILLED))
-               for (i = ICMP6ECHOLEN; i < packlen; ++i)
+               for (i = (size_t)(datap - outpack); i < sizeof(outpack); ++i)
                        *datap++ = i;
 
        ident = getpid() & 0xFFFF;
@@ -2631,7 +2633,7 @@ pr_retip(struct ip6_hdr *ip6, u_char *end)
 }
 
 static void
-fill(char *bp, char *patp)
+fill(char *bp, size_t bplen, char *patp)
 {
        int ii, jj, kk;
        int pat[16];
@@ -2646,13 +2648,11 @@ fill(char *bp, char *patp)
            &pat[7], &pat[8], &pat[9], &pat[10], &pat[11], &pat[12],
            &pat[13], &pat[14], &pat[15]);
 
-/* xxx */
-       if (ii > 0)
-               for (kk = 0;
-                   (size_t)kk <= MAXDATALEN - 8 + sizeof(struct tv32) + ii;
-                   kk += ii)
+       if (ii > 0) {
+               for (kk = 0; (size_t)kk + ii <= bplen; kk += ii)
                        for (jj = 0; jj < ii; ++jj)
                                bp[jj + kk] = pat[jj];
+       }
        if (!(options & F_QUIET)) {
                (void)printf("PATTERN: 0x");
                for (jj = 0; jj < ii; ++jj)

Reply via email to