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 <armbru@pond.sub.org>
This commit is contained in:
Markus Armbruster 2017-06-25 11:13:00 +02:00
parent 26372eb85d
commit b3383c7423

View file

@ -421,7 +421,7 @@ recv_output(int sock)
static int static int
recv_input(int fd, struct ring *inbuf) recv_input(int fd, struct ring *inbuf)
{ {
int n, i, ch; int n;
int res = 1; int res = 1;
n = ring_from_file(inbuf, fd); n = ring_from_file(inbuf, fd);
@ -435,16 +435,6 @@ recv_input(int fd, struct ring *inbuf)
res = 0; 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; return res;
} }
@ -452,14 +442,24 @@ static int
send_input(int fd, struct ring *inbuf) send_input(int fd, struct ring *inbuf)
{ {
struct iovec iov[2]; struct iovec iov[2];
int cnt; int cnt, i, ch;
ssize_t res; ssize_t res;
cnt = ring_to_iovec(inbuf, iov); cnt = ring_to_iovec(inbuf, iov);
res = writev(fd, iov, cnt); res = writev(fd, iov, cnt);
if (res < 0) if (res < 0)
return res; 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; return res;
} }