v2.5.5: logging failure triggers infinite loop and core dump

Niel Markwick nielm at bigfoot.com
Wed Nov 20 12:48:00 EST 2002

(problem encountered on Tru64Unix v4.0f with rsync 2.5.5)

A failure to write to stdout or stderr in rwrite (log.c:279) will
trigger an endless loop as follows:

0 rprintf calls rwrite
1    rwrite calls fwrite
2        fwrite fails 
3    rwrite calls _exit_cleanup
4        _exit_cleanup calls log_exit
5             log_exit calls rprintf
6                rprintf calls rwrite
7                    rwrite calls fwrite
8                        fwrite fails (unknown errno)
9                    rwrite calls _exit_cleanup

continue from 4-9 ad infinitum until stack overflow and core dump. In
my case, this was after 1573 calls to _exit_cleanup!

This is actually noted in rwrite.c:220
        /* recursion can happen with certain fatal conditions */

Fwrite actually failed because the terminal where rsync was running
had been closed, so stdout and stderr couldn't not be written
to. (SIGHUP had been ignored by the parent shell).

However, This can be reproduced easily by piping the output of rsync
to more:
    rsync -v src dst 2>&1 | more 
and hitting CTRL-C immediately after starting this command -- more is
killed, and rsync's stdout and stderr are invalid, so when rsync tries
to log 'received SIGINT', it goes into the endless loop.

A similar problem has been reported by Jonathan Kamens in May:
His patch also fixes this problem:

> modify rwrite so that it doesn't actually try to write the error 
> if the FILE to which the error has been written is showing a true
> error condition (checked with ferror)"

Niel Markwick

More information about the rsync mailing list