Index: lighttpd-1.4.x/src/mod_compress.c =================================================================== --- lighttpd-1.4.x/src/mod_compress.c (revision 2364) +++ lighttpd-1.4.x/src/mod_compress.c (working copy) @@ -410,6 +410,7 @@ void *start; const char *filename = fn->ptr; ssize_t r; + struct stat sb; /* overflow */ if ((off_t)(sce->st.st_size * 1.1) < sce->st.st_size) return -1; @@ -485,8 +486,24 @@ return -1; } + if (-1 == fstat(ifd, &sb)) { + log_error_write(srv, __FILE__, __LINE__, "sbss", "fstat of plain-file", fn, "failed", strerror(errno)); + close(ofd); + close(ifd); - if (MAP_FAILED == (start = mmap(NULL, sce->st.st_size, PROT_READ, MAP_SHARED, ifd, 0))) { + return -1; + } + + if (sb.st_ino != sce->st.st_ino || sb.st_dev != sce->st.st_dev || sb.st_mode != sce->st.st_mode || sb.st_size != sce->st.st_size) { + /* File changed */ + + close(ofd); + close(ifd); + return -1; + } + + + if (MAP_FAILED == (start = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, ifd, 0))) { log_error_write(srv, __FILE__, __LINE__, "sbss", "mmaping", fn, "failed", strerror(errno)); close(ofd); @@ -503,15 +520,15 @@ switch(type) { #ifdef USE_ZLIB case HTTP_ACCEPT_ENCODING_GZIP: - ret = deflate_file_to_buffer_gzip(srv, con, p, start, sce->st.st_size, sce->st.st_mtime); + ret = deflate_file_to_buffer_gzip(srv, con, p, start, sb.st_size, sb.st_mtime); break; case HTTP_ACCEPT_ENCODING_DEFLATE: - ret = deflate_file_to_buffer_deflate(srv, con, p, start, sce->st.st_size); + ret = deflate_file_to_buffer_deflate(srv, con, p, start, sb.st_size); break; #endif #ifdef USE_BZ2LIB case HTTP_ACCEPT_ENCODING_BZIP2: - ret = deflate_file_to_buffer_bzip2(srv, con, p, start, sce->st.st_size); + ret = deflate_file_to_buffer_bzip2(srv, con, p, start, sb.st_size); break; #endif default: @@ -530,7 +547,7 @@ } } - munmap(start, sce->st.st_size); + munmap(start, sb.st_size); close(ofd); close(ifd); @@ -553,6 +570,7 @@ int ret = -1; void *start; buffer *b; + struct stat sb; /* overflow */ if ((off_t)(sce->st.st_size * 1.1) < sce->st.st_size) return -1; @@ -571,8 +589,21 @@ return -1; } + if (-1 == fstat(ifd, &sb)) { + log_error_write(srv, __FILE__, __LINE__, "sbss", "fstat of plain-file", fn, "failed", strerror(errno)); + close(ifd); - if (MAP_FAILED == (start = mmap(NULL, sce->st.st_size, PROT_READ, MAP_SHARED, ifd, 0))) { + return -1; + } + + if (sb.st_ino != sce->st.st_ino || sb.st_dev != sce->st.st_dev || sb.st_mode != sce->st.st_mode || sb.st_size != sce->st.st_size) { + /* File changed */ + + close(ifd); + return -1; + } + + if (MAP_FAILED == (start = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, ifd, 0))) { log_error_write(srv, __FILE__, __LINE__, "sbss", "mmaping", fn, "failed", strerror(errno)); close(ifd); @@ -582,15 +613,15 @@ switch(type) { #ifdef USE_ZLIB case HTTP_ACCEPT_ENCODING_GZIP: - ret = deflate_file_to_buffer_gzip(srv, con, p, start, sce->st.st_size, sce->st.st_mtime); + ret = deflate_file_to_buffer_gzip(srv, con, p, start, sb.st_size, sb.st_mtime); break; case HTTP_ACCEPT_ENCODING_DEFLATE: - ret = deflate_file_to_buffer_deflate(srv, con, p, start, sce->st.st_size); + ret = deflate_file_to_buffer_deflate(srv, con, p, start, sb.st_size); break; #endif #ifdef USE_BZ2LIB case HTTP_ACCEPT_ENCODING_BZIP2: - ret = deflate_file_to_buffer_bzip2(srv, con, p, start, sce->st.st_size); + ret = deflate_file_to_buffer_bzip2(srv, con, p, start, sb.st_size); break; #endif default: @@ -598,7 +629,7 @@ break; } - munmap(start, sce->st.st_size); + munmap(start, sb.st_size); close(ifd); if (ret != 0) return -1;