aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrian Hunter <ext-adrian.hunter@nokia.com>2008-10-17 09:52:10 -0400
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2008-10-19 06:01:21 -0400
commit727d2dc045930b29dc68d56d5032d23661ba8503 (patch)
tree66fc9a3dccd7639acf47774274f3b69a888caeb8
parentbe2f6bd62d0d4246a9227dacbe2469e1f0eccf26 (diff)
UBIFS: do not read unnecessary bytes when unpacking bits
Fixes the following Oops: BUG: unable to handle kernel paging request at f8d24000 IP: [<f8ff0657>] :ubifs:ubifs_unpack_bits+0xcd/0x231 *pde = 34333067 *pte = 00000000 Oops: 0000 [#1] PREEMPT SMP Modules linked in: deflate zlib_deflate lzo lzo_decompress lzo_compress ubifs ubi nandsim nand nand_ids nand_ecc mtd nfsd lockd sunrpc exportfs [last unloaded: nand_ecc] Pid: 7450, comm: sync Not tainted (2.6.27-rc8-ubifs-2.6 #27) EIP: 0060:[<f8ff0657>] EFLAGS: 00010206 CPU: 0 EIP is at ubifs_unpack_bits+0xcd/0x231 [ubifs] EAX: 00000000 EBX: 00000000 ECX: d7e43dc0 EDX: 0000ff00 ESI: 00000004 EDI: f8d23ffe EBP: d7e43db4 ESP: d7e43d8c DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 Process sync (pid: 7450, ti=d7e42000 task=eb6f9530 task.ti=d7e42000) Stack: 00000400 c0103db4 dc5e8090 d7e43dc0 d7e43dc0 d7e43dc4 0000001c 00000004 f496d1e0 f8d23ffc d7e43dd4 f8ffac7e f8d23ffe 00000000 f8d23ffe f2b7af68 f496d1e0 f8d23ffc d7e43e2c f8ffadc5 00000000 0001f000 00000000 c03b10a7 Call Trace: [<c0103db4>] ? restore_nocheck_notrace+0x0/0xe [<f8ffac7e>] ? is_a_node+0x43/0x92 [ubifs] [<f8ffadc5>] ? dbg_check_ltab+0xf8/0x5c9 [ubifs] [<c03b10a7>] ? mutex_lock_nested+0x1b2/0x2a0 [<f8ffc86e>] ? ubifs_lpt_start_commit+0x49/0xecb [ubifs] [<c03b0ef3>] ? mutex_unlock+0xd/0xf [<f8fef017>] ? ubifs_tnc_start_commit+0x1cf/0xef8 [ubifs] [<f8fe65d8>] ? do_commit+0x18f/0x52d [ubifs] [<f8fe69f6>] ? ubifs_run_commit+0x80/0xca [ubifs] [<f8fd8d35>] ? ubifs_sync_fs+0xdb/0xf6 [ubifs] [<c0181a07>] ? sync_filesystems+0xc6/0x10c [<c019f279>] ? do_sync+0x3b/0x6a [<c019f2ba>] ? sys_sync+0x12/0x18 [<c0103ced>] ? sysenter_do_call+0x12/0x35 ======================= Code: 4d ec 89 01 8b 45 e8 89 10 89 d8 89 f1 d3 e8 85 c0 74 07 29 d6 83 fe 20 75 2a 89 d8 83 c4 1c 5b 5e 5f 5d c3 0f b6 57 01 c1 e2 08 <0f> b6 47 02 c1 e0 10 09 c2 0f b6 07 09 c2 0f b EIP: [<f8ff0657>] ubifs_unpack_bits+0xcd/0x231 [ubifs] SS:ESP 0068:d7e43d8c ---[ end trace 1bbb4c407a6dd816 ]--- Signed-off-by: Adrian Hunter <ext-adrian.hunter@nokia.com>
-rw-r--r--fs/ubifs/lpt.c45
1 files changed, 38 insertions, 7 deletions
diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c
index cd11b23a1875..db8bd0e518b2 100644
--- a/fs/ubifs/lpt.c
+++ b/fs/ubifs/lpt.c
@@ -288,25 +288,56 @@ uint32_t ubifs_unpack_bits(uint8_t **addr, int *pos, int nrbits)
288 const int k = 32 - nrbits; 288 const int k = 32 - nrbits;
289 uint8_t *p = *addr; 289 uint8_t *p = *addr;
290 int b = *pos; 290 int b = *pos;
291 uint32_t val; 291 uint32_t uninitialized_var(val);
292 const int bytes = (nrbits + b + 7) >> 3;
292 293
293 ubifs_assert(nrbits > 0); 294 ubifs_assert(nrbits > 0);
294 ubifs_assert(nrbits <= 32); 295 ubifs_assert(nrbits <= 32);
295 ubifs_assert(*pos >= 0); 296 ubifs_assert(*pos >= 0);
296 ubifs_assert(*pos < 8); 297 ubifs_assert(*pos < 8);
297 if (b) { 298 if (b) {
298 val = p[1] | ((uint32_t)p[2] << 8) | ((uint32_t)p[3] << 16) | 299 switch (bytes) {
299 ((uint32_t)p[4] << 24); 300 case 2:
301 val = p[1];
302 break;
303 case 3:
304 val = p[1] | ((uint32_t)p[2] << 8);
305 break;
306 case 4:
307 val = p[1] | ((uint32_t)p[2] << 8) |
308 ((uint32_t)p[3] << 16);
309 break;
310 case 5:
311 val = p[1] | ((uint32_t)p[2] << 8) |
312 ((uint32_t)p[3] << 16) |
313 ((uint32_t)p[4] << 24);
314 }
300 val <<= (8 - b); 315 val <<= (8 - b);
301 val |= *p >> b; 316 val |= *p >> b;
302 nrbits += b; 317 nrbits += b;
303 } else 318 } else {
304 val = p[0] | ((uint32_t)p[1] << 8) | ((uint32_t)p[2] << 16) | 319 switch (bytes) {
305 ((uint32_t)p[3] << 24); 320 case 1:
321 val = p[0];
322 break;
323 case 2:
324 val = p[0] | ((uint32_t)p[1] << 8);
325 break;
326 case 3:
327 val = p[0] | ((uint32_t)p[1] << 8) |
328 ((uint32_t)p[2] << 16);
329 break;
330 case 4:
331 val = p[0] | ((uint32_t)p[1] << 8) |
332 ((uint32_t)p[2] << 16) |
333 ((uint32_t)p[3] << 24);
334 break;
335 }
336 }
306 val <<= k; 337 val <<= k;
307 val >>= k; 338 val >>= k;
308 b = nrbits & 7; 339 b = nrbits & 7;
309 p += nrbits / 8; 340 p += nrbits >> 3;
310 *addr = p; 341 *addr = p;
311 *pos = b; 342 *pos = b;
312 ubifs_assert((val >> nrbits) == 0 || nrbits - b == 32); 343 ubifs_assert((val >> nrbits) == 0 || nrbits - b == 32);