aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhillip Lougher <phillip@lougher.demon.co.uk>2009-03-11 23:23:48 -0400
committerPhillip Lougher <phillip@lougher.demon.co.uk>2009-03-11 23:23:48 -0400
commit363911d027d1de1c6df79eb3f487f5476b9619f4 (patch)
tree6aa93b837f9719b0f51c11330f56288bc5acf51b
parentebdcc81c71937b30e09110c02a1e8a21fa770b6f (diff)
Squashfs: Valid filesystems are flagged as bad by the corrupted fs patch
The corrupted filesystem patch added a check against zlib trying to output too much data in the presence of data corruption. This check triggered if zlib_inflate asked to be called again (Z_OK) with avail_out == 0 and no more output buffers available. This check proves to be rather dumb, as it incorrectly catches the case where zlib has generated all the output, but there are still input bytes to be processed. This patch does a number of things. It removes the original check and replaces it with code to not move to the next output buffer if there are no more output buffers available, relying on zlib to error if it wants an extra output buffer in the case of data corruption. It also replaces the Z_NO_FLUSH flag with the more correct Z_SYNC_FLUSH flag, and makes the error messages more understandable to non-technical users. Signed-off-by: Phillip Lougher <phillip@lougher.demon.co.uk> Reported-by: Stefan Lippers-Hollmann <s.L-H@gmx.de>
-rw-r--r--fs/squashfs/block.c21
1 files changed, 4 insertions, 17 deletions
diff --git a/fs/squashfs/block.c b/fs/squashfs/block.c
index 321728f48f2d..2a7960310349 100644
--- a/fs/squashfs/block.c
+++ b/fs/squashfs/block.c
@@ -184,15 +184,7 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index,
184 offset = 0; 184 offset = 0;
185 } 185 }
186 186
187 if (msblk->stream.avail_out == 0) { 187 if (msblk->stream.avail_out == 0 && page < pages) {
188 if (page == pages) {
189 ERROR("zlib_inflate tried to "
190 "decompress too much data, "
191 "expected %d bytes. Zlib "
192 "data probably corrupt\n",
193 srclength);
194 goto release_mutex;
195 }
196 msblk->stream.next_out = buffer[page++]; 188 msblk->stream.next_out = buffer[page++];
197 msblk->stream.avail_out = PAGE_CACHE_SIZE; 189 msblk->stream.avail_out = PAGE_CACHE_SIZE;
198 } 190 }
@@ -209,25 +201,20 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index,
209 zlib_init = 1; 201 zlib_init = 1;
210 } 202 }
211 203
212 zlib_err = zlib_inflate(&msblk->stream, Z_NO_FLUSH); 204 zlib_err = zlib_inflate(&msblk->stream, Z_SYNC_FLUSH);
213 205
214 if (msblk->stream.avail_in == 0 && k < b) 206 if (msblk->stream.avail_in == 0 && k < b)
215 put_bh(bh[k++]); 207 put_bh(bh[k++]);
216 } while (zlib_err == Z_OK); 208 } while (zlib_err == Z_OK);
217 209
218 if (zlib_err != Z_STREAM_END) { 210 if (zlib_err != Z_STREAM_END) {
219 ERROR("zlib_inflate returned unexpected result" 211 ERROR("zlib_inflate error, data probably corrupt\n");
220 " 0x%x, srclength %d, avail_in %d,"
221 " avail_out %d\n", zlib_err, srclength,
222 msblk->stream.avail_in,
223 msblk->stream.avail_out);
224 goto release_mutex; 212 goto release_mutex;
225 } 213 }
226 214
227 zlib_err = zlib_inflateEnd(&msblk->stream); 215 zlib_err = zlib_inflateEnd(&msblk->stream);
228 if (zlib_err != Z_OK) { 216 if (zlib_err != Z_OK) {
229 ERROR("zlib_inflateEnd returned unexpected result 0x%x," 217 ERROR("zlib_inflate error, data probably corrupt\n");
230 " srclength %d\n", zlib_err, srclength);
231 goto release_mutex; 218 goto release_mutex;
232 } 219 }
233 length = msblk->stream.total_out; 220 length = msblk->stream.total_out;