Commit 96f991fc authored by Dag Erling Smørgrav's avatar Dag Erling Smørgrav

Try harder to avoid integer overflows in cache file size calculations

on 32-bit platforms.


git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@1794 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 8efc0b19
...@@ -118,7 +118,7 @@ struct smf_sc { ...@@ -118,7 +118,7 @@ struct smf_sc {
static void static void
smf_calcsize(struct smf_sc *sc, const char *size, int newfile) smf_calcsize(struct smf_sc *sc, const char *size, int newfile)
{ {
uintmax_t l; uintmax_t l, fssize;
unsigned bs; unsigned bs;
char suff[2]; char suff[2];
int i, explicit; int i, explicit;
...@@ -127,6 +127,7 @@ smf_calcsize(struct smf_sc *sc, const char *size, int newfile) ...@@ -127,6 +127,7 @@ smf_calcsize(struct smf_sc *sc, const char *size, int newfile)
AN(sc); AN(sc);
AZ(fstat(sc->fd, &st)); AZ(fstat(sc->fd, &st));
xxxassert(S_ISREG(st.st_mode));
#if defined(HAVE_SYS_MOUNT_H) || defined(HAVE_SYS_VFS_H) #if defined(HAVE_SYS_MOUNT_H) || defined(HAVE_SYS_VFS_H)
struct statfs fsst; struct statfs fsst;
...@@ -137,8 +138,9 @@ smf_calcsize(struct smf_sc *sc, const char *size, int newfile) ...@@ -137,8 +138,9 @@ smf_calcsize(struct smf_sc *sc, const char *size, int newfile)
bs = sc->pagesize; bs = sc->pagesize;
if (bs < fsst.f_bsize) if (bs < fsst.f_bsize)
bs = fsst.f_bsize; bs = fsst.f_bsize;
xxxassert(bs % sc->pagesize == 0);
xxxassert(S_ISREG(st.st_mode)); xxxassert(bs % fsst.f_bsize == 0);
fssize = fsst.f_bsize * fsst.f_bavail;
i = sscanf(size, "%ju%1s", &l, suff); /* can return -1, 0, 1 or 2 */ i = sscanf(size, "%ju%1s", &l, suff); /* can return -1, 0, 1 or 2 */
...@@ -179,7 +181,7 @@ smf_calcsize(struct smf_sc *sc, const char *size, int newfile) ...@@ -179,7 +181,7 @@ smf_calcsize(struct smf_sc *sc, const char *size, int newfile)
l *= (uintmax_t)(1024UL * 1024UL) * l *= (uintmax_t)(1024UL * 1024UL) *
(uintmax_t)(1024UL * 1024UL); (uintmax_t)(1024UL * 1024UL);
else if (suff[0] == '%') { else if (suff[0] == '%') {
l *= fsst.f_bsize * fsst.f_bavail; l *= fssize;
l /= 100; l /= 100;
} }
} }
...@@ -200,14 +202,14 @@ smf_calcsize(struct smf_sc *sc, const char *size, int newfile) ...@@ -200,14 +202,14 @@ smf_calcsize(struct smf_sc *sc, const char *size, int newfile)
if (l < st.st_size) { if (l < st.st_size) {
AZ(ftruncate(sc->fd, l)); AZ(ftruncate(sc->fd, l));
} else if (l - st.st_size > fsst.f_bsize * fsst.f_bavail) { } else if (l - st.st_size > fssize) {
l = ((uintmax_t)fsst.f_bsize * fsst.f_bavail * 80) / 100; l = fssize * 80 / 100;
fprintf(stderr, "WARNING: storage file size reduced" fprintf(stderr, "WARNING: storage file size reduced"
" to %ju (80%% of available disk space)\n", l); " to %ju (80%% of available disk space)\n", l);
} }
} }
/* round down to of filesystem blocksize or pagesize */ /* round down to multiple of filesystem blocksize or pagesize */
l -= (l % bs); l -= (l % bs);
if (l < MINPAGES * (uintmax_t)sc->pagesize) { if (l < MINPAGES * (uintmax_t)sc->pagesize) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment