summaryrefslogtreecommitdiff
path: root/sftp.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2017-02-15 01:46:47 +0000
committerDamien Miller <djm@mindrot.org>2017-02-17 14:52:24 +1100
commit6d5a41b38b55258213ecfaae9df7a758caa752a1 (patch)
treee5909730dfe9e662cffa2016a694e68e7e45dc7e /sftp.c
parentbd5d7d239525d595ecea92765334af33a45d9d63 (diff)
upstream commit
fix division by zero crash in "df" output when server returns zero total filesystem blocks/inodes. Spotted by Guido Vranken; ok dtucker@ Upstream-ID: 6fb6c2ae6b289aa07b6232dbc0be54682ef5419f
Diffstat (limited to 'sftp.c')
-rw-r--r--sftp.c40
1 files changed, 24 insertions, 16 deletions
diff --git a/sftp.c b/sftp.c
index 2b8fdabfb..76add3908 100644
--- a/sftp.c
+++ b/sftp.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sftp.c,v 1.177 2016/10/18 12:41:22 millert Exp $ */ 1/* $OpenBSD: sftp.c,v 1.178 2017/02/15 01:46:47 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> 3 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
4 * 4 *
@@ -969,23 +969,34 @@ static int
969do_df(struct sftp_conn *conn, const char *path, int hflag, int iflag) 969do_df(struct sftp_conn *conn, const char *path, int hflag, int iflag)
970{ 970{
971 struct sftp_statvfs st; 971 struct sftp_statvfs st;
972 char s_used[FMT_SCALED_STRSIZE]; 972 char s_used[FMT_SCALED_STRSIZE], s_avail[FMT_SCALED_STRSIZE];
973 char s_avail[FMT_SCALED_STRSIZE]; 973 char s_root[FMT_SCALED_STRSIZE], s_total[FMT_SCALED_STRSIZE];
974 char s_root[FMT_SCALED_STRSIZE]; 974 char s_icapacity[16], s_dcapacity[16];
975 char s_total[FMT_SCALED_STRSIZE];
976 unsigned long long ffree;
977 975
978 if (do_statvfs(conn, path, &st, 1) == -1) 976 if (do_statvfs(conn, path, &st, 1) == -1)
979 return -1; 977 return -1;
978 if (st.f_files == 0)
979 strlcpy(s_icapacity, "ERR", sizeof(s_icapacity));
980 else {
981 snprintf(s_icapacity, sizeof(s_icapacity), "%3llu%%",
982 (unsigned long long)(100 * (st.f_files - st.f_ffree) /
983 st.f_files));
984 }
985 if (st.f_blocks == 0)
986 strlcpy(s_dcapacity, "ERR", sizeof(s_dcapacity));
987 else {
988 snprintf(s_dcapacity, sizeof(s_dcapacity), "%3llu%%",
989 (unsigned long long)(100 * (st.f_blocks - st.f_bfree) /
990 st.f_blocks));
991 }
980 if (iflag) { 992 if (iflag) {
981 ffree = st.f_files ? (100 * (st.f_files - st.f_ffree) / st.f_files) : 0;
982 printf(" Inodes Used Avail " 993 printf(" Inodes Used Avail "
983 "(root) %%Capacity\n"); 994 "(root) %%Capacity\n");
984 printf("%11llu %11llu %11llu %11llu %3llu%%\n", 995 printf("%11llu %11llu %11llu %11llu %s\n",
985 (unsigned long long)st.f_files, 996 (unsigned long long)st.f_files,
986 (unsigned long long)(st.f_files - st.f_ffree), 997 (unsigned long long)(st.f_files - st.f_ffree),
987 (unsigned long long)st.f_favail, 998 (unsigned long long)st.f_favail,
988 (unsigned long long)st.f_ffree, ffree); 999 (unsigned long long)st.f_ffree, s_icapacity);
989 } else if (hflag) { 1000 } else if (hflag) {
990 strlcpy(s_used, "error", sizeof(s_used)); 1001 strlcpy(s_used, "error", sizeof(s_used));
991 strlcpy(s_avail, "error", sizeof(s_avail)); 1002 strlcpy(s_avail, "error", sizeof(s_avail));
@@ -996,21 +1007,18 @@ do_df(struct sftp_conn *conn, const char *path, int hflag, int iflag)
996 fmt_scaled(st.f_bfree * st.f_frsize, s_root); 1007 fmt_scaled(st.f_bfree * st.f_frsize, s_root);
997 fmt_scaled(st.f_blocks * st.f_frsize, s_total); 1008 fmt_scaled(st.f_blocks * st.f_frsize, s_total);
998 printf(" Size Used Avail (root) %%Capacity\n"); 1009 printf(" Size Used Avail (root) %%Capacity\n");
999 printf("%7sB %7sB %7sB %7sB %3llu%%\n", 1010 printf("%7sB %7sB %7sB %7sB %s\n",
1000 s_total, s_used, s_avail, s_root, 1011 s_total, s_used, s_avail, s_root, s_dcapacity);
1001 (unsigned long long)(100 * (st.f_blocks - st.f_bfree) /
1002 st.f_blocks));
1003 } else { 1012 } else {
1004 printf(" Size Used Avail " 1013 printf(" Size Used Avail "
1005 "(root) %%Capacity\n"); 1014 "(root) %%Capacity\n");
1006 printf("%12llu %12llu %12llu %12llu %3llu%%\n", 1015 printf("%12llu %12llu %12llu %12llu %s\n",
1007 (unsigned long long)(st.f_frsize * st.f_blocks / 1024), 1016 (unsigned long long)(st.f_frsize * st.f_blocks / 1024),
1008 (unsigned long long)(st.f_frsize * 1017 (unsigned long long)(st.f_frsize *
1009 (st.f_blocks - st.f_bfree) / 1024), 1018 (st.f_blocks - st.f_bfree) / 1024),
1010 (unsigned long long)(st.f_frsize * st.f_bavail / 1024), 1019 (unsigned long long)(st.f_frsize * st.f_bavail / 1024),
1011 (unsigned long long)(st.f_frsize * st.f_bfree / 1024), 1020 (unsigned long long)(st.f_frsize * st.f_bfree / 1024),
1012 (unsigned long long)(100 * (st.f_blocks - st.f_bfree) / 1021 s_dcapacity);
1013 st.f_blocks));
1014 } 1022 }
1015 return 0; 1023 return 0;
1016} 1024}