From 0e1879aafc8d52781267651a6455236cadaf2b54 Mon Sep 17 00:00:00 2001 From: claudio Date: Mon, 19 Feb 2024 16:39:18 +0000 Subject: [PATCH] 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@ --- usr.bin/rsync/sender.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) 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; -- 2.20.1