diff options
author | djm@openbsd.org <djm@openbsd.org> | 2017-02-15 01:46:47 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2017-02-17 14:52:24 +1100 |
commit | 6d5a41b38b55258213ecfaae9df7a758caa752a1 (patch) | |
tree | e5909730dfe9e662cffa2016a694e68e7e45dc7e /sftp.c | |
parent | bd5d7d239525d595ecea92765334af33a45d9d63 (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.c | 40 |
1 files changed, 24 insertions, 16 deletions
@@ -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 | |||
969 | do_df(struct sftp_conn *conn, const char *path, int hflag, int iflag) | 969 | do_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 | } |