]> git.ipfire.org Git - thirdparty/rsync.git/commitdiff
defence-in-depth: receiver block-index bounds + read_delay_line null check
authorAndrew Tridgell <andrew@tridgell.net>
Wed, 31 Dec 2025 03:01:34 +0000 (14:01 +1100)
committerAndrew Tridgell <andrew@tridgell.net>
Wed, 20 May 2026 00:01:22 +0000 (10:01 +1000)
Two assorted audit findings:

  - receive_data() never bounds-checked the block index returned
    by recv_token() against sum.count before computing offset2
    and feeding it to map_ptr(). An out-of-bounds index from a
    hostile sender produces invalid memory access. Add a
    sum.count bounds check.

  - read_delay_line()'s strchr() call could return NULL when no
    space was found, but the code unconditionally added 1 to the
    result before dereferencing. Low impact (just a disconnect on
    exit of the client-specific forked process) but the NULL
    deref is real. Guard the NULL.

Both reported by Joshua Rogers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
generator.c
receiver.c

index 89f99db4e06a962911eaaea30978126cca9d8dfc..4d4ae72e38817494dc28a4748b52d6e443eced14 100644 (file)
@@ -229,11 +229,13 @@ static int read_delay_line(char *buf, int *flags_p)
                *flags_p = 0;
 
        if (sscanf(bp, "%x ", &mode) != 1) {
-         invalid_data:
-               rprintf(FERROR, "ERROR: invalid data in delete-delay file.\n");
-               return -1;
+               goto invalid_data;
+       }
+       past_space = strchr(bp, ' ');
+       if (!past_space) {
+               goto invalid_data;
        }
-       past_space = strchr(bp, ' ') + 1;
+       past_space++;
        len = j - read_pos - (past_space - bp) + 1; /* count the '\0' */
        read_pos = j + 1;
 
@@ -247,6 +249,10 @@ static int read_delay_line(char *buf, int *flags_p)
        memcpy(buf, past_space, len);
 
        return mode;
+
+invalid_data:
+       rprintf(FERROR, "ERROR: invalid data in delete-delay file.\n");
+       return -1;
 }
 
 static void do_delayed_deletions(char *delbuf)
index 3fa68d71cc691dd6d4fe6999067798b796c52642..f49931bf1701fcea55e19c39098abf65daf3dbb0 100644 (file)
@@ -352,6 +352,11 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
                }
 
                i = -(i+1);
+               if (i < 0 || i >= sum.count) {
+                       rprintf(FERROR, "Invalid block index %d (count=%ld) [%s]\n",
+                               i, (long)sum.count, who_am_i());
+                       exit_cleanup(RERR_PROTOCOL);
+               }
                offset2 = i * (OFF_T)sum.blength;
                len = sum.blength;
                if (i == (int)sum.count-1 && sum.remainder != 0)