fix(p6-batch): reject clean EOF on record read; add traversal/EOF security tests

This commit is contained in:
2026-09-10 22:05:18 +02:00
parent c026176bb3
commit fc2d144492
4 changed files with 75 additions and 3 deletions
+1
View File
@@ -46,6 +46,7 @@ void print_usage(void) {
printf(" wire formats)\n");
printf(" --write-batch=FILE Run the normal live transfer AND also emit a\n");
printf(" self-contained batch file of the whole source tree\n");
printf(" (implies the single-threaded transfer path)\n");
printf(" --only-write-batch=FILE\n");
printf(" Emit the batch file only (no destination, no server)\n");
printf(" --read-batch=FILE Apply the batch file to the destination (no source, no\n");
+1 -1
View File
@@ -128,7 +128,7 @@ int batch_read_apply(int fd, const Config* config, const char* dest_root) {
log_message(LOG_LEVEL_ERROR, "batch: could not allocate a %llu-byte record", length);
return -1;
}
if (!read_exact(fd, record, (size_t)length, &eof)) {
if (!read_exact(fd, record, (size_t)length, &eof) || eof) {
log_message(LOG_LEVEL_ERROR, "batch: truncated chunk record");
free(record);
return -1;
+6 -2
View File
@@ -13,8 +13,12 @@
#define BATCH_MAGIC "FSTRESBATCH"
#define BATCH_MAGIC_LEN 11
#define BATCH_FORMAT_VERSION 1
/* A single deserialized record is bounded by the chunk codec's 64 MB cap
* (the same per-file data cap chunk_deserialize enforces). */
/* Max size of a single length-prefixed record (a whole serialized chunk,
* which can span several files). A single source file near the 64 MB wire
* limit plus per-file headers can produce a record slightly over 64 MB, so a
* large file just under the wire cap may be refused by the batch writer; this
* is documented upstream and the failure is clean (the partial batch is
* unlinked), never a truncated/corrupt batch. */
#define BATCH_MAX_RECORD (64ULL * 1024 * 1024)
bool batch_write_header(int fd, const Config* config);