-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
dmu: fix integer overflow in dmu_read #3333
Conversation
This looks good to me. |
There seemed to be similar overflows also in dmu_read_req(), dmu_write_req(), dmu_read_uio(), and dmu_write_uio_dnode(). |
Given that those values are offsets and sizes within a block it seems that using int is safe in practice. |
This cant be true. PaX's size overflow plugin uses double size and recalculates to compare if there is an overflow and only then triggers. and the numbers passed in when i hit it are bigger than a 32bit int. I hit it with a ZVOL tho so maybe for zvols its not limited to within a block? more about pax's size overflow is here: https://forums.grsecurity.net/viewtopic.php?f=7&t=3043 |
Treating these values all as 64-bit is definitely for the best since it makes everything explicit. @perfinion could you update this patch to made the same fix in dmu_write(), dmu_read_req(), dmu_write_req(), dmu_read_uio(), dmu_write_uio(), and dmu_write_uio_dnode() as @thegreatgazoo suggested. |
@behlendorf dmu_read() uses bcopy, all the other ones (dmu_write, dmu_read_req, dmu_req_copy etc) use memcopy. should I also swap dmu_read() to use memcopy to be consistent? |
Yes, consistently is good. And under the covers bcopy will map to memcpy anyway. |
The params to the functions are uint64_t, but the offsets to memcpy / bcopy are calculated using 32bit ints. This patch changes them to also be uint64_t so there isnt an overflow. PaX's Size Overflow caught this when formatting a zvol. Gentoo bug: #546490 PAX: offset: 1ffffb000 db->db_offset: 1ffffa000 db->db_size: 2000 size: 5000 PAX: size overflow detected in function dmu_read /var/tmp/portage/sys-fs/zfs-kmod-0.6.3-r1/work/zfs-zfs-0.6.3/module/zfs/../../module/zfs/dmu.c:781 cicus.366_146 max, count: 15 CPU: 1 PID: 2236 Comm: zvol/10 Tainted: P O 3.17.7-hardened-r1 openzfs#1 Call Trace: [<ffffffffa0382ee8>] ? dsl_dataset_get_holds+0x9d58/0x343ce [zfs] [<ffffffff81a59c88>] dump_stack+0x4e/0x7a [<ffffffffa0393c2a>] ? dsl_dataset_get_holds+0x1aa9a/0x343ce [zfs] [<ffffffff81206696>] report_size_overflow+0x36/0x40 [<ffffffffa02dba2b>] dmu_read+0x52b/0x920 [zfs] [<ffffffffa0373ad1>] zrl_is_locked+0x7d1/0x1ce0 [zfs] [<ffffffffa0364cd2>] zil_clean+0x9d2/0xc00 [zfs] [<ffffffffa0364f21>] zil_commit+0x21/0x30 [zfs] [<ffffffffa0373fe1>] zrl_is_locked+0xce1/0x1ce0 [zfs] [<ffffffff81a5e2c7>] ? __schedule+0x547/0xbc0 [<ffffffffa01582e6>] taskq_cancel_id+0x2a6/0x5b0 [spl] [<ffffffff81103eb0>] ? wake_up_state+0x20/0x20 [<ffffffffa0158150>] ? taskq_cancel_id+0x110/0x5b0 [spl] [<ffffffff810f7ff4>] kthread+0xc4/0xe0 [<ffffffff810f7f30>] ? kthread_create_on_node+0x170/0x170 [<ffffffff81a62fa4>] ret_from_fork+0x74/0xa0 [<ffffffff810f7f30>] ? kthread_create_on_node+0x170/0x170 Signed-off-by: Jason Zaman <[email protected]>
f328e60
to
7d0741b
Compare
I pushed a new version, can you take a look?
I booted this patch on my laptop and it builds and works. But I did not to any extensive testing other than the original dmu_read that i triggered. |
@perfinion thanks for fixing up the additional cases. This LGTM and the two test failures were for unrelated issues. I'll get this merged tomorrow to give @thegreatgazoo and @ryao a chance to comment. |
The params to the functions are uint64_t, but the offsets to memcpy / bcopy are calculated using 32bit ints. This patch changes them to also be uint64_t so there isnt an overflow. PaX's Size Overflow caught this when formatting a zvol. Gentoo bug: #546490 PAX: offset: 1ffffb000 db->db_offset: 1ffffa000 db->db_size: 2000 size: 5000 PAX: size overflow detected in function dmu_read /var/tmp/portage/sys-fs/zfs-kmod-0.6.3-r1/work/zfs-zfs-0.6.3/module/zfs/../../module/zfs/dmu.c:781 cicus.366_146 max, count: 15 CPU: 1 PID: 2236 Comm: zvol/10 Tainted: P O 3.17.7-hardened-r1 #1 Call Trace: [<ffffffffa0382ee8>] ? dsl_dataset_get_holds+0x9d58/0x343ce [zfs] [<ffffffff81a59c88>] dump_stack+0x4e/0x7a [<ffffffffa0393c2a>] ? dsl_dataset_get_holds+0x1aa9a/0x343ce [zfs] [<ffffffff81206696>] report_size_overflow+0x36/0x40 [<ffffffffa02dba2b>] dmu_read+0x52b/0x920 [zfs] [<ffffffffa0373ad1>] zrl_is_locked+0x7d1/0x1ce0 [zfs] [<ffffffffa0364cd2>] zil_clean+0x9d2/0xc00 [zfs] [<ffffffffa0364f21>] zil_commit+0x21/0x30 [zfs] [<ffffffffa0373fe1>] zrl_is_locked+0xce1/0x1ce0 [zfs] [<ffffffff81a5e2c7>] ? __schedule+0x547/0xbc0 [<ffffffffa01582e6>] taskq_cancel_id+0x2a6/0x5b0 [spl] [<ffffffff81103eb0>] ? wake_up_state+0x20/0x20 [<ffffffffa0158150>] ? taskq_cancel_id+0x110/0x5b0 [spl] [<ffffffff810f7ff4>] kthread+0xc4/0xe0 [<ffffffff810f7f30>] ? kthread_create_on_node+0x170/0x170 [<ffffffff81a62fa4>] ret_from_fork+0x74/0xa0 [<ffffffff810f7f30>] ? kthread_create_on_node+0x170/0x170 Signed-off-by: Jason Zaman <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Closes openzfs#3333
The params are uint64_t, but the offsets are calculated as 32bit ints.
PaX's Size Overflow catches this when formatting a zvol. This patch
changes them to also be uint64_t so there isnt an overflow.
Gentoo bug: #546490
PAX: offset: 1ffffb000 db->db_offset: 1ffffa000 db->db_size: 2000 size: 5000
PAX: size overflow detected in function dmu_read /var/tmp/portage/sys-fs/zfs-kmod-0.6.3-r1/work/zfs-zfs-0.6.3/module/zfs/../../module/zfs/dmu.c:781 cicus.366_146 max, count: 15
CPU: 1 PID: 2236 Comm: zvol/10 Tainted: P O 3.17.7-hardened-r1 #1
Call Trace:
[] ? dsl_dataset_get_holds+0x9d58/0x343ce [zfs]
[] dump_stack+0x4e/0x7a
[] ? dsl_dataset_get_holds+0x1aa9a/0x343ce [zfs]
[] report_size_overflow+0x36/0x40
[] dmu_read+0x52b/0x920 [zfs]
[] zrl_is_locked+0x7d1/0x1ce0 [zfs]
[] zil_clean+0x9d2/0xc00 [zfs]
[] zil_commit+0x21/0x30 [zfs]
[] zrl_is_locked+0xce1/0x1ce0 [zfs]
[] ? __schedule+0x547/0xbc0
[] taskq_cancel_id+0x2a6/0x5b0 [spl]
[] ? wake_up_state+0x20/0x20
[] ? taskq_cancel_id+0x110/0x5b0 [spl]
[] kthread+0xc4/0xe0
[] ? kthread_create_on_node+0x170/0x170
[] ret_from_fork+0x74/0xa0
[] ? kthread_create_on_node+0x170/0x170
Signed-off-by: Jason Zaman [email protected]
Reviewed-by: Emese Revfy [email protected]