From: claudio Date: Mon, 19 Feb 2024 16:39:18 +0000 (+0000) Subject: Fix a deadlock in openrsync when big files are synced using the hash X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=0e1879aafc8d52781267651a6455236cadaf2b54;p=openbsd Fix a deadlock in openrsync when big files are synced using the hash algorithm. Make sure the sender does not run ahead of itself and end stalling in a read from network that never shows up. Instead ensure that all queued data is pushed out before accepting new data. Problem found by and fix developed with Kyle Evans (kevans freebsd.org) OK tb@ deraadt@ --- diff --git a/usr.bin/rsync/sender.c b/usr.bin/rsync/sender.c index e2999aa2589..8e49f4d0e72 100644 --- a/usr.bin/rsync/sender.c +++ b/usr.bin/rsync/sender.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sender.c,v 1.30 2021/08/29 13:43:46 claudio Exp $ */ +/* $OpenBSD: sender.c,v 1.31 2024/02/19 16:39:18 claudio Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons * @@ -432,7 +432,7 @@ rsync_sender(struct sess *sess, int fdin, * poll events on demand. */ - pfd[0].fd = fdin; /* from receiver */ + pfd[0].fd = -1; /* from receiver */ pfd[0].events = POLLIN; pfd[1].fd = -1; /* to receiver */ pfd[1].events = POLLOUT; @@ -440,7 +440,11 @@ rsync_sender(struct sess *sess, int fdin, pfd[2].events = POLLIN; for (;;) { - assert(pfd[0].fd != -1); + /* disable recevier until all buffered data was sent */ + if (pfd[1].fd != -1 && wbufsz > 0) + pfd[0].fd = -1; + else + pfd[0].fd = fdin; if ((c = poll(pfd, 3, poll_timeout)) == -1) { ERR("poll"); goto out;