Skip to content

cp: --sparse=always hangs if the source is truncated mid-copy #12648

@sylvestre

Description

@sylvestre

The copy loop in sparse_copy() (src/uu/cp/src/platform/linux.rs) advances only by the bytes read and never handles a zero-byte read:

while current_offset < size {
    let this_read = src_file.read(&mut buf)?;
    ...
    current_offset += this_read;
}

size is captured once from the initial metadata(). If the source shrinks afterwards, read() hits EOF and returns 0 before current_offset reaches size, so the loop spins forever at 100% CPU.

Steps to reproduce

$ truncate -s 2G big
$ ( sleep 0.2; truncate -s 0 big ) &      # shrink the source mid-copy
$ cp --reflink=never --sparse=always big copy
# never returns; cp pins a core. Interrupt with Ctrl-C.

It's a race window, so adjust the sleep / size if it completes; with a larger source it's easy to hit. GNU cp finishes.

Expected

cp stops at EOF instead of looping forever.


Reported by V12 (finding F-65898).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions