Populate a sum_struct with values from the socket. This is * called by both the sender and the receiver. */
| 2023 | /* Populate a sum_struct with values from the socket. This is |
| 2024 | * called by both the sender and the receiver. */ |
| 2025 | void read_sum_head(int f, struct sum_struct *sum) |
| 2026 | { |
| 2027 | int32 max_blength = protocol_version < 30 ? OLD_MAX_BLOCK_SIZE : MAX_BLOCK_SIZE; |
| 2028 | sum->count = read_int(f); |
| 2029 | if (sum->count < 0) { |
| 2030 | rprintf(FERROR, "Invalid checksum count %ld [%s]\n", |
| 2031 | (long)sum->count, who_am_i()); |
| 2032 | exit_cleanup(RERR_PROTOCOL); |
| 2033 | } |
| 2034 | /* Guard against integer overflow in downstream allocations sized by |
| 2035 | * count*element_size. my_alloc uses divide-not-multiply so it is |
| 2036 | * already wraparound-safe, but checking here gives a clearer error |
| 2037 | * and also covers the (size_t)count * xfer_sum_len arithmetic that |
| 2038 | * is performed *before* reaching my_alloc. */ |
| 2039 | if (xfer_sum_len > 0 && (size_t)sum->count > SIZE_MAX / (size_t)xfer_sum_len) { |
| 2040 | rprintf(FERROR, "Invalid checksum count %ld (too large) [%s]\n", |
| 2041 | (long)sum->count, who_am_i()); |
| 2042 | exit_cleanup(RERR_PROTOCOL); |
| 2043 | } |
| 2044 | if ((size_t)sum->count > SIZE_MAX / sizeof(struct sum_buf)) { |
| 2045 | rprintf(FERROR, "Invalid checksum count %ld (sum_buf overflow) [%s]\n", |
| 2046 | (long)sum->count, who_am_i()); |
| 2047 | exit_cleanup(RERR_PROTOCOL); |
| 2048 | } |
| 2049 | sum->blength = read_int(f); |
| 2050 | if (sum->blength < 0 || sum->blength > max_blength) { |
| 2051 | rprintf(FERROR, "Invalid block length %ld [%s]\n", |
| 2052 | (long)sum->blength, who_am_i()); |
| 2053 | exit_cleanup(RERR_PROTOCOL); |
| 2054 | } |
| 2055 | sum->s2length = protocol_version < 27 ? csum_length : (int)read_int(f); |
| 2056 | if (sum->s2length < 0 || sum->s2length > xfer_sum_len) { |
| 2057 | rprintf(FERROR, "Invalid checksum length %d [%s]\n", |
| 2058 | sum->s2length, who_am_i()); |
| 2059 | exit_cleanup(RERR_PROTOCOL); |
| 2060 | } |
| 2061 | sum->remainder = read_int(f); |
| 2062 | if (sum->remainder < 0 || sum->remainder > sum->blength) { |
| 2063 | rprintf(FERROR, "Invalid remainder length %ld [%s]\n", |
| 2064 | (long)sum->remainder, who_am_i()); |
| 2065 | exit_cleanup(RERR_PROTOCOL); |
| 2066 | } |
| 2067 | } |
| 2068 | |
| 2069 | /* Send the values from a sum_struct over the socket. Set sum to |
| 2070 | * NULL if there are no checksums to send. This is called by both |
no test coverage detected