aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/xattr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/xattr.c')
-rw-r--r--fs/ext4/xattr.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index 0441e055c8e8..e79bd32b9b79 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -230,6 +230,27 @@ ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh)
230 return error; 230 return error;
231} 231}
232 232
233static int
234__xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header,
235 void *end, const char *function, unsigned int line)
236{
237 struct ext4_xattr_entry *entry = IFIRST(header);
238 int error = -EFSCORRUPTED;
239
240 if (((void *) header >= end) ||
241 (header->h_magic != le32_to_cpu(EXT4_XATTR_MAGIC)))
242 goto errout;
243 error = ext4_xattr_check_names(entry, end, entry);
244errout:
245 if (error)
246 __ext4_error_inode(inode, function, line, 0,
247 "corrupted in-inode xattr");
248 return error;
249}
250
251#define xattr_check_inode(inode, header, end) \
252 __xattr_check_inode((inode), (header), (end), __func__, __LINE__)
253
233static inline int 254static inline int
234ext4_xattr_check_entry(struct ext4_xattr_entry *entry, size_t size) 255ext4_xattr_check_entry(struct ext4_xattr_entry *entry, size_t size)
235{ 256{
@@ -341,7 +362,7 @@ ext4_xattr_ibody_get(struct inode *inode, int name_index, const char *name,
341 header = IHDR(inode, raw_inode); 362 header = IHDR(inode, raw_inode);
342 entry = IFIRST(header); 363 entry = IFIRST(header);
343 end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size; 364 end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
344 error = ext4_xattr_check_names(entry, end, entry); 365 error = xattr_check_inode(inode, header, end);
345 if (error) 366 if (error)
346 goto cleanup; 367 goto cleanup;
347 error = ext4_xattr_find_entry(&entry, name_index, name, 368 error = ext4_xattr_find_entry(&entry, name_index, name,
@@ -477,7 +498,7 @@ ext4_xattr_ibody_list(struct dentry *dentry, char *buffer, size_t buffer_size)
477 raw_inode = ext4_raw_inode(&iloc); 498 raw_inode = ext4_raw_inode(&iloc);
478 header = IHDR(inode, raw_inode); 499 header = IHDR(inode, raw_inode);
479 end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size; 500 end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
480 error = ext4_xattr_check_names(IFIRST(header), end, IFIRST(header)); 501 error = xattr_check_inode(inode, header, end);
481 if (error) 502 if (error)
482 goto cleanup; 503 goto cleanup;
483 error = ext4_xattr_list_entries(dentry, IFIRST(header), 504 error = ext4_xattr_list_entries(dentry, IFIRST(header),
@@ -1040,8 +1061,7 @@ int ext4_xattr_ibody_find(struct inode *inode, struct ext4_xattr_info *i,
1040 is->s.here = is->s.first; 1061 is->s.here = is->s.first;
1041 is->s.end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size; 1062 is->s.end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
1042 if (ext4_test_inode_state(inode, EXT4_STATE_XATTR)) { 1063 if (ext4_test_inode_state(inode, EXT4_STATE_XATTR)) {
1043 error = ext4_xattr_check_names(IFIRST(header), is->s.end, 1064 error = xattr_check_inode(inode, header, is->s.end);
1044 IFIRST(header));
1045 if (error) 1065 if (error)
1046 return error; 1066 return error;
1047 /* Find the named attribute. */ 1067 /* Find the named attribute. */
@@ -1356,6 +1376,10 @@ retry:
1356 last = entry; 1376 last = entry;
1357 total_ino = sizeof(struct ext4_xattr_ibody_header); 1377 total_ino = sizeof(struct ext4_xattr_ibody_header);
1358 1378
1379 error = xattr_check_inode(inode, header, end);
1380 if (error)
1381 goto cleanup;
1382
1359 free = ext4_xattr_free_space(last, &min_offs, base, &total_ino); 1383 free = ext4_xattr_free_space(last, &min_offs, base, &total_ino);
1360 if (free >= new_extra_isize) { 1384 if (free >= new_extra_isize) {
1361 entry = IFIRST(header); 1385 entry = IFIRST(header);