@@ -276,18 +276,22 @@ __xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header,
276
276
__xattr_check_inode((inode), (header), (end), __func__, __LINE__)
277
277
278
278
static int
279
- ext4_xattr_find_entry (struct ext4_xattr_entry * * pentry , int name_index ,
280
- const char * name , int sorted )
279
+ xattr_find_entry (struct inode * inode , struct ext4_xattr_entry * * pentry ,
280
+ void * end , int name_index , const char * name , int sorted )
281
281
{
282
- struct ext4_xattr_entry * entry ;
282
+ struct ext4_xattr_entry * entry , * next ;
283
283
size_t name_len ;
284
284
int cmp = 1 ;
285
285
286
286
if (name == NULL )
287
287
return - EINVAL ;
288
288
name_len = strlen (name );
289
- entry = * pentry ;
290
- for (; !IS_LAST_ENTRY (entry ); entry = EXT4_XATTR_NEXT (entry )) {
289
+ for (entry = * pentry ; !IS_LAST_ENTRY (entry ); entry = next ) {
290
+ next = EXT4_XATTR_NEXT (entry );
291
+ if ((void * ) next >= end ) {
292
+ EXT4_ERROR_INODE (inode , "corrupted xattr entries" );
293
+ return - EFSCORRUPTED ;
294
+ }
291
295
cmp = name_index - entry -> e_name_index ;
292
296
if (!cmp )
293
297
cmp = name_len - entry -> e_name_len ;
@@ -509,6 +513,7 @@ ext4_xattr_block_get(struct inode *inode, int name_index, const char *name,
509
513
struct buffer_head * bh = NULL ;
510
514
struct ext4_xattr_entry * entry ;
511
515
size_t size ;
516
+ void * end ;
512
517
int error ;
513
518
struct mb_cache * ea_block_cache = EA_BLOCK_CACHE (inode );
514
519
@@ -530,7 +535,8 @@ ext4_xattr_block_get(struct inode *inode, int name_index, const char *name,
530
535
goto cleanup ;
531
536
ext4_xattr_block_cache_insert (ea_block_cache , bh );
532
537
entry = BFIRST (bh );
533
- error = ext4_xattr_find_entry (& entry , name_index , name , 1 );
538
+ end = bh -> b_data + bh -> b_size ;
539
+ error = xattr_find_entry (inode , & entry , end , name_index , name , 1 );
534
540
if (error )
535
541
goto cleanup ;
536
542
size = le32_to_cpu (entry -> e_value_size );
@@ -579,7 +585,7 @@ ext4_xattr_ibody_get(struct inode *inode, int name_index, const char *name,
579
585
if (error )
580
586
goto cleanup ;
581
587
entry = IFIRST (header );
582
- error = ext4_xattr_find_entry ( & entry , name_index , name , 0 );
588
+ error = xattr_find_entry ( inode , & entry , end , name_index , name , 0 );
583
589
if (error )
584
590
goto cleanup ;
585
591
size = le32_to_cpu (entry -> e_value_size );
@@ -1808,8 +1814,8 @@ ext4_xattr_block_find(struct inode *inode, struct ext4_xattr_info *i,
1808
1814
bs -> s .first = BFIRST (bs -> bh );
1809
1815
bs -> s .end = bs -> bh -> b_data + bs -> bh -> b_size ;
1810
1816
bs -> s .here = bs -> s .first ;
1811
- error = ext4_xattr_find_entry ( & bs -> s .here , i -> name_index ,
1812
- i -> name , 1 );
1817
+ error = xattr_find_entry ( inode , & bs -> s .here , bs -> s . end ,
1818
+ i -> name_index , i -> name , 1 );
1813
1819
if (error && error != - ENODATA )
1814
1820
goto cleanup ;
1815
1821
bs -> s .not_found = error ;
@@ -2168,8 +2174,8 @@ int ext4_xattr_ibody_find(struct inode *inode, struct ext4_xattr_info *i,
2168
2174
if (error )
2169
2175
return error ;
2170
2176
/* Find the named attribute. */
2171
- error = ext4_xattr_find_entry ( & is -> s .here , i -> name_index ,
2172
- i -> name , 0 );
2177
+ error = xattr_find_entry ( inode , & is -> s .here , is -> s . end ,
2178
+ i -> name_index , i -> name , 0 );
2173
2179
if (error && error != - ENODATA )
2174
2180
return error ;
2175
2181
is -> s .not_found = error ;
0 commit comments