Skip to content

Commit

Permalink
upstream: Sanitize scp filenames via snmprintf. To do this we move
Browse files Browse the repository at this point in the history
the progressmeter formatting outside of signal handler context and have the
atomicio callback called for EINTR too.  bz#2434 with contributions from djm
and jjelen at redhat.com, ok djm@

OpenBSD-Commit-ID: 1af61c1f70e4f3bd8ab140b9f1fa699481db57d8
  • Loading branch information
daztucker committed Jan 24, 2019
1 parent 6249451 commit 8976f1c
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 44 deletions.
20 changes: 15 additions & 5 deletions atomicio.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: atomicio.c,v 1.28 2016/07/27 23:18:12 djm Exp $ */
/* $OpenBSD: atomicio.c,v 1.29 2019/01/23 08:01:46 dtucker Exp $ */
/*
* Copyright (c) 2006 Damien Miller. All rights reserved.
* Copyright (c) 2005 Anil Madhavapeddy. All rights reserved.
Expand Down Expand Up @@ -67,9 +67,14 @@ atomicio6(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n,
res = (f) (fd, s + pos, n - pos);
switch (res) {
case -1:
if (errno == EINTR)
if (errno == EINTR) {
/* possible SIGALARM, update callback */
if (cb != NULL && cb(cb_arg, 0) == -1) {
errno = EINTR;
return pos;
}
continue;
if (errno == EAGAIN || errno == EWOULDBLOCK) {
} else if (errno == EAGAIN || errno == EWOULDBLOCK) {
(void)poll(&pfd, 1, -1);
continue;
}
Expand Down Expand Up @@ -124,9 +129,14 @@ atomiciov6(ssize_t (*f) (int, const struct iovec *, int), int fd,
res = (f) (fd, iov, iovcnt);
switch (res) {
case -1:
if (errno == EINTR)
if (errno == EINTR) {
/* possible SIGALARM, update callback */
if (cb != NULL && cb(cb_arg, 0) == -1) {
errno = EINTR;
return pos;
}
continue;
if (errno == EAGAIN || errno == EWOULDBLOCK) {
} else if (errno == EAGAIN || errno == EWOULDBLOCK) {
(void)poll(&pfd, 1, -1);
continue;
}
Expand Down
53 changes: 24 additions & 29 deletions progressmeter.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: progressmeter.c,v 1.45 2016/06/30 05:17:05 dtucker Exp $ */
/* $OpenBSD: progressmeter.c,v 1.46 2019/01/23 08:01:46 dtucker Exp $ */
/*
* Copyright (c) 2003 Nils Nordman. All rights reserved.
*
Expand Down Expand Up @@ -31,6 +31,7 @@

#include <errno.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
Expand All @@ -39,6 +40,7 @@
#include "progressmeter.h"
#include "atomicio.h"
#include "misc.h"
#include "utf8.h"

#define DEFAULT_WINSIZE 80
#define MAX_WINSIZE 512
Expand All @@ -61,7 +63,7 @@ static void setscreensize(void);
void refresh_progress_meter(void);

/* signal handler for updating the progress meter */
static void update_progress_meter(int);
static void sig_alarm(int);

static double start; /* start progress */
static double last_update; /* last progress update */
Expand All @@ -74,6 +76,7 @@ static long stalled; /* how long we have been stalled */
static int bytes_per_second; /* current speed in bytes per second */
static int win_size; /* terminal window size */
static volatile sig_atomic_t win_resized; /* for window resizing */
static volatile sig_atomic_t alarm_fired;

/* units for format_size */
static const char unit[] = " KMGT";
Expand Down Expand Up @@ -126,9 +129,17 @@ refresh_progress_meter(void)
off_t bytes_left;
int cur_speed;
int hours, minutes, seconds;
int i, len;
int file_len;

if ((!alarm_fired && !win_resized) || !can_output())
return;
alarm_fired = 0;

if (win_resized) {
setscreensize();
win_resized = 0;
}

transferred = *counter - (cur_pos ? cur_pos : start_pos);
cur_pos = *counter;
now = monotime_double();
Expand Down Expand Up @@ -158,16 +169,11 @@ refresh_progress_meter(void)

/* filename */
buf[0] = '\0';
file_len = win_size - 35;
file_len = win_size - 36;
if (file_len > 0) {
len = snprintf(buf, file_len + 1, "\r%s", file);
if (len < 0)
len = 0;
if (len >= file_len + 1)
len = file_len;
for (i = len; i < file_len; i++)
buf[i] = ' ';
buf[file_len] = '\0';
buf[0] = '\r';
snmprintf(buf+1, sizeof(buf)-1 , &file_len, "%*s",
file_len * -1, file);
}

/* percent of transfer done */
Expand Down Expand Up @@ -228,22 +234,11 @@ refresh_progress_meter(void)

/*ARGSUSED*/
static void
update_progress_meter(int ignore)
sig_alarm(int ignore)
{
int save_errno;

save_errno = errno;

if (win_resized) {
setscreensize();
win_resized = 0;
}
if (can_output())
refresh_progress_meter();

signal(SIGALRM, update_progress_meter);
signal(SIGALRM, sig_alarm);
alarm_fired = 1;
alarm(UPDATE_INTERVAL);
errno = save_errno;
}

void
Expand All @@ -259,10 +254,9 @@ start_progress_meter(const char *f, off_t filesize, off_t *ctr)
bytes_per_second = 0;

setscreensize();
if (can_output())
refresh_progress_meter();
refresh_progress_meter();

signal(SIGALRM, update_progress_meter);
signal(SIGALRM, sig_alarm);
signal(SIGWINCH, sig_winch);
alarm(UPDATE_INTERVAL);
}
Expand All @@ -286,6 +280,7 @@ stop_progress_meter(void)
static void
sig_winch(int sig)
{
signal(SIGWINCH, sig_winch);
win_resized = 1;
}

Expand Down
3 changes: 2 additions & 1 deletion progressmeter.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: progressmeter.h,v 1.3 2015/01/14 13:54:13 djm Exp $ */
/* $OpenBSD: progressmeter.h,v 1.4 2019/01/23 08:01:46 dtucker Exp $ */
/*
* Copyright (c) 2002 Nils Nordman. All rights reserved.
*
Expand All @@ -24,4 +24,5 @@
*/

void start_progress_meter(const char *, off_t, off_t *);
void refresh_progress_meter(void);
void stop_progress_meter(void);
3 changes: 2 additions & 1 deletion scp.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: scp.c,v 1.199 2019/01/21 22:50:42 tb Exp $ */
/* $OpenBSD: scp.c,v 1.200 2019/01/23 08:01:46 dtucker Exp $ */
/*
* scp - secure remote copy. This is basically patched BSD rcp which
* uses ssh to do the data transfer (instead of using rcmd).
Expand Down Expand Up @@ -588,6 +588,7 @@ scpio(void *_cnt, size_t s)
off_t *cnt = (off_t *)_cnt;

*cnt += s;
refresh_progress_meter();
if (limit_kbps > 0)
bandwidth_limit(&bwlimit, s);
return 0;
Expand Down
18 changes: 10 additions & 8 deletions sftp-client.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: sftp-client.c,v 1.131 2019/01/16 23:23:45 djm Exp $ */
/* $OpenBSD: sftp-client.c,v 1.132 2019/01/23 08:01:46 dtucker Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
Expand Down Expand Up @@ -102,7 +102,9 @@ sftpio(void *_bwlimit, size_t amount)
{
struct bwlimit *bwlimit = (struct bwlimit *)_bwlimit;

bandwidth_limit(bwlimit, amount);
refresh_progress_meter();
if (bwlimit != NULL)
bandwidth_limit(bwlimit, amount);
return 0;
}

Expand All @@ -122,8 +124,8 @@ send_msg(struct sftp_conn *conn, struct sshbuf *m)
iov[1].iov_base = (u_char *)sshbuf_ptr(m);
iov[1].iov_len = sshbuf_len(m);

if (atomiciov6(writev, conn->fd_out, iov, 2,
conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_out) !=
if (atomiciov6(writev, conn->fd_out, iov, 2, sftpio,
conn->limit_kbps > 0 ? &conn->bwlimit_out : NULL) !=
sshbuf_len(m) + sizeof(mlen))
fatal("Couldn't send packet: %s", strerror(errno));

Expand All @@ -139,8 +141,8 @@ get_msg_extended(struct sftp_conn *conn, struct sshbuf *m, int initial)

if ((r = sshbuf_reserve(m, 4, &p)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
if (atomicio6(read, conn->fd_in, p, 4,
conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_in) != 4) {
if (atomicio6(read, conn->fd_in, p, 4, sftpio,
conn->limit_kbps > 0 ? &conn->bwlimit_in : NULL) != 4) {
if (errno == EPIPE || errno == ECONNRESET)
fatal("Connection closed");
else
Expand All @@ -158,8 +160,8 @@ get_msg_extended(struct sftp_conn *conn, struct sshbuf *m, int initial)

if ((r = sshbuf_reserve(m, msg_len, &p)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
if (atomicio6(read, conn->fd_in, p, msg_len,
conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_in)
if (atomicio6(read, conn->fd_in, p, msg_len, sftpio,
conn->limit_kbps > 0 ? &conn->bwlimit_in : NULL)
!= msg_len) {
if (errno == EPIPE)
fatal("Connection closed");
Expand Down

0 comments on commit 8976f1c

Please sign in to comment.