Size overflow panics in ZFS
Posted: Tue Apr 08, 2014 7:25 pm
Hi,
When using grsec 3.0-3.13.9-201404062127 and ZFS (an out-of-tree module), I seem to be hitting this size overflow:
The code in question seems to be:
Specifically, the panic seems to indicate the error is in line 5787 (or around that point?).
SPA_CONFIG_BLOCKSIZE is defined to be 16384:
The macro in line 5786 is defined as:
(... and it's used in dozens of places all over the ZFS code).
Here's a disassembly of where *I think* is the problem:
I think (but I'm not sure) the code in 4ea89..4eaa8 is a call to report_size_overflow().
Notice how the constant in 4e90b seems to be equal to -SPA_CONFIG_BLOCKSIZE.
How can I fix this, as a user?
When using grsec 3.0-3.13.9-201404062127 and ZFS (an out-of-tree module), I seem to be hitting this size overflow:
- Code: Select all
[ 38.550690] PAX: size overflow detected in function spa_sync_nvlist.isra.22 /tmp/nix-build-zfs-0.6.2-3.13.9.drv-0/zfs-0.6.2/module/zfs/../../module/zfs/spa.c:5787 cicus.362_65 min, count: 2
[ 38.553712] CPU: 0 PID: 1631 Comm: txg_sync Tainted: P O 3.13.9-grsec #1-NixOS
[ 38.555168] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
[ 38.556123] ffffffff816fd887 0000000000000000 ffffffffa0690df8 ffff880009437c98
[ 38.557409] ffffffff81482bcb ffffffffa069d3c0 ffff880009437cc8 ffffffff8117ae1b
[ 38.558697] 0000000000004000 ffff880009bfe578 ffff880017a43358 000000000000001b
[ 38.559978] Call Trace:
[ 38.560432] [<ffffffffa0690df8>] ? zfs_fill_zplprops+0xf70d/0x3fe0f [zfs]
[ 38.561594] [<ffffffff81482bcb>] dump_stack+0x45/0x56
[ 38.562460] [<ffffffffa069d3c0>] ? zfs_fill_zplprops+0x1bcd5/0x3fe0f [zfs]
[ 38.563616] [<ffffffff8117ae1b>] report_size_overflow+0x3b/0x50
[ 38.564622] [<ffffffffa061daa8>] spa_sync_nvlist.isra.22+0x1f8/0x200 [zfs]
[ 38.565832] [<ffffffffa061e132>] spa_sync+0x3e2/0xae0 [zfs]
[ 38.566804] [<ffffffff810a5bf8>] ? ktime_get_ts+0x48/0xe0
[ 38.567752] [<ffffffffa062f5c6>] txg_sync_thread+0x316/0x660 [zfs]
[ 38.568821] [<ffffffffa0695590>] ? zfs_fill_zplprops+0x13ea5/0x3fe0f [zfs]
[ 38.570006] [<ffffffffa062f2b0>] ? txg_init+0x290/0x290 [zfs]
[ 38.571005] [<ffffffffa04d63ea>] thread_generic_wrapper+0x7a/0x90 [spl]
[ 38.572160] [<ffffffffa04d6370>] ? __thread_exit+0xa0/0xa0 [spl]
[ 38.573168] [<ffffffff81073982>] kthread+0xd2/0xf0
[ 38.573965] [<ffffffff810738b0>] ? insert_kthread_work+0x40/0x40
[ 38.574970] [<ffffffff8148a1c4>] ret_from_fork+0x74/0xa0
[ 38.575913] [<ffffffff810738b0>] ? insert_kthread_work+0x40/0x40
The code in question seems to be:
- Code: Select all
5771 static void
5772 spa_sync_nvlist(spa_t *spa, uint64_t obj, nvlist_t *nv, dmu_tx_t *tx)
5773 {
5774 char *packed = NULL;
5775 size_t bufsize;
5776 size_t nvsize = 0;
5777 dmu_buf_t *db;
5778
5779 VERIFY(nvlist_size(nv, &nvsize, NV_ENCODE_XDR) == 0);
5780
5781 /*
5782 * Write full (SPA_CONFIG_BLOCKSIZE) blocks of configuration
5783 * information. This avoids the dbuf_will_dirty() path and
5784 * saves us a pre-read to get data we don't actually care about.
5785 */
5786 bufsize = P2ROUNDUP((uint64_t)nvsize, SPA_CONFIG_BLOCKSIZE);
5787 packed = vmem_alloc(bufsize, KM_PUSHPAGE);
5788
5789 VERIFY(nvlist_pack(nv, &packed, &nvsize, NV_ENCODE_XDR,
5790 KM_PUSHPAGE) == 0);
5791 bzero(packed + nvsize, bufsize - nvsize);
Specifically, the panic seems to indicate the error is in line 5787 (or around that point?).
SPA_CONFIG_BLOCKSIZE is defined to be 16384:
- Code: Select all
#define SPA_CONFIG_BLOCKSIZE (1ULL << 14)
The macro in line 5786 is defined as:
- Code: Select all
#define P2ROUNDUP(x, align)> (-(-(x) & -(align)))
(... and it's used in dozens of places all over the ZFS code).
Here's a disassembly of where *I think* is the problem:
- Code: Select all
4e901: 48 8b 4c 24 08 mov 0x8(%rsp),%rcx
4e906: 31 d2 xor %edx,%edx
4e908: 48 f7 d9 neg %rcx
4e90b: 48 81 e1 00 c0 ff ff and $0xffffffffffffc000,%rcx
4e912: 48 89 c8 mov %rcx,%rax
4e915: 48 f7 d8 neg %rax
4e918: 48 83 d2 00 adc $0x0,%rdx
4e91c: 48 89 c3 mov %rax,%rbx
4e91f: 48 f7 da neg %rdx
4e922: 48 89 d1 mov %rdx,%rcx
4e925: 48 09 c1 or %rax,%rcx
4e928: 0f 85 5b 01 00 00 jne 4ea89 <spa_sync_nvlist.isra.22+0x1d9>
...
4ea89: 48 c7 c1 00 00 00 00 mov $0x0,%rcx
4ea90: 48 c7 c2 00 00 00 00 mov $0x0,%rdx
4ea97: be 9b 16 00 00 mov $0x169b,%esi
4ea9c: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
4eaa3: e8 00 00 00 00 callq 4eaa8 <spa_sync_nvlist.isra.22+0x1f8>
4eaa8: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
4eaaf: 00
I think (but I'm not sure) the code in 4ea89..4eaa8 is a call to report_size_overflow().
Notice how the constant in 4e90b seems to be equal to -SPA_CONFIG_BLOCKSIZE.
How can I fix this, as a user?