diff options
author | Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz> | 2011-05-08 14:44:32 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-09 12:04:24 -0400 |
commit | d0969d1949cc67a0f100f30ad69ec7ec1eca70d2 (patch) | |
tree | 70b04ebba74aff1c4df3e8cc213a7be721550fe8 | |
parent | 0b69760be6968c528869d4aec95ecf64dbf3e8bd (diff) |
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>
-rw-r--r-- | fs/hpfs/ea.c | 41 | ||||
-rw-r--r-- | fs/hpfs/hpfs.h | 3 | ||||
-rw-r--r-- | fs/hpfs/hpfs_fn.h | 12 |
3 files changed, 32 insertions, 24 deletions
diff --git a/fs/hpfs/ea.c b/fs/hpfs/ea.c index 1bbc37ddff40..7f1d90ca5eeb 100644 --- a/fs/hpfs/ea.c +++ b/fs/hpfs/ea.c | |||
@@ -24,7 +24,7 @@ void hpfs_ea_ext_remove(struct super_block *s, secno a, int ano, unsigned len) | |||
24 | } | 24 | } |
25 | if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return; | 25 | if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return; |
26 | if (ea->indirect) { | 26 | if (ea->indirect) { |
27 | if (le16_to_cpu(ea->valuelen) != 8) { | 27 | if (ea_valuelen(ea) != 8) { |
28 | hpfs_error(s, "ea->indirect set while ea->valuelen!=8, %s %08x, pos %08x", | 28 | hpfs_error(s, "ea->indirect set while ea->valuelen!=8, %s %08x, pos %08x", |
29 | ano ? "anode" : "sectors", a, pos); | 29 | ano ? "anode" : "sectors", a, pos); |
30 | return; | 30 | return; |
@@ -33,7 +33,7 @@ void hpfs_ea_ext_remove(struct super_block *s, secno a, int ano, unsigned len) | |||
33 | return; | 33 | return; |
34 | hpfs_ea_remove(s, ea_sec(ea), ea->anode, ea_len(ea)); | 34 | hpfs_ea_remove(s, ea_sec(ea), ea->anode, ea_len(ea)); |
35 | } | 35 | } |
36 | pos += ea->namelen + le16_to_cpu(ea->valuelen) + 5; | 36 | pos += ea->namelen + ea_valuelen(ea) + 5; |
37 | } | 37 | } |
38 | if (!ano) hpfs_free_sectors(s, a, (len+511) >> 9); | 38 | if (!ano) hpfs_free_sectors(s, a, (len+511) >> 9); |
39 | else { | 39 | else { |
@@ -82,10 +82,10 @@ int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key, | |||
82 | if (!strcmp(ea->name, key)) { | 82 | if (!strcmp(ea->name, key)) { |
83 | if (ea->indirect) | 83 | if (ea->indirect) |
84 | goto indirect; | 84 | goto indirect; |
85 | if (le16_to_cpu(ea->valuelen) >= size) | 85 | if (ea_valuelen(ea) >= size) |
86 | return -EINVAL; | 86 | return -EINVAL; |
87 | memcpy(buf, ea_data(ea), le16_to_cpu(ea->valuelen)); | 87 | memcpy(buf, ea_data(ea), ea_valuelen(ea)); |
88 | buf[le16_to_cpu(ea->valuelen)] = 0; | 88 | buf[ea_valuelen(ea)] = 0; |
89 | return 0; | 89 | return 0; |
90 | } | 90 | } |
91 | a = le32_to_cpu(fnode->ea_secno); | 91 | a = le32_to_cpu(fnode->ea_secno); |
@@ -106,14 +106,14 @@ int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key, | |||
106 | if (!strcmp(ea->name, key)) { | 106 | if (!strcmp(ea->name, key)) { |
107 | if (ea->indirect) | 107 | if (ea->indirect) |
108 | goto indirect; | 108 | goto indirect; |
109 | if (le16_to_cpu(ea->valuelen) >= size) | 109 | if (ea_valuelen(ea) >= size) |
110 | return -EINVAL; | 110 | return -EINVAL; |
111 | if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, le16_to_cpu(ea->valuelen), buf)) | 111 | if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, ea_valuelen(ea), buf)) |
112 | return -EIO; | 112 | return -EIO; |
113 | buf[le16_to_cpu(ea->valuelen)] = 0; | 113 | buf[ea_valuelen(ea)] = 0; |
114 | return 0; | 114 | return 0; |
115 | } | 115 | } |
116 | pos += ea->namelen + le16_to_cpu(ea->valuelen) + 5; | 116 | pos += ea->namelen + ea_valuelen(ea) + 5; |
117 | } | 117 | } |
118 | return -ENOENT; | 118 | return -ENOENT; |
119 | indirect: | 119 | indirect: |
@@ -138,12 +138,12 @@ char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *si | |||
138 | if (!strcmp(ea->name, key)) { | 138 | if (!strcmp(ea->name, key)) { |
139 | if (ea->indirect) | 139 | if (ea->indirect) |
140 | return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea)); | 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))) { | 141 | if (!(ret = kmalloc((*size = ea_valuelen(ea)) + 1, GFP_NOFS))) { |
142 | printk("HPFS: out of memory for EA\n"); | 142 | printk("HPFS: out of memory for EA\n"); |
143 | return NULL; | 143 | return NULL; |
144 | } | 144 | } |
145 | memcpy(ret, ea_data(ea), le16_to_cpu(ea->valuelen)); | 145 | memcpy(ret, ea_data(ea), ea_valuelen(ea)); |
146 | ret[le16_to_cpu(ea->valuelen)] = 0; | 146 | ret[ea_valuelen(ea)] = 0; |
147 | return ret; | 147 | return ret; |
148 | } | 148 | } |
149 | a = le32_to_cpu(fnode->ea_secno); | 149 | a = le32_to_cpu(fnode->ea_secno); |
@@ -164,18 +164,18 @@ char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *si | |||
164 | if (!strcmp(ea->name, key)) { | 164 | if (!strcmp(ea->name, key)) { |
165 | if (ea->indirect) | 165 | if (ea->indirect) |
166 | return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea)); | 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))) { | 167 | if (!(ret = kmalloc((*size = ea_valuelen(ea)) + 1, GFP_NOFS))) { |
168 | printk("HPFS: out of memory for EA\n"); | 168 | printk("HPFS: out of memory for EA\n"); |
169 | return NULL; | 169 | return NULL; |
170 | } | 170 | } |
171 | if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, le16_to_cpu(ea->valuelen), ret)) { | 171 | if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, ea_valuelen(ea), ret)) { |
172 | kfree(ret); | 172 | kfree(ret); |
173 | return NULL; | 173 | return NULL; |
174 | } | 174 | } |
175 | ret[le16_to_cpu(ea->valuelen)] = 0; | 175 | ret[ea_valuelen(ea)] = 0; |
176 | return ret; | 176 | return ret; |
177 | } | 177 | } |
178 | pos += ea->namelen + le16_to_cpu(ea->valuelen) + 5; | 178 | pos += ea->namelen + ea_valuelen(ea) + 5; |
179 | } | 179 | } |
180 | return NULL; | 180 | return NULL; |
181 | } | 181 | } |
@@ -202,7 +202,7 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key, | |||
202 | if (ea->indirect) { | 202 | if (ea->indirect) { |
203 | if (ea_len(ea) == size) | 203 | if (ea_len(ea) == size) |
204 | set_indirect_ea(s, ea->anode, ea_sec(ea), data, size); | 204 | set_indirect_ea(s, ea->anode, ea_sec(ea), data, size); |
205 | } else if (le16_to_cpu(ea->valuelen) == size) { | 205 | } else if (ea_valuelen(ea) == size) { |
206 | memcpy(ea_data(ea), data, size); | 206 | memcpy(ea_data(ea), data, size); |
207 | } | 207 | } |
208 | return; | 208 | return; |
@@ -228,12 +228,12 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key, | |||
228 | set_indirect_ea(s, ea->anode, ea_sec(ea), data, size); | 228 | set_indirect_ea(s, ea->anode, ea_sec(ea), data, size); |
229 | } | 229 | } |
230 | else { | 230 | else { |
231 | if (le16_to_cpu(ea->valuelen) == size) | 231 | if (ea_valuelen(ea) == size) |
232 | hpfs_ea_write(s, a, ano, pos + 4 + ea->namelen + 1, size, data); | 232 | hpfs_ea_write(s, a, ano, pos + 4 + ea->namelen + 1, size, data); |
233 | } | 233 | } |
234 | return; | 234 | return; |
235 | } | 235 | } |
236 | pos += ea->namelen + le16_to_cpu(ea->valuelen) + 5; | 236 | pos += ea->namelen + ea_valuelen(ea) + 5; |
237 | } | 237 | } |
238 | if (!le16_to_cpu(fnode->ea_offs)) { | 238 | if (!le16_to_cpu(fnode->ea_offs)) { |
239 | /*if (le16_to_cpu(fnode->ea_size_s)) { | 239 | /*if (le16_to_cpu(fnode->ea_size_s)) { |
@@ -254,7 +254,8 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key, | |||
254 | ea = fnode_end_ea(fnode); | 254 | ea = fnode_end_ea(fnode); |
255 | *(char *)ea = 0; | 255 | *(char *)ea = 0; |
256 | ea->namelen = strlen(key); | 256 | ea->namelen = strlen(key); |
257 | ea->valuelen = cpu_to_le16(size); | 257 | ea->valuelen_lo = size; |
258 | ea->valuelen_hi = size >> 8; | ||
258 | strcpy(ea->name, key); | 259 | strcpy(ea->name, key); |
259 | memcpy(ea_data(ea), data, size); | 260 | 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); | 261 | fnode->ea_size_s = cpu_to_le16(le16_to_cpu(fnode->ea_size_s) + strlen(key) + size + 5); |
diff --git a/fs/hpfs/hpfs.h b/fs/hpfs/hpfs.h index 91a6223893f9..8b0650aae328 100644 --- a/fs/hpfs/hpfs.h +++ b/fs/hpfs/hpfs.h | |||
@@ -546,7 +546,8 @@ struct extended_attribute | |||
546 | where real value starts */ | 546 | where real value starts */ |
547 | #endif | 547 | #endif |
548 | u8 namelen; /* length of name, bytes */ | 548 | u8 namelen; /* length of name, bytes */ |
549 | u16 valuelen; /* length of value, bytes */ | 549 | u8 valuelen_lo; /* length of value, bytes */ |
550 | u8 valuelen_hi; /* length of value, bytes */ | ||
550 | u8 name[0]; | 551 | u8 name[0]; |
551 | /* | 552 | /* |
552 | u8 name[namelen]; ascii attrib name | 553 | u8 name[namelen]; ascii attrib name |
diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h index f99377306b13..dd552f862c8f 100644 --- a/fs/hpfs/hpfs_fn.h +++ b/fs/hpfs/hpfs_fn.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/pagemap.h> | 13 | #include <linux/pagemap.h> |
14 | #include <linux/buffer_head.h> | 14 | #include <linux/buffer_head.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <asm/unaligned.h> | ||
16 | 17 | ||
17 | #include "hpfs.h" | 18 | #include "hpfs.h" |
18 | 19 | ||
@@ -135,19 +136,24 @@ static inline struct extended_attribute *fnode_end_ea(struct fnode *fnode) | |||
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 | 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 | } |
137 | 138 | ||
139 | static unsigned ea_valuelen(struct extended_attribute *ea) | ||
140 | { | ||
141 | return ea->valuelen_lo + 256 * ea->valuelen_hi; | ||
142 | } | ||
143 | |||
138 | static inline struct extended_attribute *next_ea(struct extended_attribute *ea) | 144 | static inline struct extended_attribute *next_ea(struct extended_attribute *ea) |
139 | { | 145 | { |
140 | return (struct extended_attribute *)((char *)ea + 5 + ea->namelen + le16_to_cpu(ea->valuelen)); | 146 | return (struct extended_attribute *)((char *)ea + 5 + ea->namelen + ea_valuelen(ea)); |
141 | } | 147 | } |
142 | 148 | ||
143 | static inline secno ea_sec(struct extended_attribute *ea) | 149 | static inline secno ea_sec(struct extended_attribute *ea) |
144 | { | 150 | { |
145 | return le32_to_cpu(*((secno *)((char *)ea + 9 + ea->namelen))); | 151 | return le32_to_cpu(get_unaligned((secno *)((char *)ea + 9 + ea->namelen))); |
146 | } | 152 | } |
147 | 153 | ||
148 | static inline secno ea_len(struct extended_attribute *ea) | 154 | static inline secno ea_len(struct extended_attribute *ea) |
149 | { | 155 | { |
150 | return le32_to_cpu(*((secno *)((char *)ea + 5 + ea->namelen))); | 156 | return le32_to_cpu(get_unaligned((secno *)((char *)ea + 5 + ea->namelen))); |
151 | } | 157 | } |
152 | 158 | ||
153 | static inline char *ea_data(struct extended_attribute *ea) | 159 | static inline char *ea_data(struct extended_attribute *ea) |