From b3383c7423aad2daf9ddbd2c1280a6a7795484b7 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Sun, 25 Jun 2017 11:13:00 +0200 Subject: [PATCH] client: Delay additional input processing until after send We need to copy input to @auxfp to implement command line option -2, and pass it to save_input() to enable protection against a rogue server exploiting redirection and execute. We currently do this right when input enters the ring buffer, in recv_input(). Calling save_input() before sending input to the server is sloppy: it can make the client accept "future" redirections and executes. Delay save_input() until after input is sent. For simplicity, delay copying to @auxfp as well. This is actually pretty close to how things worked before commit 8b7d0b9 (v4.3.11). Signed-off-by: Markus Armbruster --- src/client/play.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/client/play.c b/src/client/play.c index 2e074233..210ff733 100644 --- a/src/client/play.c +++ b/src/client/play.c @@ -421,7 +421,7 @@ recv_output(int sock) static int recv_input(int fd, struct ring *inbuf) { - int n, i, ch; + int n; int res = 1; n = ring_from_file(inbuf, fd); @@ -435,16 +435,6 @@ recv_input(int fd, struct ring *inbuf) res = 0; } - /* copy input to AUXFP etc. */ - for (i = -n; i < 0; i++) { - ch = ring_peek(inbuf, i); - assert(ch != EOF); - if (ch != '\r') - save_input(ch); - if (auxfp) - putc(ch, auxfp); - } - return res; } @@ -452,14 +442,24 @@ static int send_input(int fd, struct ring *inbuf) { struct iovec iov[2]; - int cnt; + int cnt, i, ch; ssize_t res; cnt = ring_to_iovec(inbuf, iov); res = writev(fd, iov, cnt); if (res < 0) return res; - ring_discard(inbuf, res); + + /* Copy input to @auxfp etc. */ + for (i = 0; i < res; i++) { + ch = ring_getc(inbuf); + assert(ch != EOF); + if (ch != '\r') + save_input(ch); + if (auxfp) + putc(ch, auxfp); + } + return res; }