1 | The following changes since commit 67c1115edd98f388ca89dd38322ea3fadf034523: | 1 | The following changes since commit fd87be1dada5672f877e03c2ca8504458292c479: |
---|---|---|---|
2 | 2 | ||
3 | Merge remote-tracking branch 'remotes/kraxel/tags/ui-20210323-pull-request' into staging (2021-03-23 23:47:30 +0000) | 3 | Merge tag 'accel-20240426' of https://github.com/philmd/qemu into staging (2024-04-26 15:28:13 -0700) |
4 | 4 | ||
5 | are available in the Git repository at: | 5 | are available in the Git repository at: |
6 | 6 | ||
7 | https://gitlab.com/stefanha/qemu.git tags/block-pull-request | 7 | https://gitlab.com/stefanha/qemu.git tags/block-pull-request |
8 | 8 | ||
9 | for you to fetch changes up to 3460fd7f3959d1fa7bcc255796844aa261c805a4: | 9 | for you to fetch changes up to d1c4580662bf75bf6875bb5e1ad446b300816ac7: |
10 | 10 | ||
11 | migrate-bitmaps-postcopy-test: check that we can't remove in-flight bitmaps (2021-03-24 13:41:19 +0000) | 11 | hw/ufs: Fix buffer overflow bug (2024-04-29 09:33:06 -0400) |
12 | 12 | ||
13 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
14 | Pull request | 14 | Pull request |
15 | 15 | ||
16 | This dirty bitmap fix solves a crash that can be triggered in the destination | 16 | Buffer overflow fix for Universal Flash Storage (UFS) emulation. |
17 | QEMU process during live migration. | ||
18 | 17 | ||
19 | ---------------------------------------------------------------- | 18 | ---------------------------------------------------------------- |
20 | 19 | ||
21 | Vladimir Sementsov-Ogievskiy (2): | 20 | Jeuk Kim (1): |
22 | migration/block-dirty-bitmap: make incoming disabled bitmaps busy | 21 | hw/ufs: Fix buffer overflow bug |
23 | migrate-bitmaps-postcopy-test: check that we can't remove in-flight | ||
24 | bitmaps | ||
25 | 22 | ||
26 | migration/block-dirty-bitmap.c | 6 ++++++ | 23 | hw/ufs/ufs.c | 8 ++++++++ |
27 | tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test | 10 ++++++++++ | 24 | 1 file changed, 8 insertions(+) |
28 | 2 files changed, 16 insertions(+) | ||
29 | 25 | ||
30 | -- | 26 | -- |
31 | 2.30.2 | 27 | 2.44.0 |
32 | diff view generated by jsdifflib |
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | 1 | From: Jeuk Kim <jeuk20.kim@samsung.com> |
---|---|---|---|
2 | 2 | ||
3 | Incoming enabled bitmaps are busy, because we do | 3 | It fixes the buffer overflow vulnerability in the ufs device. |
4 | bdrv_dirty_bitmap_create_successor() for them. But disabled bitmaps | 4 | The bug was detected by sanitizers. |
5 | being migrated are not marked busy, and user can remove them during the | ||
6 | incoming migration. Then we may crash in cancel_incoming_locked() when | ||
7 | try to remove the bitmap that was already removed by user, like this: | ||
8 | 5 | ||
9 | #0 qemu_mutex_lock_impl (mutex=0x5593d88c50d1, file=0x559680554b20 | 6 | You can reproduce it by: |
10 | "../block/dirty-bitmap.c", line=64) at ../util/qemu-thread-posix.c:77 | ||
11 | #1 bdrv_dirty_bitmaps_lock (bs=0x5593d88c0ee9) | ||
12 | at ../block/dirty-bitmap.c:64 | ||
13 | #2 bdrv_release_dirty_bitmap (bitmap=0x5596810e9570) | ||
14 | at ../block/dirty-bitmap.c:362 | ||
15 | #3 cancel_incoming_locked (s=0x559680be8208 <dbm_state+40>) | ||
16 | at ../migration/block-dirty-bitmap.c:918 | ||
17 | #4 dirty_bitmap_load (f=0x559681d02b10, opaque=0x559680be81e0 | ||
18 | <dbm_state>, version_id=1) at ../migration/block-dirty-bitmap.c:1194 | ||
19 | #5 vmstate_load (f=0x559681d02b10, se=0x559680fb5810) | ||
20 | at ../migration/savevm.c:908 | ||
21 | #6 qemu_loadvm_section_part_end (f=0x559681d02b10, | ||
22 | mis=0x559680fb4a30) at ../migration/savevm.c:2473 | ||
23 | #7 qemu_loadvm_state_main (f=0x559681d02b10, mis=0x559680fb4a30) | ||
24 | at ../migration/savevm.c:2626 | ||
25 | #8 postcopy_ram_listen_thread (opaque=0x0) | ||
26 | at ../migration/savevm.c:1871 | ||
27 | #9 qemu_thread_start (args=0x5596817ccd10) | ||
28 | at ../util/qemu-thread-posix.c:521 | ||
29 | #10 start_thread () at /lib64/libpthread.so.0 | ||
30 | #11 clone () at /lib64/libc.so.6 | ||
31 | 7 | ||
32 | Note bs pointer taken from bitmap: it's definitely bad aligned. That's | 8 | cat << EOF |\ |
33 | because we are in use after free, bitmap is already freed. | 9 | qemu-system-x86_64 \ |
10 | -display none -machine accel=qtest -m 512M -M q35 -nodefaults -drive \ | ||
11 | file=null-co://,if=none,id=disk0 -device ufs,id=ufs_bus -device \ | ||
12 | ufs-lu,drive=disk0,bus=ufs_bus -qtest stdio | ||
13 | outl 0xcf8 0x80000810 | ||
14 | outl 0xcfc 0xe0000000 | ||
15 | outl 0xcf8 0x80000804 | ||
16 | outw 0xcfc 0x06 | ||
17 | write 0xe0000058 0x1 0xa7 | ||
18 | write 0xa 0x1 0x50 | ||
19 | EOF | ||
34 | 20 | ||
35 | So, let's make disabled bitmaps (being migrated) busy during incoming | 21 | Resolves: #2299 |
36 | migration. | 22 | Fixes: 329f16624499 ("hw/ufs: Support for Query Transfer Requests") |
23 | Reported-by: Zheyu Ma <zheyuma97@gmail.com> | ||
24 | Signed-off-by: Jeuk Kim <jeuk20.kim@samsung.com> | ||
25 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
26 | Message-ID: <f2c8aeb1afefcda92054c448b21fc59cdd99db30.1714360640.git.jeuk20.kim@samsung.com> | ||
27 | --- | ||
28 | hw/ufs/ufs.c | 8 ++++++++ | ||
29 | 1 file changed, 8 insertions(+) | ||
37 | 30 | ||
38 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | 31 | diff --git a/hw/ufs/ufs.c b/hw/ufs/ufs.c |
39 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
40 | Message-Id: <20210322094906.5079-2-vsementsov@virtuozzo.com> | ||
41 | --- | ||
42 | migration/block-dirty-bitmap.c | 6 ++++++ | ||
43 | 1 file changed, 6 insertions(+) | ||
44 | |||
45 | diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c | ||
46 | index XXXXXXX..XXXXXXX 100644 | 32 | index XXXXXXX..XXXXXXX 100644 |
47 | --- a/migration/block-dirty-bitmap.c | 33 | --- a/hw/ufs/ufs.c |
48 | +++ b/migration/block-dirty-bitmap.c | 34 | +++ b/hw/ufs/ufs.c |
49 | @@ -XXX,XX +XXX,XX @@ static int dirty_bitmap_load_start(QEMUFile *f, DBMLoadState *s) | 35 | @@ -XXX,XX +XXX,XX @@ static MemTxResult ufs_dma_read_req_upiu(UfsRequest *req) |
50 | error_report_err(local_err); | 36 | copy_size = sizeof(UtpUpiuHeader) + UFS_TRANSACTION_SPECIFIC_FIELD_SIZE + |
51 | return -EINVAL; | 37 | data_segment_length; |
52 | } | 38 | |
53 | + } else { | 39 | + if (copy_size > sizeof(req->req_upiu)) { |
54 | + bdrv_dirty_bitmap_set_busy(s->bitmap, true); | 40 | + copy_size = sizeof(req->req_upiu); |
41 | + } | ||
42 | + | ||
43 | ret = ufs_addr_read(u, req_upiu_base_addr, &req->req_upiu, copy_size); | ||
44 | if (ret) { | ||
45 | trace_ufs_err_dma_read_req_upiu(req->slot, req_upiu_base_addr); | ||
46 | @@ -XXX,XX +XXX,XX @@ static MemTxResult ufs_dma_write_rsp_upiu(UfsRequest *req) | ||
47 | copy_size = rsp_upiu_byte_len; | ||
55 | } | 48 | } |
56 | 49 | ||
57 | b = g_new(LoadBitmapState, 1); | 50 | + if (copy_size > sizeof(req->rsp_upiu)) { |
58 | @@ -XXX,XX +XXX,XX @@ static void cancel_incoming_locked(DBMLoadState *s) | 51 | + copy_size = sizeof(req->rsp_upiu); |
59 | assert(!s->before_vm_start_handled || !b->migrated); | 52 | + } |
60 | if (bdrv_dirty_bitmap_has_successor(b->bitmap)) { | 53 | + |
61 | bdrv_reclaim_dirty_bitmap(b->bitmap, &error_abort); | 54 | ret = ufs_addr_write(u, rsp_upiu_base_addr, &req->rsp_upiu, copy_size); |
62 | + } else { | 55 | if (ret) { |
63 | + bdrv_dirty_bitmap_set_busy(b->bitmap, false); | 56 | trace_ufs_err_dma_write_rsp_upiu(req->slot, rsp_upiu_base_addr); |
64 | } | ||
65 | bdrv_release_dirty_bitmap(b->bitmap); | ||
66 | } | ||
67 | @@ -XXX,XX +XXX,XX @@ static void dirty_bitmap_load_complete(QEMUFile *f, DBMLoadState *s) | ||
68 | |||
69 | if (bdrv_dirty_bitmap_has_successor(s->bitmap)) { | ||
70 | bdrv_reclaim_dirty_bitmap(s->bitmap, &error_abort); | ||
71 | + } else { | ||
72 | + bdrv_dirty_bitmap_set_busy(s->bitmap, false); | ||
73 | } | ||
74 | |||
75 | for (item = s->bitmaps; item; item = g_slist_next(item)) { | ||
76 | -- | 57 | -- |
77 | 2.30.2 | 58 | 2.44.0 |
78 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | Check that we can't remove bitmaps being migrated on destination vm. | ||
4 | The new check proves that previous commit helps. | ||
5 | |||
6 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
7 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
8 | Message-Id: <20210322094906.5079-3-vsementsov@virtuozzo.com> | ||
9 | --- | ||
10 | tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test | 10 ++++++++++ | ||
11 | 1 file changed, 10 insertions(+) | ||
12 | |||
13 | diff --git a/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test b/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test | ||
14 | index XXXXXXX..XXXXXXX 100755 | ||
15 | --- a/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test | ||
16 | +++ b/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test | ||
17 | @@ -XXX,XX +XXX,XX @@ class TestDirtyBitmapPostcopyMigration(iotests.QMPTestCase): | ||
18 | self.start_postcopy() | ||
19 | |||
20 | self.vm_b_events += self.vm_b.get_qmp_events() | ||
21 | + | ||
22 | + # While being here, let's check that we can't remove in-flight bitmaps. | ||
23 | + for vm in (self.vm_a, self.vm_b): | ||
24 | + for i in range(0, nb_bitmaps): | ||
25 | + result = vm.qmp('block-dirty-bitmap-remove', node='drive0', | ||
26 | + name=f'bitmap{i}') | ||
27 | + self.assert_qmp(result, 'error/desc', | ||
28 | + f"Bitmap 'bitmap{i}' is currently in use by " | ||
29 | + "another operation and cannot be used") | ||
30 | + | ||
31 | self.vm_b.shutdown() | ||
32 | # recreate vm_b, so there is no incoming option, which prevents | ||
33 | # loading bitmaps from disk | ||
34 | -- | ||
35 | 2.30.2 | ||
36 | diff view generated by jsdifflib |