HPFS: Fix some unaligned accesses

Fix some unaligned accesses

Signed-off-by: Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by Mikulas Patocka and committed by Linus Torvalds d0969d19 0b69760b

+32 -24
+21 -20
fs/hpfs/ea.c
··· 24 } 25 if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return; 26 if (ea->indirect) { 27 - if (le16_to_cpu(ea->valuelen) != 8) { 28 hpfs_error(s, "ea->indirect set while ea->valuelen!=8, %s %08x, pos %08x", 29 ano ? "anode" : "sectors", a, pos); 30 return; ··· 33 return; 34 hpfs_ea_remove(s, ea_sec(ea), ea->anode, ea_len(ea)); 35 } 36 - pos += ea->namelen + le16_to_cpu(ea->valuelen) + 5; 37 } 38 if (!ano) hpfs_free_sectors(s, a, (len+511) >> 9); 39 else { ··· 82 if (!strcmp(ea->name, key)) { 83 if (ea->indirect) 84 goto indirect; 85 - if (le16_to_cpu(ea->valuelen) >= size) 86 return -EINVAL; 87 - memcpy(buf, ea_data(ea), le16_to_cpu(ea->valuelen)); 88 - buf[le16_to_cpu(ea->valuelen)] = 0; 89 return 0; 90 } 91 a = le32_to_cpu(fnode->ea_secno); ··· 106 if (!strcmp(ea->name, key)) { 107 if (ea->indirect) 108 goto indirect; 109 - if (le16_to_cpu(ea->valuelen) >= size) 110 return -EINVAL; 111 - if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, le16_to_cpu(ea->valuelen), buf)) 112 return -EIO; 113 - buf[le16_to_cpu(ea->valuelen)] = 0; 114 return 0; 115 } 116 - pos += ea->namelen + le16_to_cpu(ea->valuelen) + 5; 117 } 118 return -ENOENT; 119 indirect: ··· 138 if (!strcmp(ea->name, key)) { 139 if (ea->indirect) 140 return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea)); 141 - if (!(ret = kmalloc((*size = le16_to_cpu(ea->valuelen)) + 1, GFP_NOFS))) { 142 printk("HPFS: out of memory for EA\n"); 143 return NULL; 144 } 145 - memcpy(ret, ea_data(ea), le16_to_cpu(ea->valuelen)); 146 - ret[le16_to_cpu(ea->valuelen)] = 0; 147 return ret; 148 } 149 a = le32_to_cpu(fnode->ea_secno); ··· 164 if (!strcmp(ea->name, key)) { 165 if (ea->indirect) 166 return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea)); 167 - if (!(ret = kmalloc((*size = le16_to_cpu(ea->valuelen)) + 1, GFP_NOFS))) { 168 printk("HPFS: out of memory for EA\n"); 169 return NULL; 170 } 171 - if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, le16_to_cpu(ea->valuelen), ret)) { 172 kfree(ret); 173 return NULL; 174 } 175 - ret[le16_to_cpu(ea->valuelen)] = 0; 176 return ret; 177 } 178 - pos += ea->namelen + le16_to_cpu(ea->valuelen) + 5; 179 } 180 return NULL; 181 } ··· 202 if (ea->indirect) { 203 if (ea_len(ea) == size) 204 set_indirect_ea(s, ea->anode, ea_sec(ea), data, size); 205 - } else if (le16_to_cpu(ea->valuelen) == size) { 206 memcpy(ea_data(ea), data, size); 207 } 208 return; ··· 228 set_indirect_ea(s, ea->anode, ea_sec(ea), data, size); 229 } 230 else { 231 - if (le16_to_cpu(ea->valuelen) == size) 232 hpfs_ea_write(s, a, ano, pos + 4 + ea->namelen + 1, size, data); 233 } 234 return; 235 } 236 - pos += ea->namelen + le16_to_cpu(ea->valuelen) + 5; 237 } 238 if (!le16_to_cpu(fnode->ea_offs)) { 239 /*if (le16_to_cpu(fnode->ea_size_s)) { ··· 254 ea = fnode_end_ea(fnode); 255 *(char *)ea = 0; 256 ea->namelen = strlen(key); 257 - ea->valuelen = cpu_to_le16(size); 258 strcpy(ea->name, key); 259 memcpy(ea_data(ea), data, size); 260 fnode->ea_size_s = cpu_to_le16(le16_to_cpu(fnode->ea_size_s) + strlen(key) + size + 5);
··· 24 } 25 if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return; 26 if (ea->indirect) { 27 + if (ea_valuelen(ea) != 8) { 28 hpfs_error(s, "ea->indirect set while ea->valuelen!=8, %s %08x, pos %08x", 29 ano ? "anode" : "sectors", a, pos); 30 return; ··· 33 return; 34 hpfs_ea_remove(s, ea_sec(ea), ea->anode, ea_len(ea)); 35 } 36 + pos += ea->namelen + ea_valuelen(ea) + 5; 37 } 38 if (!ano) hpfs_free_sectors(s, a, (len+511) >> 9); 39 else { ··· 82 if (!strcmp(ea->name, key)) { 83 if (ea->indirect) 84 goto indirect; 85 + if (ea_valuelen(ea) >= size) 86 return -EINVAL; 87 + memcpy(buf, ea_data(ea), ea_valuelen(ea)); 88 + buf[ea_valuelen(ea)] = 0; 89 return 0; 90 } 91 a = le32_to_cpu(fnode->ea_secno); ··· 106 if (!strcmp(ea->name, key)) { 107 if (ea->indirect) 108 goto indirect; 109 + if (ea_valuelen(ea) >= size) 110 return -EINVAL; 111 + if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, ea_valuelen(ea), buf)) 112 return -EIO; 113 + buf[ea_valuelen(ea)] = 0; 114 return 0; 115 } 116 + pos += ea->namelen + ea_valuelen(ea) + 5; 117 } 118 return -ENOENT; 119 indirect: ··· 138 if (!strcmp(ea->name, key)) { 139 if (ea->indirect) 140 return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea)); 141 + if (!(ret = kmalloc((*size = ea_valuelen(ea)) + 1, GFP_NOFS))) { 142 printk("HPFS: out of memory for EA\n"); 143 return NULL; 144 } 145 + memcpy(ret, ea_data(ea), ea_valuelen(ea)); 146 + ret[ea_valuelen(ea)] = 0; 147 return ret; 148 } 149 a = le32_to_cpu(fnode->ea_secno); ··· 164 if (!strcmp(ea->name, key)) { 165 if (ea->indirect) 166 return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea)); 167 + if (!(ret = kmalloc((*size = ea_valuelen(ea)) + 1, GFP_NOFS))) { 168 printk("HPFS: out of memory for EA\n"); 169 return NULL; 170 } 171 + if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, ea_valuelen(ea), ret)) { 172 kfree(ret); 173 return NULL; 174 } 175 + ret[ea_valuelen(ea)] = 0; 176 return ret; 177 } 178 + pos += ea->namelen + ea_valuelen(ea) + 5; 179 } 180 return NULL; 181 } ··· 202 if (ea->indirect) { 203 if (ea_len(ea) == size) 204 set_indirect_ea(s, ea->anode, ea_sec(ea), data, size); 205 + } else if (ea_valuelen(ea) == size) { 206 memcpy(ea_data(ea), data, size); 207 } 208 return; ··· 228 set_indirect_ea(s, ea->anode, ea_sec(ea), data, size); 229 } 230 else { 231 + if (ea_valuelen(ea) == size) 232 hpfs_ea_write(s, a, ano, pos + 4 + ea->namelen + 1, size, data); 233 } 234 return; 235 } 236 + pos += ea->namelen + ea_valuelen(ea) + 5; 237 } 238 if (!le16_to_cpu(fnode->ea_offs)) { 239 /*if (le16_to_cpu(fnode->ea_size_s)) { ··· 254 ea = fnode_end_ea(fnode); 255 *(char *)ea = 0; 256 ea->namelen = strlen(key); 257 + ea->valuelen_lo = size; 258 + ea->valuelen_hi = size >> 8; 259 strcpy(ea->name, key); 260 memcpy(ea_data(ea), data, size); 261 fnode->ea_size_s = cpu_to_le16(le16_to_cpu(fnode->ea_size_s) + strlen(key) + size + 5);
+2 -1
fs/hpfs/hpfs.h
··· 546 where real value starts */ 547 #endif 548 u8 namelen; /* length of name, bytes */ 549 - u16 valuelen; /* length of value, bytes */ 550 u8 name[0]; 551 /* 552 u8 name[namelen]; ascii attrib name
··· 546 where real value starts */ 547 #endif 548 u8 namelen; /* length of name, bytes */ 549 + u8 valuelen_lo; /* length of value, bytes */ 550 + u8 valuelen_hi; /* length of value, bytes */ 551 u8 name[0]; 552 /* 553 u8 name[namelen]; ascii attrib name
+9 -3
fs/hpfs/hpfs_fn.h
··· 13 #include <linux/pagemap.h> 14 #include <linux/buffer_head.h> 15 #include <linux/slab.h> 16 17 #include "hpfs.h" 18 ··· 136 return (struct extended_attribute *)((char *)fnode + le16_to_cpu(fnode->ea_offs) + le16_to_cpu(fnode->acl_size_s) + le16_to_cpu(fnode->ea_size_s)); 137 } 138 139 static inline struct extended_attribute *next_ea(struct extended_attribute *ea) 140 { 141 - return (struct extended_attribute *)((char *)ea + 5 + ea->namelen + le16_to_cpu(ea->valuelen)); 142 } 143 144 static inline secno ea_sec(struct extended_attribute *ea) 145 { 146 - return le32_to_cpu(*((secno *)((char *)ea + 9 + ea->namelen))); 147 } 148 149 static inline secno ea_len(struct extended_attribute *ea) 150 { 151 - return le32_to_cpu(*((secno *)((char *)ea + 5 + ea->namelen))); 152 } 153 154 static inline char *ea_data(struct extended_attribute *ea)
··· 13 #include <linux/pagemap.h> 14 #include <linux/buffer_head.h> 15 #include <linux/slab.h> 16 + #include <asm/unaligned.h> 17 18 #include "hpfs.h" 19 ··· 135 return (struct extended_attribute *)((char *)fnode + le16_to_cpu(fnode->ea_offs) + le16_to_cpu(fnode->acl_size_s) + le16_to_cpu(fnode->ea_size_s)); 136 } 137 138 + static unsigned ea_valuelen(struct extended_attribute *ea) 139 + { 140 + return ea->valuelen_lo + 256 * ea->valuelen_hi; 141 + } 142 + 143 static inline struct extended_attribute *next_ea(struct extended_attribute *ea) 144 { 145 + return (struct extended_attribute *)((char *)ea + 5 + ea->namelen + ea_valuelen(ea)); 146 } 147 148 static inline secno ea_sec(struct extended_attribute *ea) 149 { 150 + return le32_to_cpu(get_unaligned((secno *)((char *)ea + 9 + ea->namelen))); 151 } 152 153 static inline secno ea_len(struct extended_attribute *ea) 154 { 155 + return le32_to_cpu(get_unaligned((secno *)((char *)ea + 5 + ea->namelen))); 156 } 157 158 static inline char *ea_data(struct extended_attribute *ea)