@@ -205,12 +205,17 @@ static inline const struct xattr_handler *f2fs_xattr_handler(int index)
205205 return handler ;
206206}
207207
208- static struct f2fs_xattr_entry * __find_xattr (void * base_addr , int index ,
209- size_t len , const char * name )
208+ static struct f2fs_xattr_entry * __find_xattr (void * base_addr ,
209+ void * last_base_addr , int index ,
210+ size_t len , const char * name )
210211{
211212 struct f2fs_xattr_entry * entry ;
212213
213214 list_for_each_xattr (entry , base_addr ) {
215+ if ((void * )(entry ) + sizeof (__u32 ) > last_base_addr ||
216+ (void * )XATTR_NEXT_ENTRY (entry ) > last_base_addr )
217+ return NULL ;
218+
214219 if (entry -> e_name_index != index )
215220 continue ;
216221 if (entry -> e_name_len != len )
@@ -300,20 +305,22 @@ static int lookup_all_xattrs(struct inode *inode, struct page *ipage,
300305 const char * name , struct f2fs_xattr_entry * * xe ,
301306 void * * base_addr , int * base_size )
302307{
303- void * cur_addr , * txattr_addr , * last_addr = NULL ;
308+ void * cur_addr , * txattr_addr , * last_txattr_addr ;
309+ void * last_addr = NULL ;
304310 nid_t xnid = F2FS_I (inode )-> i_xattr_nid ;
305- unsigned int size = xnid ? VALID_XATTR_BLOCK_SIZE : 0 ;
306311 unsigned int inline_size = inline_xattr_size (inode );
307312 int err = 0 ;
308313
309- if (!size && !inline_size )
314+ if (!xnid && !inline_size )
310315 return - ENODATA ;
311316
312- * base_size = inline_size + size + XATTR_PADDING_SIZE ;
317+ * base_size = XATTR_SIZE ( xnid , inode ) + XATTR_PADDING_SIZE ;
313318 txattr_addr = f2fs_kzalloc (F2FS_I_SB (inode ), * base_size , GFP_NOFS );
314319 if (!txattr_addr )
315320 return - ENOMEM ;
316321
322+ last_txattr_addr = (void * )txattr_addr + XATTR_SIZE (xnid , inode );
323+
317324 /* read from inline xattr */
318325 if (inline_size ) {
319326 err = read_inline_xattr (inode , ipage , txattr_addr );
@@ -340,7 +347,11 @@ static int lookup_all_xattrs(struct inode *inode, struct page *ipage,
340347 else
341348 cur_addr = txattr_addr ;
342349
343- * xe = __find_xattr (cur_addr , index , len , name );
350+ * xe = __find_xattr (cur_addr , last_txattr_addr , index , len , name );
351+ if (!* xe ) {
352+ err = - EFAULT ;
353+ goto out ;
354+ }
344355check :
345356 if (IS_XATTR_LAST_ENTRY (* xe )) {
346357 err = - ENODATA ;
@@ -584,7 +595,8 @@ static int __f2fs_setxattr(struct inode *inode, int index,
584595 struct page * ipage , int flags )
585596{
586597 struct f2fs_xattr_entry * here , * last ;
587- void * base_addr ;
598+ void * base_addr , * last_base_addr ;
599+ nid_t xnid = F2FS_I (inode )-> i_xattr_nid ;
588600 int found , newsize ;
589601 size_t len ;
590602 __u32 new_hsize ;
@@ -608,8 +620,14 @@ static int __f2fs_setxattr(struct inode *inode, int index,
608620 if (error )
609621 return error ;
610622
623+ last_base_addr = (void * )base_addr + XATTR_SIZE (xnid , inode );
624+
611625 /* find entry with wanted name. */
612- here = __find_xattr (base_addr , index , len , name );
626+ here = __find_xattr (base_addr , last_base_addr , index , len , name );
627+ if (!here ) {
628+ error = - EFAULT ;
629+ goto exit ;
630+ }
613631
614632 found = IS_XATTR_LAST_ENTRY (here ) ? 0 : 1 ;
615633
0 commit comments