@@ -46,10 +46,11 @@ static int ntfs_write_ea(struct ntfs_inode *ni, __le32 type, char *value, s64 ea
4646}
4747
4848static int ntfs_ea_lookup (char * ea_buf , s64 ea_buf_size , const char * name ,
49- int name_len , s64 * ea_offset , s64 * ea_size )
49+ int name_len , s64 * ea_offset , s64 * ea_size )
5050{
5151 const struct ea_attr * p_ea ;
52- s64 offset ;
52+ size_t actual_size ;
53+ loff_t offset , p_ea_size ;
5354 unsigned int next ;
5455
5556 if (ea_buf_size < sizeof (struct ea_attr ))
@@ -59,36 +60,33 @@ static int ntfs_ea_lookup(char *ea_buf, s64 ea_buf_size, const char *name,
5960 do {
6061 p_ea = (const struct ea_attr * )& ea_buf [offset ];
6162 next = le32_to_cpu (p_ea -> next_entry_offset );
63+ p_ea_size = next ? next : (ea_buf_size - offset );
6264
63- if (offset + next > ea_buf_size ||
64- ((1 + p_ea -> ea_name_length ) > (ea_buf_size - offset )))
65+ if (p_ea_size < sizeof (struct ea_attr ) ||
66+ offset + p_ea_size > ea_buf_size )
67+ break ;
68+
69+ if ((s64 )p_ea -> ea_name_length + 1 >
70+ p_ea_size - offsetof(struct ea_attr , ea_name ))
71+ break ;
72+
73+ actual_size = ALIGN (struct_size (p_ea , ea_name , 1 + p_ea -> ea_name_length +
74+ le16_to_cpu (p_ea -> ea_value_length )), 4 );
75+ if (actual_size > p_ea_size )
6576 break ;
6677
6778 if (p_ea -> ea_name_length == name_len &&
6879 !memcmp (p_ea -> ea_name , name , name_len )) {
6980 * ea_offset = offset ;
70- if (next )
71- * ea_size = next ;
72- else {
73- unsigned int ea_len = 1 + p_ea -> ea_name_length +
74- le16_to_cpu (p_ea -> ea_value_length );
75-
76- if ((ea_buf_size - offset ) < ea_len )
77- goto out ;
78-
79- * ea_size = ALIGN (struct_size (p_ea , ea_name ,
80- 1 + p_ea -> ea_name_length +
81- le16_to_cpu (p_ea -> ea_value_length )), 4 );
82- }
81+ * ea_size = next ? next : actual_size ;
8382
8483 if (ea_buf_size < * ea_offset + * ea_size )
8584 goto out ;
8685
8786 return 0 ;
8887 }
8988 offset += next ;
90- } while (next > 0 && offset < ea_buf_size &&
91- sizeof (struct ea_attr ) < (ea_buf_size - offset ));
89+ } while (next > 0 && offset < ea_buf_size );
9290
9391out :
9492 return - ENOENT ;
0 commit comments