@@ -92,36 +92,6 @@ static void ext4_idx_store_pblock(struct ext4_extent_idx *ix, ext4_fsblk_t pb)
92
92
ix -> ei_leaf_hi = cpu_to_le16 ((unsigned long ) ((pb >> 31 ) >> 1 ) & 0xffff );
93
93
}
94
94
95
- static int ext4_ext_check_header (const char * function , struct inode * inode ,
96
- struct ext4_extent_header * eh )
97
- {
98
- const char * error_msg = NULL ;
99
-
100
- if (unlikely (eh -> eh_magic != EXT4_EXT_MAGIC )) {
101
- error_msg = "invalid magic" ;
102
- goto corrupted ;
103
- }
104
- if (unlikely (eh -> eh_max == 0 )) {
105
- error_msg = "invalid eh_max" ;
106
- goto corrupted ;
107
- }
108
- if (unlikely (le16_to_cpu (eh -> eh_entries ) > le16_to_cpu (eh -> eh_max ))) {
109
- error_msg = "invalid eh_entries" ;
110
- goto corrupted ;
111
- }
112
- return 0 ;
113
-
114
- corrupted :
115
- ext4_error (inode -> i_sb , function ,
116
- "bad header in inode #%lu: %s - magic %x, "
117
- "entries %u, max %u, depth %u" ,
118
- inode -> i_ino , error_msg , le16_to_cpu (eh -> eh_magic ),
119
- le16_to_cpu (eh -> eh_entries ), le16_to_cpu (eh -> eh_max ),
120
- le16_to_cpu (eh -> eh_depth ));
121
-
122
- return - EIO ;
123
- }
124
-
125
95
static handle_t * ext4_ext_journal_restart (handle_t * handle , int needed )
126
96
{
127
97
int err ;
@@ -270,6 +240,70 @@ static int ext4_ext_space_root_idx(struct inode *inode)
270
240
return size ;
271
241
}
272
242
243
+ static int
244
+ ext4_ext_max_entries (struct inode * inode , int depth )
245
+ {
246
+ int max ;
247
+
248
+ if (depth == ext_depth (inode )) {
249
+ if (depth == 0 )
250
+ max = ext4_ext_space_root (inode );
251
+ else
252
+ max = ext4_ext_space_root_idx (inode );
253
+ } else {
254
+ if (depth == 0 )
255
+ max = ext4_ext_space_block (inode );
256
+ else
257
+ max = ext4_ext_space_block_idx (inode );
258
+ }
259
+
260
+ return max ;
261
+ }
262
+
263
+ static int __ext4_ext_check_header (const char * function , struct inode * inode ,
264
+ struct ext4_extent_header * eh ,
265
+ int depth )
266
+ {
267
+ const char * error_msg ;
268
+ int max = 0 ;
269
+
270
+ if (unlikely (eh -> eh_magic != EXT4_EXT_MAGIC )) {
271
+ error_msg = "invalid magic" ;
272
+ goto corrupted ;
273
+ }
274
+ if (unlikely (le16_to_cpu (eh -> eh_depth ) != depth )) {
275
+ error_msg = "unexpected eh_depth" ;
276
+ goto corrupted ;
277
+ }
278
+ if (unlikely (eh -> eh_max == 0 )) {
279
+ error_msg = "invalid eh_max" ;
280
+ goto corrupted ;
281
+ }
282
+ max = ext4_ext_max_entries (inode , depth );
283
+ if (unlikely (le16_to_cpu (eh -> eh_max ) > max )) {
284
+ error_msg = "too large eh_max" ;
285
+ goto corrupted ;
286
+ }
287
+ if (unlikely (le16_to_cpu (eh -> eh_entries ) > le16_to_cpu (eh -> eh_max ))) {
288
+ error_msg = "invalid eh_entries" ;
289
+ goto corrupted ;
290
+ }
291
+ return 0 ;
292
+
293
+ corrupted :
294
+ ext4_error (inode -> i_sb , function ,
295
+ "bad header in inode #%lu: %s - magic %x, "
296
+ "entries %u, max %u(%u), depth %u(%u)" ,
297
+ inode -> i_ino , error_msg , le16_to_cpu (eh -> eh_magic ),
298
+ le16_to_cpu (eh -> eh_entries ), le16_to_cpu (eh -> eh_max ),
299
+ max , le16_to_cpu (eh -> eh_depth ), depth );
300
+
301
+ return - EIO ;
302
+ }
303
+
304
+ #define ext4_ext_check_header (inode , eh , depth ) \
305
+ __ext4_ext_check_header(__FUNCTION__, inode, eh, depth)
306
+
273
307
#ifdef EXT_DEBUG
274
308
static void ext4_ext_show_path (struct inode * inode , struct ext4_ext_path * path )
275
309
{
@@ -330,16 +364,14 @@ static void ext4_ext_drop_refs(struct ext4_ext_path *path)
330
364
/*
331
365
* ext4_ext_binsearch_idx:
332
366
* binary search for the closest index of the given block
367
+ * the header must be checked before calling this
333
368
*/
334
369
static void
335
370
ext4_ext_binsearch_idx (struct inode * inode , struct ext4_ext_path * path , int block )
336
371
{
337
372
struct ext4_extent_header * eh = path -> p_hdr ;
338
373
struct ext4_extent_idx * r , * l , * m ;
339
374
340
- BUG_ON (eh -> eh_magic != EXT4_EXT_MAGIC );
341
- BUG_ON (le16_to_cpu (eh -> eh_entries ) > le16_to_cpu (eh -> eh_max ));
342
- BUG_ON (le16_to_cpu (eh -> eh_entries ) <= 0 );
343
375
344
376
ext_debug ("binsearch for %d(idx): " , block );
345
377
@@ -389,16 +421,14 @@ ext4_ext_binsearch_idx(struct inode *inode, struct ext4_ext_path *path, int bloc
389
421
/*
390
422
* ext4_ext_binsearch:
391
423
* binary search for closest extent of the given block
424
+ * the header must be checked before calling this
392
425
*/
393
426
static void
394
427
ext4_ext_binsearch (struct inode * inode , struct ext4_ext_path * path , int block )
395
428
{
396
429
struct ext4_extent_header * eh = path -> p_hdr ;
397
430
struct ext4_extent * r , * l , * m ;
398
431
399
- BUG_ON (eh -> eh_magic != EXT4_EXT_MAGIC );
400
- BUG_ON (le16_to_cpu (eh -> eh_entries ) > le16_to_cpu (eh -> eh_max ));
401
-
402
432
if (eh -> eh_entries == 0 ) {
403
433
/*
404
434
* this leaf is empty:
@@ -469,11 +499,10 @@ ext4_ext_find_extent(struct inode *inode, int block, struct ext4_ext_path *path)
469
499
short int depth , i , ppos = 0 , alloc = 0 ;
470
500
471
501
eh = ext_inode_hdr (inode );
472
- BUG_ON ( eh == NULL );
473
- if (ext4_ext_check_header (__FUNCTION__ , inode , eh ))
502
+ depth = ext_depth ( inode );
503
+ if (ext4_ext_check_header (inode , eh , depth ))
474
504
return ERR_PTR (- EIO );
475
505
476
- i = depth = ext_depth (inode );
477
506
478
507
/* account possible depth increase */
479
508
if (!path ) {
@@ -485,10 +514,12 @@ ext4_ext_find_extent(struct inode *inode, int block, struct ext4_ext_path *path)
485
514
}
486
515
path [0 ].p_hdr = eh ;
487
516
517
+ i = depth ;
488
518
/* walk through the tree */
489
519
while (i ) {
490
520
ext_debug ("depth %d: num %d, max %d\n" ,
491
521
ppos , le16_to_cpu (eh -> eh_entries ), le16_to_cpu (eh -> eh_max ));
522
+
492
523
ext4_ext_binsearch_idx (inode , path + ppos , block );
493
524
path [ppos ].p_block = idx_pblock (path [ppos ].p_idx );
494
525
path [ppos ].p_depth = i ;
@@ -505,7 +536,7 @@ ext4_ext_find_extent(struct inode *inode, int block, struct ext4_ext_path *path)
505
536
path [ppos ].p_hdr = eh ;
506
537
i -- ;
507
538
508
- if (ext4_ext_check_header (__FUNCTION__ , inode , eh ))
539
+ if (ext4_ext_check_header (inode , eh , i ))
509
540
goto err ;
510
541
}
511
542
@@ -514,9 +545,6 @@ ext4_ext_find_extent(struct inode *inode, int block, struct ext4_ext_path *path)
514
545
path [ppos ].p_ext = NULL ;
515
546
path [ppos ].p_idx = NULL ;
516
547
517
- if (ext4_ext_check_header (__FUNCTION__ , inode , eh ))
518
- goto err ;
519
-
520
548
/* find extent */
521
549
ext4_ext_binsearch (inode , path + ppos , block );
522
550
@@ -1738,13 +1766,12 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
1738
1766
unsigned uninitialized = 0 ;
1739
1767
struct ext4_extent * ex ;
1740
1768
1769
+ /* the header must be checked already in ext4_ext_remove_space() */
1741
1770
ext_debug ("truncate since %lu in leaf\n" , start );
1742
1771
if (!path [depth ].p_hdr )
1743
1772
path [depth ].p_hdr = ext_block_hdr (path [depth ].p_bh );
1744
1773
eh = path [depth ].p_hdr ;
1745
1774
BUG_ON (eh == NULL );
1746
- BUG_ON (le16_to_cpu (eh -> eh_entries ) > le16_to_cpu (eh -> eh_max ));
1747
- BUG_ON (eh -> eh_magic != EXT4_EXT_MAGIC );
1748
1775
1749
1776
/* find where to start removing */
1750
1777
ex = EXT_LAST_EXTENT (eh );
@@ -1898,7 +1925,7 @@ int ext4_ext_remove_space(struct inode *inode, unsigned long start)
1898
1925
return - ENOMEM ;
1899
1926
}
1900
1927
path [0 ].p_hdr = ext_inode_hdr (inode );
1901
- if (ext4_ext_check_header (__FUNCTION__ , inode , path [0 ].p_hdr )) {
1928
+ if (ext4_ext_check_header (inode , path [0 ].p_hdr , depth )) {
1902
1929
err = - EIO ;
1903
1930
goto out ;
1904
1931
}
@@ -1919,17 +1946,8 @@ int ext4_ext_remove_space(struct inode *inode, unsigned long start)
1919
1946
if (!path [i ].p_hdr ) {
1920
1947
ext_debug ("initialize header\n" );
1921
1948
path [i ].p_hdr = ext_block_hdr (path [i ].p_bh );
1922
- if (ext4_ext_check_header (__FUNCTION__ , inode ,
1923
- path [i ].p_hdr )) {
1924
- err = - EIO ;
1925
- goto out ;
1926
- }
1927
1949
}
1928
1950
1929
- BUG_ON (le16_to_cpu (path [i ].p_hdr -> eh_entries )
1930
- > le16_to_cpu (path [i ].p_hdr -> eh_max ));
1931
- BUG_ON (path [i ].p_hdr -> eh_magic != EXT4_EXT_MAGIC );
1932
-
1933
1951
if (!path [i ].p_idx ) {
1934
1952
/* this level hasn't been touched yet */
1935
1953
path [i ].p_idx = EXT_LAST_INDEX (path [i ].p_hdr );
@@ -1946,17 +1964,27 @@ int ext4_ext_remove_space(struct inode *inode, unsigned long start)
1946
1964
i , EXT_FIRST_INDEX (path [i ].p_hdr ),
1947
1965
path [i ].p_idx );
1948
1966
if (ext4_ext_more_to_rm (path + i )) {
1967
+ struct buffer_head * bh ;
1949
1968
/* go to the next level */
1950
1969
ext_debug ("move to level %d (block %llu)\n" ,
1951
1970
i + 1 , idx_pblock (path [i ].p_idx ));
1952
1971
memset (path + i + 1 , 0 , sizeof (* path ));
1953
- path [i + 1 ].p_bh =
1954
- sb_bread (sb , idx_pblock (path [i ].p_idx ));
1955
- if (!path [i + 1 ].p_bh ) {
1972
+ bh = sb_bread (sb , idx_pblock (path [i ].p_idx ));
1973
+ if (!bh ) {
1956
1974
/* should we reset i_size? */
1957
1975
err = - EIO ;
1958
1976
break ;
1959
1977
}
1978
+ if (WARN_ON (i + 1 > depth )) {
1979
+ err = - EIO ;
1980
+ break ;
1981
+ }
1982
+ if (ext4_ext_check_header (inode , ext_block_hdr (bh ),
1983
+ depth - i - 1 )) {
1984
+ err = - EIO ;
1985
+ break ;
1986
+ }
1987
+ path [i + 1 ].p_bh = bh ;
1960
1988
1961
1989
/* save actual number of indexes since this
1962
1990
* number is changed at the next iteration */
0 commit comments