diff --git a/fs/hpfs/ea.c b/fs/hpfs/ea.c index 102ba18e561f..7e6e43010fec 100644 --- a/fs/hpfs/ea.c +++ b/fs/hpfs/ea.c @@ -135,7 +135,31 @@ char *hpfs_get_ea(struct super_block *s, struct fnode secno a; struct extended_attribute *ea; struct extended_attribute *ea_end = fnode_end_ea(fnode); - for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea)) + for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea)) { + /* Validate EA structure bounds */ + if ((char *)ea + sizeof(*ea) > (char *)ea_end) { + hpfs_error(s, "EA structure exceeds bounds"); + return NULL; + } + + /* Validate namelen to prevent overflow */ + if (ea->namelen >= 256) { + hpfs_error(s, "EA namelen too large: %d", ea->namelen); + return NULL; + } + + /* Ensure name field is within bounds */ + if ((char *)ea + 5 + ea->namelen > (char *)ea_end) { + hpfs_error(s, "EA name field exceeds bounds"); + return NULL; + } + + /* Validate next_ea() result will be within bounds */ + if (next_ea(ea) > ea_end) { + hpfs_error(s, "next EA exceeds bounds"); + return NULL; + } + if (!strcmp(ea->name, key)) { if (ea_indirect(ea)) return get_indirect_ea(s, ea_in_anode(ea), ea_sec(ea), *size = @@ -147,6 +171,7 @@ char *hpfs_get_ea(struct super_block *s, struct fnode ret[ea_valuelen(ea)] = 0; return ret; } + } a = le32_to_cpu(fnode->ea_secno); len = le32_to_cpu(fnode->ea_size_l); ano = fnode_in_anode(fnode);