Merge branch 'c9' into a9
This commit is contained in:
		
						commit
						2c29d3c60d
					
				| @ -0,0 +1,260 @@ | ||||
| From 5c35b7d631e9cdf75512b9e1a0b5d48e8fd768d9 Mon Sep 17 00:00:00 2001 | ||||
| From: Jon Maloy <jmaloy@redhat.com> | ||||
| Date: Wed, 5 Jun 2024 19:56:51 -0400 | ||||
| Subject: [PATCH 4/4] block: Parse filenames only when explicitly requested | ||||
| 
 | ||||
| RH-Author: Jon Maloy <jmaloy@redhat.com> | ||||
| RH-MergeRequest: 2: EMBARGOED CVE-2024-4467 for rhel-9.4.z (PRDSC) | ||||
| RH-Jira: https://issues.redhat.com/browse/RHEL-35610 | ||||
| RH-CVE: CVE-2024-4467 | ||||
| RH-Acked-by: Kevin Wolf <kwolf@redhat.com> | ||||
| RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com> | ||||
| RH-Acked-by: Hanna Czenczek <hczenczek@redhat.com> | ||||
| RH-Commit: [4/4] 6f71e6a07bd5a9f8352db920f498f5fa5a2cdbfb | ||||
| 
 | ||||
| commit f44c2941d4419e60f16dea3e9adca164e75aa78d (origin/cve-2024-4467-hreitz-rhel-9.5.0) | ||||
| Author: Kevin Wolf <kwolf@redhat.com> | ||||
| Date:   Thu Apr 25 14:56:02 2024 +0200 | ||||
| 
 | ||||
|     block: Parse filenames only when explicitly requested | ||||
| 
 | ||||
|     When handling image filenames from legacy options such as -drive or from | ||||
|     tools, these filenames are parsed for protocol prefixes, including for | ||||
|     the json:{} pseudo-protocol. | ||||
| 
 | ||||
|     This behaviour is intended for filenames that come directly from the | ||||
|     command line and for backing files, which may come from the image file | ||||
|     itself. Higher level management tools generally take care to verify that | ||||
|     untrusted images don't contain a bad (or any) backing file reference; | ||||
|     'qemu-img info' is a suitable tool for this. | ||||
| 
 | ||||
|     However, for other files that can be referenced in images, such as | ||||
|     qcow2 data files or VMDK extents, the string from the image file is | ||||
|     usually not verified by management tools - and 'qemu-img info' wouldn't | ||||
|     be suitable because in contrast to backing files, it already opens these | ||||
|     other referenced files. So here the string should be interpreted as a | ||||
|     literal local filename. More complex configurations need to be specified | ||||
|     explicitly on the command line or in QMP. | ||||
| 
 | ||||
|     This patch changes bdrv_open_inherit() so that it only parses filenames | ||||
|     if a new parameter parse_filename is true. It is set for the top level | ||||
|     in bdrv_open(), for the file child and for the backing file child. All | ||||
|     other callers pass false and disable filename parsing this way. | ||||
| 
 | ||||
|     Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||||
|     Reviewed-by: Eric Blake <eblake@redhat.com> | ||||
|     Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||||
|     Reviewed-by: Hanna Czenczek <hreitz@redhat.com> | ||||
|     Upstream: N/A, embargoed | ||||
|     Signed-off-by: Hanna Czenczek <hreitz@redhat.com> | ||||
| 
 | ||||
| Signed-off-by: Jon Maloy <jmaloy@redhat.com> | ||||
| ---
 | ||||
|  block.c | 90 ++++++++++++++++++++++++++++++++++++--------------------- | ||||
|  1 file changed, 57 insertions(+), 33 deletions(-) | ||||
| 
 | ||||
| diff --git a/block.c b/block.c
 | ||||
| index a097772238..8b6aa4a65c 100644
 | ||||
| --- a/block.c
 | ||||
| +++ b/block.c
 | ||||
| @@ -86,6 +86,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
 | ||||
|                                             BlockDriverState *parent, | ||||
|                                             const BdrvChildClass *child_class, | ||||
|                                             BdrvChildRole child_role, | ||||
| +                                           bool parse_filename,
 | ||||
|                                             Error **errp); | ||||
|   | ||||
|  static bool bdrv_recurse_has_child(BlockDriverState *bs, | ||||
| @@ -2035,7 +2036,8 @@ static void parse_json_protocol(QDict *options, const char **pfilename,
 | ||||
|   * block driver has been specified explicitly. | ||||
|   */ | ||||
|  static int bdrv_fill_options(QDict **options, const char *filename, | ||||
| -                             int *flags, Error **errp)
 | ||||
| +                             int *flags, bool allow_parse_filename,
 | ||||
| +                             Error **errp)
 | ||||
|  { | ||||
|      const char *drvname; | ||||
|      bool protocol = *flags & BDRV_O_PROTOCOL; | ||||
| @@ -2077,7 +2079,7 @@ static int bdrv_fill_options(QDict **options, const char *filename,
 | ||||
|      if (protocol && filename) { | ||||
|          if (!qdict_haskey(*options, "filename")) { | ||||
|              qdict_put_str(*options, "filename", filename); | ||||
| -            parse_filename = true;
 | ||||
| +            parse_filename = allow_parse_filename;
 | ||||
|          } else { | ||||
|              error_setg(errp, "Can't specify 'file' and 'filename' options at " | ||||
|                               "the same time"); | ||||
| @@ -3639,7 +3641,8 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
 | ||||
|      } | ||||
|   | ||||
|      backing_hd = bdrv_open_inherit(backing_filename, reference, options, 0, bs, | ||||
| -                                   &child_of_bds, bdrv_backing_role(bs), errp);
 | ||||
| +                                   &child_of_bds, bdrv_backing_role(bs), true,
 | ||||
| +                                   errp);
 | ||||
|      if (!backing_hd) { | ||||
|          bs->open_flags |= BDRV_O_NO_BACKING; | ||||
|          error_prepend(errp, "Could not open backing file: "); | ||||
| @@ -3673,7 +3676,8 @@ free_exit:
 | ||||
|  static BlockDriverState * | ||||
|  bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key, | ||||
|                     BlockDriverState *parent, const BdrvChildClass *child_class, | ||||
| -                   BdrvChildRole child_role, bool allow_none, Error **errp)
 | ||||
| +                   BdrvChildRole child_role, bool allow_none,
 | ||||
| +                   bool parse_filename, Error **errp)
 | ||||
|  { | ||||
|      BlockDriverState *bs = NULL; | ||||
|      QDict *image_options; | ||||
| @@ -3704,7 +3708,8 @@ bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key,
 | ||||
|      } | ||||
|   | ||||
|      bs = bdrv_open_inherit(filename, reference, image_options, 0, | ||||
| -                           parent, child_class, child_role, errp);
 | ||||
| +                           parent, child_class, child_role, parse_filename,
 | ||||
| +                           errp);
 | ||||
|      if (!bs) { | ||||
|          goto done; | ||||
|      } | ||||
| @@ -3714,6 +3719,33 @@ done:
 | ||||
|      return bs; | ||||
|  } | ||||
|   | ||||
| +static BdrvChild *bdrv_open_child_common(const char *filename,
 | ||||
| +                                         QDict *options, const char *bdref_key,
 | ||||
| +                                         BlockDriverState *parent,
 | ||||
| +                                         const BdrvChildClass *child_class,
 | ||||
| +                                         BdrvChildRole child_role,
 | ||||
| +                                         bool allow_none, bool parse_filename,
 | ||||
| +                                         Error **errp)
 | ||||
| +{
 | ||||
| +    BlockDriverState *bs;
 | ||||
| +    BdrvChild *child;
 | ||||
| +
 | ||||
| +    GLOBAL_STATE_CODE();
 | ||||
| +
 | ||||
| +    bs = bdrv_open_child_bs(filename, options, bdref_key, parent, child_class,
 | ||||
| +                            child_role, allow_none, parse_filename, errp);
 | ||||
| +    if (bs == NULL) {
 | ||||
| +        return NULL;
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    bdrv_graph_wrlock();
 | ||||
| +    child = bdrv_attach_child(parent, bs, bdref_key, child_class, child_role,
 | ||||
| +                              errp);
 | ||||
| +    bdrv_graph_wrunlock();
 | ||||
| +
 | ||||
| +    return child;
 | ||||
| +}
 | ||||
| +
 | ||||
|  /* | ||||
|   * Opens a disk image whose options are given as BlockdevRef in another block | ||||
|   * device's options. | ||||
| @@ -3737,27 +3769,15 @@ BdrvChild *bdrv_open_child(const char *filename,
 | ||||
|                             BdrvChildRole child_role, | ||||
|                             bool allow_none, Error **errp) | ||||
|  { | ||||
| -    BlockDriverState *bs;
 | ||||
| -    BdrvChild *child;
 | ||||
| -
 | ||||
| -    GLOBAL_STATE_CODE();
 | ||||
| -
 | ||||
| -    bs = bdrv_open_child_bs(filename, options, bdref_key, parent, child_class,
 | ||||
| -                            child_role, allow_none, errp);
 | ||||
| -    if (bs == NULL) {
 | ||||
| -        return NULL;
 | ||||
| -    }
 | ||||
| -
 | ||||
| -    bdrv_graph_wrlock();
 | ||||
| -    child = bdrv_attach_child(parent, bs, bdref_key, child_class, child_role,
 | ||||
| -                              errp);
 | ||||
| -    bdrv_graph_wrunlock();
 | ||||
| -
 | ||||
| -    return child;
 | ||||
| +    return bdrv_open_child_common(filename, options, bdref_key, parent,
 | ||||
| +                                  child_class, child_role, allow_none, false,
 | ||||
| +                                  errp);
 | ||||
|  } | ||||
|   | ||||
|  /* | ||||
| - * Wrapper on bdrv_open_child() for most popular case: open primary child of bs.
 | ||||
| + * This does mostly the same as bdrv_open_child(), but for opening the primary
 | ||||
| + * child of a node. A notable difference from bdrv_open_child() is that it
 | ||||
| + * enables filename parsing for protocol names (including json:).
 | ||||
|   * | ||||
|   * @parent can move to a different AioContext in this function. | ||||
|   */ | ||||
| @@ -3772,8 +3792,8 @@ int bdrv_open_file_child(const char *filename,
 | ||||
|      role = parent->drv->is_filter ? | ||||
|          (BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY) : BDRV_CHILD_IMAGE; | ||||
|   | ||||
| -    if (!bdrv_open_child(filename, options, bdref_key, parent,
 | ||||
| -                         &child_of_bds, role, false, errp))
 | ||||
| +    if (!bdrv_open_child_common(filename, options, bdref_key, parent,
 | ||||
| +                                &child_of_bds, role, false, true, errp))
 | ||||
|      { | ||||
|          return -EINVAL; | ||||
|      } | ||||
| @@ -3818,7 +3838,8 @@ BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp)
 | ||||
|   | ||||
|      } | ||||
|   | ||||
| -    bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, 0, errp);
 | ||||
| +    bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, 0, false,
 | ||||
| +                           errp);
 | ||||
|      obj = NULL; | ||||
|      qobject_unref(obj); | ||||
|      visit_free(v); | ||||
| @@ -3907,7 +3928,7 @@ static BlockDriverState * no_coroutine_fn
 | ||||
|  bdrv_open_inherit(const char *filename, const char *reference, QDict *options, | ||||
|                    int flags, BlockDriverState *parent, | ||||
|                    const BdrvChildClass *child_class, BdrvChildRole child_role, | ||||
| -                  Error **errp)
 | ||||
| +                  bool parse_filename, Error **errp)
 | ||||
|  { | ||||
|      int ret; | ||||
|      BlockBackend *file = NULL; | ||||
| @@ -3955,9 +3976,11 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
 | ||||
|      } | ||||
|   | ||||
|      /* json: syntax counts as explicit options, as if in the QDict */ | ||||
| -    parse_json_protocol(options, &filename, &local_err);
 | ||||
| -    if (local_err) {
 | ||||
| -        goto fail;
 | ||||
| +    if (parse_filename) {
 | ||||
| +        parse_json_protocol(options, &filename, &local_err);
 | ||||
| +        if (local_err) {
 | ||||
| +            goto fail;
 | ||||
| +        }
 | ||||
|      } | ||||
|   | ||||
|      bs->explicit_options = qdict_clone_shallow(options); | ||||
| @@ -3982,7 +4005,8 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
 | ||||
|                                       parent->open_flags, parent->options); | ||||
|      } | ||||
|   | ||||
| -    ret = bdrv_fill_options(&options, filename, &flags, &local_err);
 | ||||
| +    ret = bdrv_fill_options(&options, filename, &flags, parse_filename,
 | ||||
| +                            &local_err);
 | ||||
|      if (ret < 0) { | ||||
|          goto fail; | ||||
|      } | ||||
| @@ -4051,7 +4075,7 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
 | ||||
|   | ||||
|          file_bs = bdrv_open_child_bs(filename, options, "file", bs, | ||||
|                                       &child_of_bds, BDRV_CHILD_IMAGE, | ||||
| -                                     true, &local_err);
 | ||||
| +                                     true, true, &local_err);
 | ||||
|          if (local_err) { | ||||
|              goto fail; | ||||
|          } | ||||
| @@ -4200,7 +4224,7 @@ BlockDriverState *bdrv_open(const char *filename, const char *reference,
 | ||||
|      GLOBAL_STATE_CODE(); | ||||
|   | ||||
|      return bdrv_open_inherit(filename, reference, options, flags, NULL, | ||||
| -                             NULL, 0, errp);
 | ||||
| +                             NULL, 0, true, errp);
 | ||||
|  } | ||||
|   | ||||
|  /* Return true if the NULL-terminated @list contains @str */ | ||||
| -- 
 | ||||
| 2.39.3 | ||||
| 
 | ||||
| @ -0,0 +1,69 @@ | ||||
| From c2eafeb32a256cbafb0e65c0380acb478181326e Mon Sep 17 00:00:00 2001 | ||||
| From: Jon Maloy <jmaloy@redhat.com> | ||||
| Date: Wed, 5 Jun 2024 19:56:51 -0400 | ||||
| Subject: [PATCH 2/4] iotests/244: Don't store data-file with protocol in image | ||||
| 
 | ||||
| RH-Author: Jon Maloy <jmaloy@redhat.com> | ||||
| RH-MergeRequest: 2: EMBARGOED CVE-2024-4467 for rhel-9.4.z (PRDSC) | ||||
| RH-Jira: https://issues.redhat.com/browse/RHEL-35610 | ||||
| RH-CVE: CVE-2024-4467 | ||||
| RH-Acked-by: Kevin Wolf <kwolf@redhat.com> | ||||
| RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com> | ||||
| RH-Acked-by: Hanna Czenczek <hczenczek@redhat.com> | ||||
| RH-Commit: [2/4] ddef095945aa55bb0aacc2a2cb58f9e12ad20d5e | ||||
| 
 | ||||
| commit 92e00dab8be1570b13172353d77d2af44cb4e22b | ||||
| Author: Kevin Wolf <kwolf@redhat.com> | ||||
| Date:   Thu Apr 25 14:49:40 2024 +0200 | ||||
| 
 | ||||
|     iotests/244: Don't store data-file with protocol in image | ||||
| 
 | ||||
|     We want to disable filename parsing for data files because it's too easy | ||||
|     to abuse in malicious image files. Make the test ready for the change by | ||||
|     passing the data file explicitly in command line options. | ||||
| 
 | ||||
|     Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||||
|     Reviewed-by: Eric Blake <eblake@redhat.com> | ||||
|     Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||||
|     Reviewed-by: Hanna Czenczek <hreitz@redhat.com> | ||||
|     Upstream: N/A, embargoed | ||||
|     Signed-off-by: Hanna Czenczek <hreitz@redhat.com> | ||||
| 
 | ||||
| Signed-off-by: Jon Maloy <jmaloy@redhat.com> | ||||
| ---
 | ||||
|  tests/qemu-iotests/244 | 19 ++++++++++++++++--- | ||||
|  1 file changed, 16 insertions(+), 3 deletions(-) | ||||
| 
 | ||||
| diff --git a/tests/qemu-iotests/244 b/tests/qemu-iotests/244
 | ||||
| index 3e61fa25bb..bb9cc6512f 100755
 | ||||
| --- a/tests/qemu-iotests/244
 | ||||
| +++ b/tests/qemu-iotests/244
 | ||||
| @@ -215,9 +215,22 @@ $QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n -C "$TEST_IMG.src" "$TEST_IMG"
 | ||||
|  $QEMU_IMG compare -f $IMGFMT -F $IMGFMT "$TEST_IMG.src" "$TEST_IMG" | ||||
|   | ||||
|  # blkdebug doesn't support copy offloading, so this tests the error path | ||||
| -$QEMU_IMG amend -f $IMGFMT -o "data_file=blkdebug::$TEST_IMG.data" "$TEST_IMG"
 | ||||
| -$QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n -C "$TEST_IMG.src" "$TEST_IMG"
 | ||||
| -$QEMU_IMG compare -f $IMGFMT -F $IMGFMT "$TEST_IMG.src" "$TEST_IMG"
 | ||||
| +test_img_with_blkdebug="json:{
 | ||||
| +    'driver': 'qcow2',
 | ||||
| +    'file': {
 | ||||
| +        'driver': 'file',
 | ||||
| +        'filename': '$TEST_IMG'
 | ||||
| +    },
 | ||||
| +    'data-file': {
 | ||||
| +        'driver': 'blkdebug',
 | ||||
| +        'image': {
 | ||||
| +            'driver': 'file',
 | ||||
| +            'filename': '$TEST_IMG.data'
 | ||||
| +        }
 | ||||
| +    }
 | ||||
| +}"
 | ||||
| +$QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n -C "$TEST_IMG.src" "$test_img_with_blkdebug"
 | ||||
| +$QEMU_IMG compare -f $IMGFMT -F $IMGFMT "$TEST_IMG.src" "$test_img_with_blkdebug"
 | ||||
|   | ||||
|  echo | ||||
|  echo "=== Flushing should flush the data file ===" | ||||
| -- 
 | ||||
| 2.39.3 | ||||
| 
 | ||||
| @ -0,0 +1,72 @@ | ||||
| From 931ab59f39b5e3551b328fe5b0f872df7a19ba05 Mon Sep 17 00:00:00 2001 | ||||
| From: Jon Maloy <jmaloy@redhat.com> | ||||
| Date: Wed, 5 Jun 2024 19:56:51 -0400 | ||||
| Subject: [PATCH 3/4] iotests/270: Don't store data-file with json: prefix in | ||||
|  image | ||||
| 
 | ||||
| RH-Author: Jon Maloy <jmaloy@redhat.com> | ||||
| RH-MergeRequest: 2: EMBARGOED CVE-2024-4467 for rhel-9.4.z (PRDSC) | ||||
| RH-Jira: https://issues.redhat.com/browse/RHEL-35610 | ||||
| RH-CVE: CVE-2024-4467 | ||||
| RH-Acked-by: Kevin Wolf <kwolf@redhat.com> | ||||
| RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com> | ||||
| RH-Acked-by: Hanna Czenczek <hczenczek@redhat.com> | ||||
| RH-Commit: [3/4] 7a9844fd48e3f3c4d1711ea4fb671c795ca4a1c1 | ||||
| 
 | ||||
| commit 705bcc2819ce8e0f8b9d660a93bc48de26413aec | ||||
| Author: Kevin Wolf <kwolf@redhat.com> | ||||
| Date:   Thu Apr 25 14:49:40 2024 +0200 | ||||
| 
 | ||||
|     iotests/270: Don't store data-file with json: prefix in image | ||||
| 
 | ||||
|     We want to disable filename parsing for data files because it's too easy | ||||
|     to abuse in malicious image files. Make the test ready for the change by | ||||
|     passing the data file explicitly in command line options. | ||||
| 
 | ||||
|     Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||||
|     Reviewed-by: Eric Blake <eblake@redhat.com> | ||||
|     Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||||
|     Reviewed-by: Hanna Czenczek <hreitz@redhat.com> | ||||
|     Upstream: N/A, embargoed | ||||
|     Signed-off-by: Hanna Czenczek <hreitz@redhat.com> | ||||
| 
 | ||||
| Signed-off-by: Jon Maloy <jmaloy@redhat.com> | ||||
| ---
 | ||||
|  tests/qemu-iotests/270 | 14 +++++++++++--- | ||||
|  1 file changed, 11 insertions(+), 3 deletions(-) | ||||
| 
 | ||||
| diff --git a/tests/qemu-iotests/270 b/tests/qemu-iotests/270
 | ||||
| index 74352342db..c37b674aa2 100755
 | ||||
| --- a/tests/qemu-iotests/270
 | ||||
| +++ b/tests/qemu-iotests/270
 | ||||
| @@ -60,8 +60,16 @@ _make_test_img -o cluster_size=2M,data_file="$TEST_IMG.orig" \
 | ||||
|  # "write" 2G of data without using any space. | ||||
|  # (qemu-img create does not like it, though, because null-co does not | ||||
|  # support image creation.) | ||||
| -$QEMU_IMG amend -o data_file="json:{'driver':'null-co',,'size':'4294967296'}" \
 | ||||
| -    "$TEST_IMG"
 | ||||
| +test_img_with_null_data="json:{
 | ||||
| +    'driver': '$IMGFMT',
 | ||||
| +    'file': {
 | ||||
| +        'filename': '$TEST_IMG'
 | ||||
| +    },
 | ||||
| +    'data-file': {
 | ||||
| +        'driver': 'null-co',
 | ||||
| +        'size':'4294967296'
 | ||||
| +    }
 | ||||
| +}"
 | ||||
|   | ||||
|  # This gives us a range of: | ||||
|  #   2^31 - 512 + 768 - 1 = 2^31 + 255 > 2^31 | ||||
| @@ -74,7 +82,7 @@ $QEMU_IMG amend -o data_file="json:{'driver':'null-co',,'size':'4294967296'}" \
 | ||||
|  # on L2 boundaries, we need large L2 tables; hence the cluster size of | ||||
|  # 2 MB.  (Anything from 256 kB should work, though, because then one L2 | ||||
|  # table covers 8 GB.) | ||||
| -$QEMU_IO -c "write 768 $((2 ** 31 - 512))" "$TEST_IMG" | _filter_qemu_io
 | ||||
| +$QEMU_IO -c "write 768 $((2 ** 31 - 512))" "$test_img_with_null_data" | _filter_qemu_io
 | ||||
|   | ||||
|  _check_test_img | ||||
|   | ||||
| -- 
 | ||||
| 2.39.3 | ||||
| 
 | ||||
							
								
								
									
										275
									
								
								SOURCES/kvm-iotests-test-NBD-TLS-iothread.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										275
									
								
								SOURCES/kvm-iotests-test-NBD-TLS-iothread.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,275 @@ | ||||
| From 4296c41178438f9dffa16c538b0c1a2e28944f4c Mon Sep 17 00:00:00 2001 | ||||
| From: Eric Blake <eblake@redhat.com> | ||||
| Date: Fri, 17 May 2024 21:50:15 -0500 | ||||
| Subject: [PATCH 4/4] iotests: test NBD+TLS+iothread | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
| 
 | ||||
| RH-Author: Eric Blake <eblake@redhat.com> | ||||
| RH-MergeRequest: 375: Fix regression on nbd+tls | ||||
| RH-Jira: RHEL-33754 | ||||
| RH-Acked-by: Kevin Wolf <kwolf@redhat.com> | ||||
| RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com> | ||||
| RH-Commit: [4/4] 5905c09466f4e65f3ff9973b41f42cbe1d75363c (ebblake/qemu-kvm) | ||||
| 
 | ||||
| Prevent regressions when using NBD with TLS in the presence of | ||||
| iothreads, adding coverage the fix to qio channels made in the | ||||
| previous patch. | ||||
| 
 | ||||
| The shell function pick_unused_port() was copied from | ||||
| nbdkit.git/tests/functions.sh.in, where it had all authors from Red | ||||
| Hat, agreeing to the resulting relicensing from 2-clause BSD to GPLv2. | ||||
| 
 | ||||
| CC: qemu-stable@nongnu.org | ||||
| CC: "Richard W.M. Jones" <rjones@redhat.com> | ||||
| Signed-off-by: Eric Blake <eblake@redhat.com> | ||||
| Message-ID: <20240531180639.1392905-6-eblake@redhat.com> | ||||
| Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> | ||||
| (cherry picked from commit a73c99378022ebb785481e84cfe1e81097546268) | ||||
| Jira: https://issues.redhat.com/browse/RHEL-33754 | ||||
| Signed-off-by: Eric Blake <eblake@redhat.com> | ||||
| ---
 | ||||
|  tests/qemu-iotests/tests/nbd-tls-iothread     | 168 ++++++++++++++++++ | ||||
|  tests/qemu-iotests/tests/nbd-tls-iothread.out |  54 ++++++ | ||||
|  2 files changed, 222 insertions(+) | ||||
|  create mode 100755 tests/qemu-iotests/tests/nbd-tls-iothread | ||||
|  create mode 100644 tests/qemu-iotests/tests/nbd-tls-iothread.out | ||||
| 
 | ||||
| diff --git a/tests/qemu-iotests/tests/nbd-tls-iothread b/tests/qemu-iotests/tests/nbd-tls-iothread
 | ||||
| new file mode 100755 | ||||
| index 0000000000..a2fb07206e
 | ||||
| --- /dev/null
 | ||||
| +++ b/tests/qemu-iotests/tests/nbd-tls-iothread
 | ||||
| @@ -0,0 +1,168 @@
 | ||||
| +#!/usr/bin/env bash
 | ||||
| +# group: rw quick
 | ||||
| +#
 | ||||
| +# Test of NBD+TLS+iothread
 | ||||
| +#
 | ||||
| +# Copyright (C) 2024 Red Hat, Inc.
 | ||||
| +#
 | ||||
| +# This program is free software; you can redistribute it and/or modify
 | ||||
| +# it under the terms of the GNU General Public License as published by
 | ||||
| +# the Free Software Foundation; either version 2 of the License, or
 | ||||
| +# (at your option) any later version.
 | ||||
| +#
 | ||||
| +# This program is distributed in the hope that it will be useful,
 | ||||
| +# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | ||||
| +# GNU General Public License for more details.
 | ||||
| +#
 | ||||
| +# You should have received a copy of the GNU General Public License
 | ||||
| +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
| +#
 | ||||
| +
 | ||||
| +# creator
 | ||||
| +owner=eblake@redhat.com
 | ||||
| +
 | ||||
| +seq=`basename $0`
 | ||||
| +echo "QA output created by $seq"
 | ||||
| +
 | ||||
| +status=1    # failure is the default!
 | ||||
| +
 | ||||
| +_cleanup()
 | ||||
| +{
 | ||||
| +    _cleanup_qemu
 | ||||
| +    _cleanup_test_img
 | ||||
| +    rm -f "$dst_image"
 | ||||
| +    tls_x509_cleanup
 | ||||
| +}
 | ||||
| +trap "_cleanup; exit \$status" 0 1 2 3 15
 | ||||
| +
 | ||||
| +# get standard environment, filters and checks
 | ||||
| +cd ..
 | ||||
| +. ./common.rc
 | ||||
| +. ./common.filter
 | ||||
| +. ./common.qemu
 | ||||
| +. ./common.tls
 | ||||
| +. ./common.nbd
 | ||||
| +
 | ||||
| +_supported_fmt qcow2  # Hardcoded to qcow2 command line and QMP below
 | ||||
| +_supported_proto file
 | ||||
| +
 | ||||
| +# pick_unused_port
 | ||||
| +#
 | ||||
| +# Picks and returns an "unused" port, setting the global variable
 | ||||
| +# $port.
 | ||||
| +#
 | ||||
| +# This is inherently racy, but we need it because qemu does not currently
 | ||||
| +# permit NBD+TLS over a Unix domain socket
 | ||||
| +pick_unused_port ()
 | ||||
| +{
 | ||||
| +    if ! (ss --version) >/dev/null 2>&1; then
 | ||||
| +        _notrun "ss utility required, skipped this test"
 | ||||
| +    fi
 | ||||
| +
 | ||||
| +    # Start at a random port to make it less likely that two parallel
 | ||||
| +    # tests will conflict.
 | ||||
| +    port=$(( 50000 + (RANDOM%15000) ))
 | ||||
| +    while ss -ltn | grep -sqE ":$port\b"; do
 | ||||
| +        ((port++))
 | ||||
| +        if [ $port -eq 65000 ]; then port=50000; fi
 | ||||
| +    done
 | ||||
| +    echo picked unused port
 | ||||
| +}
 | ||||
| +
 | ||||
| +tls_x509_init
 | ||||
| +
 | ||||
| +size=1G
 | ||||
| +DST_IMG="$TEST_DIR/dst.qcow2"
 | ||||
| +
 | ||||
| +echo
 | ||||
| +echo "== preparing TLS creds and spare port =="
 | ||||
| +
 | ||||
| +pick_unused_port
 | ||||
| +tls_x509_create_root_ca "ca1"
 | ||||
| +tls_x509_create_server "ca1" "server1"
 | ||||
| +tls_x509_create_client "ca1" "client1"
 | ||||
| +tls_obj_base=tls-creds-x509,id=tls0,verify-peer=true,dir="${tls_dir}"
 | ||||
| +
 | ||||
| +echo
 | ||||
| +echo "== preparing image =="
 | ||||
| +
 | ||||
| +_make_test_img $size
 | ||||
| +$QEMU_IMG create -f qcow2 "$DST_IMG" $size | _filter_img_create
 | ||||
| +
 | ||||
| +echo
 | ||||
| +echo === Starting Src QEMU ===
 | ||||
| +echo
 | ||||
| +
 | ||||
| +_launch_qemu -machine q35 \
 | ||||
| +    -object iothread,id=iothread0 \
 | ||||
| +    -object "${tls_obj_base}"/client1,endpoint=client \
 | ||||
| +    -device '{"driver":"pcie-root-port", "id":"root0", "multifunction":true,
 | ||||
| +              "bus":"pcie.0"}' \
 | ||||
| +    -device '{"driver":"virtio-scsi-pci", "id":"virtio_scsi_pci0",
 | ||||
| +              "bus":"root0", "iothread":"iothread0"}' \
 | ||||
| +    -device '{"driver":"scsi-hd", "id":"image1", "drive":"drive_image1",
 | ||||
| +              "bus":"virtio_scsi_pci0.0"}' \
 | ||||
| +    -blockdev '{"driver":"file", "cache":{"direct":true, "no-flush":false},
 | ||||
| +                "filename":"'"$TEST_IMG"'", "node-name":"drive_sys1"}' \
 | ||||
| +    -blockdev '{"driver":"qcow2", "node-name":"drive_image1",
 | ||||
| +                "file":"drive_sys1"}'
 | ||||
| +h1=$QEMU_HANDLE
 | ||||
| +_send_qemu_cmd $h1 '{"execute": "qmp_capabilities"}' 'return'
 | ||||
| +
 | ||||
| +echo
 | ||||
| +echo === Starting Dst VM2 ===
 | ||||
| +echo
 | ||||
| +
 | ||||
| +_launch_qemu -machine q35 \
 | ||||
| +    -object iothread,id=iothread0 \
 | ||||
| +    -object "${tls_obj_base}"/server1,endpoint=server \
 | ||||
| +    -device '{"driver":"pcie-root-port", "id":"root0", "multifunction":true,
 | ||||
| +              "bus":"pcie.0"}' \
 | ||||
| +    -device '{"driver":"virtio-scsi-pci", "id":"virtio_scsi_pci0",
 | ||||
| +              "bus":"root0", "iothread":"iothread0"}' \
 | ||||
| +    -device '{"driver":"scsi-hd", "id":"image1", "drive":"drive_image1",
 | ||||
| +              "bus":"virtio_scsi_pci0.0"}' \
 | ||||
| +    -blockdev '{"driver":"file", "cache":{"direct":true, "no-flush":false},
 | ||||
| +                "filename":"'"$DST_IMG"'", "node-name":"drive_sys1"}' \
 | ||||
| +    -blockdev '{"driver":"qcow2", "node-name":"drive_image1",
 | ||||
| +                "file":"drive_sys1"}' \
 | ||||
| +    -incoming defer
 | ||||
| +h2=$QEMU_HANDLE
 | ||||
| +_send_qemu_cmd $h2 '{"execute": "qmp_capabilities"}' 'return'
 | ||||
| +
 | ||||
| +echo
 | ||||
| +echo === Dst VM: Enable NBD server for incoming storage migration ===
 | ||||
| +echo
 | ||||
| +
 | ||||
| +_send_qemu_cmd $h2 '{"execute": "nbd-server-start", "arguments":
 | ||||
| +    {"addr": {"type": "inet", "data": {"host": "127.0.0.1", "port": "'$port'"}},
 | ||||
| +              "tls-creds": "tls0"}}' '{"return": {}}' | sed "s/\"$port\"/PORT/g"
 | ||||
| +_send_qemu_cmd $h2 '{"execute": "block-export-add", "arguments":
 | ||||
| +    {"node-name": "drive_image1", "type": "nbd", "writable": true,
 | ||||
| +      "id": "drive_image1"}}' '{"return": {}}'
 | ||||
| +
 | ||||
| +echo
 | ||||
| +echo === Src VM: Mirror to dst NBD for outgoing storage migration ===
 | ||||
| +echo
 | ||||
| +
 | ||||
| +_send_qemu_cmd $h1 '{"execute": "blockdev-add", "arguments":
 | ||||
| +    {"node-name": "mirror", "driver": "nbd",
 | ||||
| +     "server": {"type": "inet", "host": "127.0.0.1", "port": "'$port'"},
 | ||||
| +     "export": "drive_image1", "tls-creds": "tls0",
 | ||||
| +     "tls-hostname": "127.0.0.1"}}' '{"return": {}}' | sed "s/\"$port\"/PORT/g"
 | ||||
| +_send_qemu_cmd $h1 '{"execute": "blockdev-mirror", "arguments":
 | ||||
| +    {"sync": "full", "device": "drive_image1", "target": "mirror",
 | ||||
| +     "job-id": "drive_image1_53"}}' '{"return": {}}'
 | ||||
| +_timed_wait_for $h1 '"ready"'
 | ||||
| +
 | ||||
| +echo
 | ||||
| +echo === Cleaning up ===
 | ||||
| +echo
 | ||||
| +
 | ||||
| +_send_qemu_cmd $h1 '{"execute":"quit"}' ''
 | ||||
| +_send_qemu_cmd $h2 '{"execute":"quit"}' ''
 | ||||
| +
 | ||||
| +echo "*** done"
 | ||||
| +rm -f $seq.full
 | ||||
| +status=0
 | ||||
| diff --git a/tests/qemu-iotests/tests/nbd-tls-iothread.out b/tests/qemu-iotests/tests/nbd-tls-iothread.out
 | ||||
| new file mode 100644 | ||||
| index 0000000000..1d83d4f903
 | ||||
| --- /dev/null
 | ||||
| +++ b/tests/qemu-iotests/tests/nbd-tls-iothread.out
 | ||||
| @@ -0,0 +1,54 @@
 | ||||
| +QA output created by nbd-tls-iothread
 | ||||
| +
 | ||||
| +== preparing TLS creds and spare port ==
 | ||||
| +picked unused port
 | ||||
| +Generating a self signed certificate...
 | ||||
| +Generating a signed certificate...
 | ||||
| +Generating a signed certificate...
 | ||||
| +
 | ||||
| +== preparing image ==
 | ||||
| +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 | ||||
| +Formatting 'TEST_DIR/dst.IMGFMT', fmt=IMGFMT size=1073741824
 | ||||
| +
 | ||||
| +=== Starting Src QEMU ===
 | ||||
| +
 | ||||
| +{"execute": "qmp_capabilities"}
 | ||||
| +{"return": {}}
 | ||||
| +
 | ||||
| +=== Starting Dst VM2 ===
 | ||||
| +
 | ||||
| +{"execute": "qmp_capabilities"}
 | ||||
| +{"return": {}}
 | ||||
| +
 | ||||
| +=== Dst VM: Enable NBD server for incoming storage migration ===
 | ||||
| +
 | ||||
| +{"execute": "nbd-server-start", "arguments":
 | ||||
| +    {"addr": {"type": "inet", "data": {"host": "127.0.0.1", "port": PORT}},
 | ||||
| +              "tls-creds": "tls0"}}
 | ||||
| +{"return": {}}
 | ||||
| +{"execute": "block-export-add", "arguments":
 | ||||
| +    {"node-name": "drive_image1", "type": "nbd", "writable": true,
 | ||||
| +      "id": "drive_image1"}}
 | ||||
| +{"return": {}}
 | ||||
| +
 | ||||
| +=== Src VM: Mirror to dst NBD for outgoing storage migration ===
 | ||||
| +
 | ||||
| +{"execute": "blockdev-add", "arguments":
 | ||||
| +    {"node-name": "mirror", "driver": "nbd",
 | ||||
| +     "server": {"type": "inet", "host": "127.0.0.1", "port": PORT},
 | ||||
| +     "export": "drive_image1", "tls-creds": "tls0",
 | ||||
| +     "tls-hostname": "127.0.0.1"}}
 | ||||
| +{"return": {}}
 | ||||
| +{"execute": "blockdev-mirror", "arguments":
 | ||||
| +    {"sync": "full", "device": "drive_image1", "target": "mirror",
 | ||||
| +     "job-id": "drive_image1_53"}}
 | ||||
| +{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "drive_image1_53"}}
 | ||||
| +{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "drive_image1_53"}}
 | ||||
| +{"return": {}}
 | ||||
| +{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "drive_image1_53"}}
 | ||||
| +
 | ||||
| +=== Cleaning up ===
 | ||||
| +
 | ||||
| +{"execute":"quit"}
 | ||||
| +{"execute":"quit"}
 | ||||
| +*** done
 | ||||
| -- 
 | ||||
| 2.39.3 | ||||
| 
 | ||||
| @ -1,9 +1,18 @@ | ||||
| From e34f4d87e8d47b0a65cb663aaf7bef60c2112d36 Mon Sep 17 00:00:00 2001 | ||||
| From 8a8fa4ab4dc05502550ca207926cd0c93a3341ea Mon Sep 17 00:00:00 2001 | ||||
| From: Igor Mammedov <imammedo@redhat.com> | ||||
| Date: Mon, 8 Apr 2024 13:09:56 +0200 | ||||
| Date: Mon, 8 Apr 2024 12:43:49 +0200 | ||||
| Subject: [PATCH] kvm: error out of kvm_irqchip_add_msi_route() in case of full | ||||
|  route table | ||||
| 
 | ||||
| RH-Author: Igor Mammedov <imammedo@redhat.com> | ||||
| RH-MergeRequest: 374: kvm: error out of kvm_irqchip_add_msi_route() in case of full route table | ||||
| RH-Jira: RHEL-32990 | ||||
| RH-Acked-by: Ani Sinha <anisinha@redhat.com> | ||||
| RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com> | ||||
| RH-Commit: [1/1] df31f2d0cafe10a1ac22a2bebb85dc17c1e891e0 | ||||
| 
 | ||||
| RH-Jira: RHEL-32990 | ||||
| 
 | ||||
| subj is calling kvm_add_routing_entry() which simply extends | ||||
|   KVMState::irq_routes::entries[] | ||||
| but doesn't check if number of routes goes beyond limit the kernel | ||||
| @ -31,17 +40,15 @@ as expected with following warnings on console: | ||||
|     virtio_bus_start_ioeventfd: failed. Fallback to userspace (slower). | ||||
| 
 | ||||
| Signed-off-by: Igor Mammedov <imammedo@redhat.com> | ||||
| Message-ID: <20240408110956.451558-1-imammedo@redhat.com> | ||||
| Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> | ||||
| ---
 | ||||
|  accel/kvm/kvm-all.c | 15 ++++++++++----- | ||||
|  1 file changed, 10 insertions(+), 5 deletions(-) | ||||
| 
 | ||||
| diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
 | ||||
| index a8cecd040ebc..931f74256e8a 100644
 | ||||
| index e39a810a4e..f1a4564cbd 100644
 | ||||
| --- a/accel/kvm/kvm-all.c
 | ||||
| +++ b/accel/kvm/kvm-all.c
 | ||||
| @@ -1999,12 +1999,17 @@ int kvm_irqchip_add_msi_route(KVMRouteChange *c, int vector, PCIDevice *dev)
 | ||||
| @@ -2000,12 +2000,17 @@ int kvm_irqchip_add_msi_route(KVMRouteChange *c, int vector, PCIDevice *dev)
 | ||||
|          return -EINVAL; | ||||
|      } | ||||
|   | ||||
| @ -64,3 +71,6 @@ index a8cecd040ebc..931f74256e8a 100644 | ||||
|   | ||||
|      return virq; | ||||
|  } | ||||
| -- 
 | ||||
| 2.39.3 | ||||
| 
 | ||||
| @ -0,0 +1,329 @@ | ||||
| From d1dd79b558fb9b23ae14165ec8edf0085e927091 Mon Sep 17 00:00:00 2001 | ||||
| From: Eric Blake <eblake@redhat.com> | ||||
| Date: Mon, 8 Apr 2024 11:00:44 -0500 | ||||
| Subject: [PATCH 2/4] nbd/server: Mark negotiation functions as coroutine_fn | ||||
| 
 | ||||
| RH-Author: Eric Blake <eblake@redhat.com> | ||||
| RH-MergeRequest: 375: Fix regression on nbd+tls | ||||
| RH-Jira: RHEL-33754 | ||||
| RH-Acked-by: Kevin Wolf <kwolf@redhat.com> | ||||
| RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com> | ||||
| RH-Commit: [2/4] 6dc8ecca16df5ae5cc6dc36e7b96f991396fcf24 (ebblake/qemu-kvm) | ||||
| 
 | ||||
| nbd_negotiate() is already marked coroutine_fn.  And given the fix in | ||||
| the previous patch to have nbd_negotiate_handle_starttls not create | ||||
| and wait on a g_main_loop (as that would violate coroutine | ||||
| constraints), it is worth marking the rest of the related static | ||||
| functions reachable only during option negotiation as also being | ||||
| coroutine_fn. | ||||
| 
 | ||||
| Suggested-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> | ||||
| Signed-off-by: Eric Blake <eblake@redhat.com> | ||||
| Message-ID: <20240408160214.1200629-6-eblake@redhat.com> | ||||
| Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> | ||||
| [eblake: drop one spurious coroutine_fn marking] | ||||
| Signed-off-by: Eric Blake <eblake@redhat.com> | ||||
| (cherry picked from commit 4fa333e08dd96395a99ea8dd9e4c73a29dd23344) | ||||
| Jira: https://issues.redhat.com/browse/RHEL-33754 | ||||
| Signed-off-by: Eric Blake <eblake@redhat.com> | ||||
| ---
 | ||||
|  nbd/server.c | 102 +++++++++++++++++++++++++++++---------------------- | ||||
|  1 file changed, 59 insertions(+), 43 deletions(-) | ||||
| 
 | ||||
| diff --git a/nbd/server.c b/nbd/server.c
 | ||||
| index 98ae0e1632..892797bb11 100644
 | ||||
| --- a/nbd/server.c
 | ||||
| +++ b/nbd/server.c
 | ||||
| @@ -195,8 +195,9 @@ static inline void set_be_option_rep(NBDOptionReply *rep, uint32_t option,
 | ||||
|   | ||||
|  /* Send a reply header, including length, but no payload. | ||||
|   * Return -errno on error, 0 on success. */ | ||||
| -static int nbd_negotiate_send_rep_len(NBDClient *client, uint32_t type,
 | ||||
| -                                      uint32_t len, Error **errp)
 | ||||
| +static coroutine_fn int
 | ||||
| +nbd_negotiate_send_rep_len(NBDClient *client, uint32_t type,
 | ||||
| +                           uint32_t len, Error **errp)
 | ||||
|  { | ||||
|      NBDOptionReply rep; | ||||
|   | ||||
| @@ -211,15 +212,15 @@ static int nbd_negotiate_send_rep_len(NBDClient *client, uint32_t type,
 | ||||
|   | ||||
|  /* Send a reply header with default 0 length. | ||||
|   * Return -errno on error, 0 on success. */ | ||||
| -static int nbd_negotiate_send_rep(NBDClient *client, uint32_t type,
 | ||||
| -                                  Error **errp)
 | ||||
| +static coroutine_fn int
 | ||||
| +nbd_negotiate_send_rep(NBDClient *client, uint32_t type, Error **errp)
 | ||||
|  { | ||||
|      return nbd_negotiate_send_rep_len(client, type, 0, errp); | ||||
|  } | ||||
|   | ||||
|  /* Send an error reply. | ||||
|   * Return -errno on error, 0 on success. */ | ||||
| -static int G_GNUC_PRINTF(4, 0)
 | ||||
| +static coroutine_fn int G_GNUC_PRINTF(4, 0)
 | ||||
|  nbd_negotiate_send_rep_verr(NBDClient *client, uint32_t type, | ||||
|                              Error **errp, const char *fmt, va_list va) | ||||
|  { | ||||
| @@ -259,7 +260,7 @@ nbd_sanitize_name(const char *name)
 | ||||
|   | ||||
|  /* Send an error reply. | ||||
|   * Return -errno on error, 0 on success. */ | ||||
| -static int G_GNUC_PRINTF(4, 5)
 | ||||
| +static coroutine_fn int G_GNUC_PRINTF(4, 5)
 | ||||
|  nbd_negotiate_send_rep_err(NBDClient *client, uint32_t type, | ||||
|                             Error **errp, const char *fmt, ...) | ||||
|  { | ||||
| @@ -275,7 +276,7 @@ nbd_negotiate_send_rep_err(NBDClient *client, uint32_t type,
 | ||||
|  /* Drop remainder of the current option, and send a reply with the | ||||
|   * given error type and message. Return -errno on read or write | ||||
|   * failure; or 0 if connection is still live. */ | ||||
| -static int G_GNUC_PRINTF(4, 0)
 | ||||
| +static coroutine_fn int G_GNUC_PRINTF(4, 0)
 | ||||
|  nbd_opt_vdrop(NBDClient *client, uint32_t type, Error **errp, | ||||
|                const char *fmt, va_list va) | ||||
|  { | ||||
| @@ -288,7 +289,7 @@ nbd_opt_vdrop(NBDClient *client, uint32_t type, Error **errp,
 | ||||
|      return ret; | ||||
|  } | ||||
|   | ||||
| -static int G_GNUC_PRINTF(4, 5)
 | ||||
| +static coroutine_fn int G_GNUC_PRINTF(4, 5)
 | ||||
|  nbd_opt_drop(NBDClient *client, uint32_t type, Error **errp, | ||||
|               const char *fmt, ...) | ||||
|  { | ||||
| @@ -302,7 +303,7 @@ nbd_opt_drop(NBDClient *client, uint32_t type, Error **errp,
 | ||||
|      return ret; | ||||
|  } | ||||
|   | ||||
| -static int G_GNUC_PRINTF(3, 4)
 | ||||
| +static coroutine_fn int G_GNUC_PRINTF(3, 4)
 | ||||
|  nbd_opt_invalid(NBDClient *client, Error **errp, const char *fmt, ...) | ||||
|  { | ||||
|      int ret; | ||||
| @@ -319,8 +320,9 @@ nbd_opt_invalid(NBDClient *client, Error **errp, const char *fmt, ...)
 | ||||
|   * If @check_nul, require that no NUL bytes appear in buffer. | ||||
|   * Return -errno on I/O error, 0 if option was completely handled by | ||||
|   * sending a reply about inconsistent lengths, or 1 on success. */ | ||||
| -static int nbd_opt_read(NBDClient *client, void *buffer, size_t size,
 | ||||
| -                        bool check_nul, Error **errp)
 | ||||
| +static coroutine_fn int
 | ||||
| +nbd_opt_read(NBDClient *client, void *buffer, size_t size,
 | ||||
| +             bool check_nul, Error **errp)
 | ||||
|  { | ||||
|      if (size > client->optlen) { | ||||
|          return nbd_opt_invalid(client, errp, | ||||
| @@ -343,7 +345,8 @@ static int nbd_opt_read(NBDClient *client, void *buffer, size_t size,
 | ||||
|  /* Drop size bytes from the unparsed payload of the current option. | ||||
|   * Return -errno on I/O error, 0 if option was completely handled by | ||||
|   * sending a reply about inconsistent lengths, or 1 on success. */ | ||||
| -static int nbd_opt_skip(NBDClient *client, size_t size, Error **errp)
 | ||||
| +static coroutine_fn int
 | ||||
| +nbd_opt_skip(NBDClient *client, size_t size, Error **errp)
 | ||||
|  { | ||||
|      if (size > client->optlen) { | ||||
|          return nbd_opt_invalid(client, errp, | ||||
| @@ -366,8 +369,9 @@ static int nbd_opt_skip(NBDClient *client, size_t size, Error **errp)
 | ||||
|   * Return -errno on I/O error, 0 if option was completely handled by | ||||
|   * sending a reply about inconsistent lengths, or 1 on success. | ||||
|   */ | ||||
| -static int nbd_opt_read_name(NBDClient *client, char **name, uint32_t *length,
 | ||||
| -                             Error **errp)
 | ||||
| +static coroutine_fn int
 | ||||
| +nbd_opt_read_name(NBDClient *client, char **name, uint32_t *length,
 | ||||
| +                  Error **errp)
 | ||||
|  { | ||||
|      int ret; | ||||
|      uint32_t len; | ||||
| @@ -402,8 +406,8 @@ static int nbd_opt_read_name(NBDClient *client, char **name, uint32_t *length,
 | ||||
|   | ||||
|  /* Send a single NBD_REP_SERVER reply to NBD_OPT_LIST, including payload. | ||||
|   * Return -errno on error, 0 on success. */ | ||||
| -static int nbd_negotiate_send_rep_list(NBDClient *client, NBDExport *exp,
 | ||||
| -                                       Error **errp)
 | ||||
| +static coroutine_fn int
 | ||||
| +nbd_negotiate_send_rep_list(NBDClient *client, NBDExport *exp, Error **errp)
 | ||||
|  { | ||||
|      ERRP_GUARD(); | ||||
|      size_t name_len, desc_len; | ||||
| @@ -444,7 +448,8 @@ static int nbd_negotiate_send_rep_list(NBDClient *client, NBDExport *exp,
 | ||||
|   | ||||
|  /* Process the NBD_OPT_LIST command, with a potential series of replies. | ||||
|   * Return -errno on error, 0 on success. */ | ||||
| -static int nbd_negotiate_handle_list(NBDClient *client, Error **errp)
 | ||||
| +static coroutine_fn int
 | ||||
| +nbd_negotiate_handle_list(NBDClient *client, Error **errp)
 | ||||
|  { | ||||
|      NBDExport *exp; | ||||
|      assert(client->opt == NBD_OPT_LIST); | ||||
| @@ -459,7 +464,8 @@ static int nbd_negotiate_handle_list(NBDClient *client, Error **errp)
 | ||||
|      return nbd_negotiate_send_rep(client, NBD_REP_ACK, errp); | ||||
|  } | ||||
|   | ||||
| -static void nbd_check_meta_export(NBDClient *client, NBDExport *exp)
 | ||||
| +static coroutine_fn void
 | ||||
| +nbd_check_meta_export(NBDClient *client, NBDExport *exp)
 | ||||
|  { | ||||
|      if (exp != client->contexts.exp) { | ||||
|          client->contexts.count = 0; | ||||
| @@ -468,8 +474,9 @@ static void nbd_check_meta_export(NBDClient *client, NBDExport *exp)
 | ||||
|   | ||||
|  /* Send a reply to NBD_OPT_EXPORT_NAME. | ||||
|   * Return -errno on error, 0 on success. */ | ||||
| -static int nbd_negotiate_handle_export_name(NBDClient *client, bool no_zeroes,
 | ||||
| -                                            Error **errp)
 | ||||
| +static coroutine_fn int
 | ||||
| +nbd_negotiate_handle_export_name(NBDClient *client, bool no_zeroes,
 | ||||
| +                                 Error **errp)
 | ||||
|  { | ||||
|      ERRP_GUARD(); | ||||
|      g_autofree char *name = NULL; | ||||
| @@ -536,9 +543,9 @@ static int nbd_negotiate_handle_export_name(NBDClient *client, bool no_zeroes,
 | ||||
|  /* Send a single NBD_REP_INFO, with a buffer @buf of @length bytes. | ||||
|   * The buffer does NOT include the info type prefix. | ||||
|   * Return -errno on error, 0 if ready to send more. */ | ||||
| -static int nbd_negotiate_send_info(NBDClient *client,
 | ||||
| -                                   uint16_t info, uint32_t length, void *buf,
 | ||||
| -                                   Error **errp)
 | ||||
| +static coroutine_fn int
 | ||||
| +nbd_negotiate_send_info(NBDClient *client, uint16_t info, uint32_t length,
 | ||||
| +                        void *buf, Error **errp)
 | ||||
|  { | ||||
|      int rc; | ||||
|   | ||||
| @@ -565,7 +572,8 @@ static int nbd_negotiate_send_info(NBDClient *client,
 | ||||
|   * -errno  transmission error occurred or @fatal was requested, errp is set | ||||
|   * 0       error message successfully sent to client, errp is not set | ||||
|   */ | ||||
| -static int nbd_reject_length(NBDClient *client, bool fatal, Error **errp)
 | ||||
| +static coroutine_fn int
 | ||||
| +nbd_reject_length(NBDClient *client, bool fatal, Error **errp)
 | ||||
|  { | ||||
|      int ret; | ||||
|   | ||||
| @@ -583,7 +591,8 @@ static int nbd_reject_length(NBDClient *client, bool fatal, Error **errp)
 | ||||
|  /* Handle NBD_OPT_INFO and NBD_OPT_GO. | ||||
|   * Return -errno on error, 0 if ready for next option, and 1 to move | ||||
|   * into transmission phase.  */ | ||||
| -static int nbd_negotiate_handle_info(NBDClient *client, Error **errp)
 | ||||
| +static coroutine_fn int
 | ||||
| +nbd_negotiate_handle_info(NBDClient *client, Error **errp)
 | ||||
|  { | ||||
|      int rc; | ||||
|      g_autofree char *name = NULL; | ||||
| @@ -755,7 +764,8 @@ struct NBDTLSServerHandshakeData {
 | ||||
|      Coroutine *co; | ||||
|  }; | ||||
|   | ||||
| -static void nbd_server_tls_handshake(QIOTask *task, void *opaque)
 | ||||
| +static void
 | ||||
| +nbd_server_tls_handshake(QIOTask *task, void *opaque)
 | ||||
|  { | ||||
|      struct NBDTLSServerHandshakeData *data = opaque; | ||||
|   | ||||
| @@ -768,8 +778,8 @@ static void nbd_server_tls_handshake(QIOTask *task, void *opaque)
 | ||||
|   | ||||
|  /* Handle NBD_OPT_STARTTLS. Return NULL to drop connection, or else the | ||||
|   * new channel for all further (now-encrypted) communication. */ | ||||
| -static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client,
 | ||||
| -                                                 Error **errp)
 | ||||
| +static coroutine_fn QIOChannel *
 | ||||
| +nbd_negotiate_handle_starttls(NBDClient *client, Error **errp)
 | ||||
|  { | ||||
|      QIOChannel *ioc; | ||||
|      QIOChannelTLS *tioc; | ||||
| @@ -821,10 +831,9 @@ static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client,
 | ||||
|   * | ||||
|   * For NBD_OPT_LIST_META_CONTEXT @context_id is ignored, 0 is used instead. | ||||
|   */ | ||||
| -static int nbd_negotiate_send_meta_context(NBDClient *client,
 | ||||
| -                                           const char *context,
 | ||||
| -                                           uint32_t context_id,
 | ||||
| -                                           Error **errp)
 | ||||
| +static coroutine_fn int
 | ||||
| +nbd_negotiate_send_meta_context(NBDClient *client, const char *context,
 | ||||
| +                                uint32_t context_id, Error **errp)
 | ||||
|  { | ||||
|      NBDOptionReplyMetaContext opt; | ||||
|      struct iovec iov[] = { | ||||
| @@ -849,8 +858,9 @@ static int nbd_negotiate_send_meta_context(NBDClient *client,
 | ||||
|   * Return true if @query matches @pattern, or if @query is empty when | ||||
|   * the @client is performing _LIST_. | ||||
|   */ | ||||
| -static bool nbd_meta_empty_or_pattern(NBDClient *client, const char *pattern,
 | ||||
| -                                      const char *query)
 | ||||
| +static coroutine_fn bool
 | ||||
| +nbd_meta_empty_or_pattern(NBDClient *client, const char *pattern,
 | ||||
| +                          const char *query)
 | ||||
|  { | ||||
|      if (!*query) { | ||||
|          trace_nbd_negotiate_meta_query_parse("empty"); | ||||
| @@ -867,7 +877,8 @@ static bool nbd_meta_empty_or_pattern(NBDClient *client, const char *pattern,
 | ||||
|  /* | ||||
|   * Return true and adjust @str in place if it begins with @prefix. | ||||
|   */ | ||||
| -static bool nbd_strshift(const char **str, const char *prefix)
 | ||||
| +static coroutine_fn bool
 | ||||
| +nbd_strshift(const char **str, const char *prefix)
 | ||||
|  { | ||||
|      size_t len = strlen(prefix); | ||||
|   | ||||
| @@ -883,8 +894,9 @@ static bool nbd_strshift(const char **str, const char *prefix)
 | ||||
|   * Handle queries to 'base' namespace. For now, only the base:allocation | ||||
|   * context is available.  Return true if @query has been handled. | ||||
|   */ | ||||
| -static bool nbd_meta_base_query(NBDClient *client, NBDMetaContexts *meta,
 | ||||
| -                                const char *query)
 | ||||
| +static coroutine_fn bool
 | ||||
| +nbd_meta_base_query(NBDClient *client, NBDMetaContexts *meta,
 | ||||
| +                    const char *query)
 | ||||
|  { | ||||
|      if (!nbd_strshift(&query, "base:")) { | ||||
|          return false; | ||||
| @@ -903,8 +915,9 @@ static bool nbd_meta_base_query(NBDClient *client, NBDMetaContexts *meta,
 | ||||
|   * and qemu:allocation-depth contexts are available.  Return true if @query | ||||
|   * has been handled. | ||||
|   */ | ||||
| -static bool nbd_meta_qemu_query(NBDClient *client, NBDMetaContexts *meta,
 | ||||
| -                                const char *query)
 | ||||
| +static coroutine_fn bool
 | ||||
| +nbd_meta_qemu_query(NBDClient *client, NBDMetaContexts *meta,
 | ||||
| +                    const char *query)
 | ||||
|  { | ||||
|      size_t i; | ||||
|   | ||||
| @@ -968,8 +981,9 @@ static bool nbd_meta_qemu_query(NBDClient *client, NBDMetaContexts *meta,
 | ||||
|   * | ||||
|   * Return -errno on I/O error, 0 if option was completely handled by | ||||
|   * sending a reply about inconsistent lengths, or 1 on success. */ | ||||
| -static int nbd_negotiate_meta_query(NBDClient *client,
 | ||||
| -                                    NBDMetaContexts *meta, Error **errp)
 | ||||
| +static coroutine_fn int
 | ||||
| +nbd_negotiate_meta_query(NBDClient *client,
 | ||||
| +                         NBDMetaContexts *meta, Error **errp)
 | ||||
|  { | ||||
|      int ret; | ||||
|      g_autofree char *query = NULL; | ||||
| @@ -1008,7 +1022,8 @@ static int nbd_negotiate_meta_query(NBDClient *client,
 | ||||
|   * Handle NBD_OPT_LIST_META_CONTEXT and NBD_OPT_SET_META_CONTEXT | ||||
|   * | ||||
|   * Return -errno on I/O error, or 0 if option was completely handled. */ | ||||
| -static int nbd_negotiate_meta_queries(NBDClient *client, Error **errp)
 | ||||
| +static coroutine_fn int
 | ||||
| +nbd_negotiate_meta_queries(NBDClient *client, Error **errp)
 | ||||
|  { | ||||
|      int ret; | ||||
|      g_autofree char *export_name = NULL; | ||||
| @@ -1136,7 +1151,8 @@ static int nbd_negotiate_meta_queries(NBDClient *client, Error **errp)
 | ||||
|   * 1       if client sent NBD_OPT_ABORT, i.e. on valid disconnect, | ||||
|   *         errp is not set | ||||
|   */ | ||||
| -static int nbd_negotiate_options(NBDClient *client, Error **errp)
 | ||||
| +static coroutine_fn int
 | ||||
| +nbd_negotiate_options(NBDClient *client, Error **errp)
 | ||||
|  { | ||||
|      uint32_t flags; | ||||
|      bool fixedNewstyle = false; | ||||
| -- 
 | ||||
| 2.39.3 | ||||
| 
 | ||||
| @ -0,0 +1,207 @@ | ||||
| From ef01aeba9f6c4c886719261333a04bc32484f0d0 Mon Sep 17 00:00:00 2001 | ||||
| From: Zhu Yangyang <zhuyangyang14@huawei.com> | ||||
| Date: Mon, 8 Apr 2024 11:00:43 -0500 | ||||
| Subject: [PATCH 1/4] nbd/server: do not poll within a coroutine context | ||||
| 
 | ||||
| RH-Author: Eric Blake <eblake@redhat.com> | ||||
| RH-MergeRequest: 375: Fix regression on nbd+tls | ||||
| RH-Jira: RHEL-33754 | ||||
| RH-Acked-by: Kevin Wolf <kwolf@redhat.com> | ||||
| RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com> | ||||
| RH-Commit: [1/4] 88ca2c90e0c412ba8c1cfd7ea91e01ec58220e9b (ebblake/qemu-kvm) | ||||
| 
 | ||||
| Coroutines are not supposed to block. Instead, they should yield. | ||||
| 
 | ||||
| The client performs TLS upgrade outside of an AIOContext, during | ||||
| synchronous handshake; this still requires g_main_loop.  But the | ||||
| server responds to TLS upgrade inside a coroutine, so a nested | ||||
| g_main_loop is wrong.  Since the two callbacks no longer share more | ||||
| than the setting of data.complete and data.error, it's just as easy to | ||||
| use static helpers instead of trying to share a common code path.  It | ||||
| is also possible to add assertions that no other code is interfering | ||||
| with the eventual path to qio reaching the callback, whether or not it | ||||
| required a yield or main loop. | ||||
| 
 | ||||
| Fixes: f95910f ("nbd: implement TLS support in the protocol negotiation") | ||||
| Signed-off-by: Zhu Yangyang <zhuyangyang14@huawei.com> | ||||
| [eblake: move callbacks to their use point, add assertions] | ||||
| Signed-off-by: Eric Blake <eblake@redhat.com> | ||||
| Message-ID: <20240408160214.1200629-5-eblake@redhat.com> | ||||
| Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> | ||||
| (cherry picked from commit ae6d91a7e9b77abb029ed3fa9fad461422286942) | ||||
| Jira: https://issues.redhat.com/browse/RHEL-33754 | ||||
| Signed-off-by: Eric Blake <eblake@redhat.com> | ||||
| ---
 | ||||
|  nbd/client.c       | 28 ++++++++++++++++++++++++---- | ||||
|  nbd/common.c       | 11 ----------- | ||||
|  nbd/nbd-internal.h | 10 ---------- | ||||
|  nbd/server.c       | 28 +++++++++++++++++++++++----- | ||||
|  4 files changed, 47 insertions(+), 30 deletions(-) | ||||
| 
 | ||||
| diff --git a/nbd/client.c b/nbd/client.c
 | ||||
| index 29ffc609a4..c89c750467 100644
 | ||||
| --- a/nbd/client.c
 | ||||
| +++ b/nbd/client.c
 | ||||
| @@ -596,13 +596,31 @@ static int nbd_request_simple_option(QIOChannel *ioc, int opt, bool strict,
 | ||||
|      return 1; | ||||
|  } | ||||
|   | ||||
| +/* Callback to learn when QIO TLS upgrade is complete */
 | ||||
| +struct NBDTLSClientHandshakeData {
 | ||||
| +    bool complete;
 | ||||
| +    Error *error;
 | ||||
| +    GMainLoop *loop;
 | ||||
| +};
 | ||||
| +
 | ||||
| +static void nbd_client_tls_handshake(QIOTask *task, void *opaque)
 | ||||
| +{
 | ||||
| +    struct NBDTLSClientHandshakeData *data = opaque;
 | ||||
| +
 | ||||
| +    qio_task_propagate_error(task, &data->error);
 | ||||
| +    data->complete = true;
 | ||||
| +    if (data->loop) {
 | ||||
| +        g_main_loop_quit(data->loop);
 | ||||
| +    }
 | ||||
| +}
 | ||||
| +
 | ||||
|  static QIOChannel *nbd_receive_starttls(QIOChannel *ioc, | ||||
|                                          QCryptoTLSCreds *tlscreds, | ||||
|                                          const char *hostname, Error **errp) | ||||
|  { | ||||
|      int ret; | ||||
|      QIOChannelTLS *tioc; | ||||
| -    struct NBDTLSHandshakeData data = { 0 };
 | ||||
| +    struct NBDTLSClientHandshakeData data = { 0 };
 | ||||
|   | ||||
|      ret = nbd_request_simple_option(ioc, NBD_OPT_STARTTLS, true, errp); | ||||
|      if (ret <= 0) { | ||||
| @@ -619,18 +637,20 @@ static QIOChannel *nbd_receive_starttls(QIOChannel *ioc,
 | ||||
|          return NULL; | ||||
|      } | ||||
|      qio_channel_set_name(QIO_CHANNEL(tioc), "nbd-client-tls"); | ||||
| -    data.loop = g_main_loop_new(g_main_context_default(), FALSE);
 | ||||
|      trace_nbd_receive_starttls_tls_handshake(); | ||||
|      qio_channel_tls_handshake(tioc, | ||||
| -                              nbd_tls_handshake,
 | ||||
| +                              nbd_client_tls_handshake,
 | ||||
|                                &data, | ||||
|                                NULL, | ||||
|                                NULL); | ||||
|   | ||||
|      if (!data.complete) { | ||||
| +        data.loop = g_main_loop_new(g_main_context_default(), FALSE);
 | ||||
|          g_main_loop_run(data.loop); | ||||
| +        assert(data.complete);
 | ||||
| +        g_main_loop_unref(data.loop);
 | ||||
|      } | ||||
| -    g_main_loop_unref(data.loop);
 | ||||
| +
 | ||||
|      if (data.error) { | ||||
|          error_propagate(errp, data.error); | ||||
|          object_unref(OBJECT(tioc)); | ||||
| diff --git a/nbd/common.c b/nbd/common.c
 | ||||
| index 3247c1d618..589a748cfe 100644
 | ||||
| --- a/nbd/common.c
 | ||||
| +++ b/nbd/common.c
 | ||||
| @@ -47,17 +47,6 @@ int nbd_drop(QIOChannel *ioc, size_t size, Error **errp)
 | ||||
|  } | ||||
|   | ||||
|   | ||||
| -void nbd_tls_handshake(QIOTask *task,
 | ||||
| -                       void *opaque)
 | ||||
| -{
 | ||||
| -    struct NBDTLSHandshakeData *data = opaque;
 | ||||
| -
 | ||||
| -    qio_task_propagate_error(task, &data->error);
 | ||||
| -    data->complete = true;
 | ||||
| -    g_main_loop_quit(data->loop);
 | ||||
| -}
 | ||||
| -
 | ||||
| -
 | ||||
|  const char *nbd_opt_lookup(uint32_t opt) | ||||
|  { | ||||
|      switch (opt) { | ||||
| diff --git a/nbd/nbd-internal.h b/nbd/nbd-internal.h
 | ||||
| index dfa02f77ee..91895106a9 100644
 | ||||
| --- a/nbd/nbd-internal.h
 | ||||
| +++ b/nbd/nbd-internal.h
 | ||||
| @@ -72,16 +72,6 @@ static inline int nbd_write(QIOChannel *ioc, const void *buffer, size_t size,
 | ||||
|      return qio_channel_write_all(ioc, buffer, size, errp) < 0 ? -EIO : 0; | ||||
|  } | ||||
|   | ||||
| -struct NBDTLSHandshakeData {
 | ||||
| -    GMainLoop *loop;
 | ||||
| -    bool complete;
 | ||||
| -    Error *error;
 | ||||
| -};
 | ||||
| -
 | ||||
| -
 | ||||
| -void nbd_tls_handshake(QIOTask *task,
 | ||||
| -                       void *opaque);
 | ||||
| -
 | ||||
|  int nbd_drop(QIOChannel *ioc, size_t size, Error **errp); | ||||
|   | ||||
|  #endif | ||||
| diff --git a/nbd/server.c b/nbd/server.c
 | ||||
| index c3484cc1eb..98ae0e1632 100644
 | ||||
| --- a/nbd/server.c
 | ||||
| +++ b/nbd/server.c
 | ||||
| @@ -748,6 +748,23 @@ static int nbd_negotiate_handle_info(NBDClient *client, Error **errp)
 | ||||
|      return rc; | ||||
|  } | ||||
|   | ||||
| +/* Callback to learn when QIO TLS upgrade is complete */
 | ||||
| +struct NBDTLSServerHandshakeData {
 | ||||
| +    bool complete;
 | ||||
| +    Error *error;
 | ||||
| +    Coroutine *co;
 | ||||
| +};
 | ||||
| +
 | ||||
| +static void nbd_server_tls_handshake(QIOTask *task, void *opaque)
 | ||||
| +{
 | ||||
| +    struct NBDTLSServerHandshakeData *data = opaque;
 | ||||
| +
 | ||||
| +    qio_task_propagate_error(task, &data->error);
 | ||||
| +    data->complete = true;
 | ||||
| +    if (!qemu_coroutine_entered(data->co)) {
 | ||||
| +        aio_co_wake(data->co);
 | ||||
| +    }
 | ||||
| +}
 | ||||
|   | ||||
|  /* Handle NBD_OPT_STARTTLS. Return NULL to drop connection, or else the | ||||
|   * new channel for all further (now-encrypted) communication. */ | ||||
| @@ -756,7 +773,7 @@ static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client,
 | ||||
|  { | ||||
|      QIOChannel *ioc; | ||||
|      QIOChannelTLS *tioc; | ||||
| -    struct NBDTLSHandshakeData data = { 0 };
 | ||||
| +    struct NBDTLSServerHandshakeData data = { 0 };
 | ||||
|   | ||||
|      assert(client->opt == NBD_OPT_STARTTLS); | ||||
|   | ||||
| @@ -777,17 +794,18 @@ static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client,
 | ||||
|   | ||||
|      qio_channel_set_name(QIO_CHANNEL(tioc), "nbd-server-tls"); | ||||
|      trace_nbd_negotiate_handle_starttls_handshake(); | ||||
| -    data.loop = g_main_loop_new(g_main_context_default(), FALSE);
 | ||||
| +    data.co = qemu_coroutine_self();
 | ||||
|      qio_channel_tls_handshake(tioc, | ||||
| -                              nbd_tls_handshake,
 | ||||
| +                              nbd_server_tls_handshake,
 | ||||
|                                &data, | ||||
|                                NULL, | ||||
|                                NULL); | ||||
|   | ||||
|      if (!data.complete) { | ||||
| -        g_main_loop_run(data.loop);
 | ||||
| +        qemu_coroutine_yield();
 | ||||
| +        assert(data.complete);
 | ||||
|      } | ||||
| -    g_main_loop_unref(data.loop);
 | ||||
| +
 | ||||
|      if (data.error) { | ||||
|          object_unref(OBJECT(tioc)); | ||||
|          error_propagate(errp, data.error); | ||||
| -- 
 | ||||
| 2.39.3 | ||||
| 
 | ||||
							
								
								
									
										125
									
								
								SOURCES/kvm-qcow2-Don-t-open-data_file-with-BDRV_O_NO_IO.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								SOURCES/kvm-qcow2-Don-t-open-data_file-with-BDRV_O_NO_IO.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,125 @@ | ||||
| From 6e39b4c13c0eacb35e81874b09e6b6411266c631 Mon Sep 17 00:00:00 2001 | ||||
| From: Jon Maloy <jmaloy@redhat.com> | ||||
| Date: Wed, 5 Jun 2024 19:56:51 -0400 | ||||
| Subject: [PATCH 1/4] qcow2: Don't open data_file with BDRV_O_NO_IO | ||||
| 
 | ||||
| RH-Author: Jon Maloy <jmaloy@redhat.com> | ||||
| RH-MergeRequest: 2: EMBARGOED CVE-2024-4467 for rhel-9.4.z (PRDSC) | ||||
| RH-Jira: https://issues.redhat.com/browse/RHEL-35610 | ||||
| RH-CVE: CVE-2024-4467 | ||||
| RH-Acked-by: Kevin Wolf <kwolf@redhat.com> | ||||
| RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com> | ||||
| RH-Acked-by: Hanna Czenczek <hczenczek@redhat.com> | ||||
| RH-Commit: [1/4] 1000359b05c706f3c5155a9481692352be333129 | ||||
| 
 | ||||
| commit f9843ce5c519901654a7d8ba43ee95ce25ca13c2 | ||||
| Author: Kevin Wolf <kwolf@redhat.com> | ||||
| Date:   Thu Apr 11 15:06:01 2024 +0200 | ||||
| 
 | ||||
|     qcow2: Don't open data_file with BDRV_O_NO_IO | ||||
| 
 | ||||
|     One use case for 'qemu-img info' is verifying that untrusted images | ||||
|     don't reference an unwanted external file, be it as a backing file or an | ||||
|     external data file. To make sure that calling 'qemu-img info' can't | ||||
|     already have undesired side effects with a malicious image, just don't | ||||
|     open the data file at all with BDRV_O_NO_IO. If nothing ever tries to do | ||||
|     I/O, we don't need to have it open. | ||||
| 
 | ||||
|     This changes the output of iotests case 061, which used 'qemu-img info' | ||||
|     to show that opening an image with an invalid data file fails. After | ||||
|     this patch, it succeeds. Replace this part of the test with a qemu-io | ||||
|     call, but keep the final 'qemu-img info' to show that the invalid data | ||||
|     file is correctly displayed in the output. | ||||
| 
 | ||||
|     Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||||
|     Reviewed-by: Eric Blake <eblake@redhat.com> | ||||
|     Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||||
|     Reviewed-by: Hanna Czenczek <hreitz@redhat.com> | ||||
|     Upstream: N/A, embargoed | ||||
|     Signed-off-by: Hanna Czenczek <hreitz@redhat.com> | ||||
| 
 | ||||
| Signed-off-by: Jon Maloy <jmaloy@redhat.com> | ||||
| ---
 | ||||
|  block/qcow2.c              | 17 ++++++++++++++++- | ||||
|  tests/qemu-iotests/061     |  6 ++++-- | ||||
|  tests/qemu-iotests/061.out |  8 ++++++-- | ||||
|  3 files changed, 26 insertions(+), 5 deletions(-) | ||||
| 
 | ||||
| diff --git a/block/qcow2.c b/block/qcow2.c
 | ||||
| index d91b7b91d3..b269cfc78f 100644
 | ||||
| --- a/block/qcow2.c
 | ||||
| +++ b/block/qcow2.c
 | ||||
| @@ -1642,7 +1642,22 @@ qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
 | ||||
|          goto fail; | ||||
|      } | ||||
|   | ||||
| -    if (open_data_file) {
 | ||||
| +    if (open_data_file && (flags & BDRV_O_NO_IO)) {
 | ||||
| +        /*
 | ||||
| +         * Don't open the data file for 'qemu-img info' so that it can be used
 | ||||
| +         * to verify that an untrusted qcow2 image doesn't refer to external
 | ||||
| +         * files.
 | ||||
| +         *
 | ||||
| +         * Note: This still makes has_data_file() return true.
 | ||||
| +         */
 | ||||
| +        if (s->incompatible_features & QCOW2_INCOMPAT_DATA_FILE) {
 | ||||
| +            s->data_file = NULL;
 | ||||
| +        } else {
 | ||||
| +            s->data_file = bs->file;
 | ||||
| +        }
 | ||||
| +        qdict_extract_subqdict(options, NULL, "data-file.");
 | ||||
| +        qdict_del(options, "data-file");
 | ||||
| +    } else if (open_data_file) {
 | ||||
|          /* Open external data file */ | ||||
|          bdrv_graph_co_rdunlock(); | ||||
|          s->data_file = bdrv_co_open_child(NULL, options, "data-file", bs, | ||||
| diff --git a/tests/qemu-iotests/061 b/tests/qemu-iotests/061
 | ||||
| index 53c7d428e3..b71ac097d1 100755
 | ||||
| --- a/tests/qemu-iotests/061
 | ||||
| +++ b/tests/qemu-iotests/061
 | ||||
| @@ -326,12 +326,14 @@ $QEMU_IMG amend -o "data_file=foo" "$TEST_IMG"
 | ||||
|  echo | ||||
|  _make_test_img -o "compat=1.1,data_file=$TEST_IMG.data" 64M | ||||
|  $QEMU_IMG amend -o "data_file=foo" "$TEST_IMG" | ||||
| -_img_info --format-specific
 | ||||
| +$QEMU_IO -c "read 0 4k" "$TEST_IMG" 2>&1 | _filter_testdir | _filter_imgfmt
 | ||||
| +$QEMU_IO -c "open -o data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" -c "read 0 4k" | _filter_qemu_io
 | ||||
|  TEST_IMG="data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" _img_info --format-specific --image-opts | ||||
|   | ||||
|  echo | ||||
|  $QEMU_IMG amend -o "data_file=" --image-opts "data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" | ||||
| -_img_info --format-specific
 | ||||
| +$QEMU_IO -c "read 0 4k" "$TEST_IMG" 2>&1 | _filter_testdir | _filter_imgfmt
 | ||||
| +$QEMU_IO -c "open -o data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" -c "read 0 4k" | _filter_qemu_io
 | ||||
|  TEST_IMG="data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" _img_info --format-specific --image-opts | ||||
|   | ||||
|  echo | ||||
| diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out
 | ||||
| index 139fc68177..24c33add7c 100644
 | ||||
| --- a/tests/qemu-iotests/061.out
 | ||||
| +++ b/tests/qemu-iotests/061.out
 | ||||
| @@ -545,7 +545,9 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
 | ||||
|  qemu-img: data-file can only be set for images that use an external data file | ||||
|   | ||||
|  Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IMGFMT.data | ||||
| -qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Could not open 'foo': No such file or directory
 | ||||
| +qemu-io: can't open device TEST_DIR/t.IMGFMT: Could not open 'foo': No such file or directory
 | ||||
| +read 4096/4096 bytes at offset 0
 | ||||
| +4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 | ||||
|  image: TEST_DIR/t.IMGFMT | ||||
|  file format: IMGFMT | ||||
|  virtual size: 64 MiB (67108864 bytes) | ||||
| @@ -560,7 +562,9 @@ Format specific information:
 | ||||
|      corrupt: false | ||||
|      extended l2: false | ||||
|   | ||||
| -qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'data-file' is required for this image
 | ||||
| +qemu-io: can't open device TEST_DIR/t.IMGFMT: 'data-file' is required for this image
 | ||||
| +read 4096/4096 bytes at offset 0
 | ||||
| +4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 | ||||
|  image: TEST_DIR/t.IMGFMT | ||||
|  file format: IMGFMT | ||||
|  virtual size: 64 MiB (67108864 bytes) | ||||
| -- 
 | ||||
| 2.39.3 | ||||
| 
 | ||||
							
								
								
									
										129
									
								
								SOURCES/kvm-qio-Inherit-follow_coroutine_ctx-across-TLS.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								SOURCES/kvm-qio-Inherit-follow_coroutine_ctx-across-TLS.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,129 @@ | ||||
| From 69d6b5f98d665fbcb86e42df40bcc5e9c79b397f Mon Sep 17 00:00:00 2001 | ||||
| From: Eric Blake <eblake@redhat.com> | ||||
| Date: Fri, 17 May 2024 21:50:14 -0500 | ||||
| Subject: [PATCH 3/4] qio: Inherit follow_coroutine_ctx across TLS | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
| 
 | ||||
| RH-Author: Eric Blake <eblake@redhat.com> | ||||
| RH-MergeRequest: 375: Fix regression on nbd+tls | ||||
| RH-Jira: RHEL-33754 | ||||
| RH-Acked-by: Kevin Wolf <kwolf@redhat.com> | ||||
| RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com> | ||||
| RH-Commit: [3/4] 14ddea7e3c81898bb3fe4be51a40749d67a5c0c0 (ebblake/qemu-kvm) | ||||
| 
 | ||||
| Since qemu 8.2, the combination of NBD + TLS + iothread crashes on an | ||||
| assertion failure: | ||||
| 
 | ||||
| qemu-kvm: ../io/channel.c:534: void qio_channel_restart_read(void *): Assertion `qemu_get_current_aio_context() == qemu_coroutine_get_aio_context(co)' failed. | ||||
| 
 | ||||
| It turns out that when we removed AioContext locking, we did so by | ||||
| having NBD tell its qio channels that it wanted to opt in to | ||||
| qio_channel_set_follow_coroutine_ctx(); but while we opted in on the | ||||
| main channel, we did not opt in on the TLS wrapper channel. | ||||
| qemu-iotests has coverage of NBD+iothread and NBD+TLS, but apparently | ||||
| no coverage of NBD+TLS+iothread, or we would have noticed this | ||||
| regression sooner.  (I'll add that in the next patch) | ||||
| 
 | ||||
| But while we could manually opt in to the TLS channel in nbd/server.c | ||||
| (a one-line change), it is more generic if all qio channels that wrap | ||||
| other channels inherit the follow status, in the same way that they | ||||
| inherit feature bits. | ||||
| 
 | ||||
| CC: Stefan Hajnoczi <stefanha@redhat.com> | ||||
| CC: Daniel P. Berrangé <berrange@redhat.com> | ||||
| CC: qemu-stable@nongnu.org | ||||
| Fixes: https://issues.redhat.com/browse/RHEL-34786 | ||||
| Fixes: 06e0f098 ("io: follow coroutine AioContext in qio_channel_yield()", v8.2.0) | ||||
| Signed-off-by: Eric Blake <eblake@redhat.com> | ||||
| Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||||
| Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> | ||||
| Message-ID: <20240518025246.791593-5-eblake@redhat.com> | ||||
| (cherry picked from commit 199e84de1c903ba5aa1f7256310bbc4a20dd930b) | ||||
| Jira: https://issues.redhat.com/browse/RHEL-33754 | ||||
| Signed-off-by: Eric Blake <eblake@redhat.com> | ||||
| ---
 | ||||
|  io/channel-tls.c     | 26 +++++++++++++++----------- | ||||
|  io/channel-websock.c |  1 + | ||||
|  2 files changed, 16 insertions(+), 11 deletions(-) | ||||
| 
 | ||||
| diff --git a/io/channel-tls.c b/io/channel-tls.c
 | ||||
| index 58fe1aceee..a8ad89c3d1 100644
 | ||||
| --- a/io/channel-tls.c
 | ||||
| +++ b/io/channel-tls.c
 | ||||
| @@ -69,37 +69,40 @@ qio_channel_tls_new_server(QIOChannel *master,
 | ||||
|                             const char *aclname, | ||||
|                             Error **errp) | ||||
|  { | ||||
| -    QIOChannelTLS *ioc;
 | ||||
| +    QIOChannelTLS *tioc;
 | ||||
| +    QIOChannel *ioc;
 | ||||
|   | ||||
| -    ioc = QIO_CHANNEL_TLS(object_new(TYPE_QIO_CHANNEL_TLS));
 | ||||
| +    tioc = QIO_CHANNEL_TLS(object_new(TYPE_QIO_CHANNEL_TLS));
 | ||||
| +    ioc = QIO_CHANNEL(tioc);
 | ||||
|   | ||||
| -    ioc->master = master;
 | ||||
| +    tioc->master = master;
 | ||||
| +    ioc->follow_coroutine_ctx = master->follow_coroutine_ctx;
 | ||||
|      if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) { | ||||
| -        qio_channel_set_feature(QIO_CHANNEL(ioc), QIO_CHANNEL_FEATURE_SHUTDOWN);
 | ||||
| +        qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN);
 | ||||
|      } | ||||
|      object_ref(OBJECT(master)); | ||||
|   | ||||
| -    ioc->session = qcrypto_tls_session_new(
 | ||||
| +    tioc->session = qcrypto_tls_session_new(
 | ||||
|          creds, | ||||
|          NULL, | ||||
|          aclname, | ||||
|          QCRYPTO_TLS_CREDS_ENDPOINT_SERVER, | ||||
|          errp); | ||||
| -    if (!ioc->session) {
 | ||||
| +    if (!tioc->session) {
 | ||||
|          goto error; | ||||
|      } | ||||
|   | ||||
|      qcrypto_tls_session_set_callbacks( | ||||
| -        ioc->session,
 | ||||
| +        tioc->session,
 | ||||
|          qio_channel_tls_write_handler, | ||||
|          qio_channel_tls_read_handler, | ||||
| -        ioc);
 | ||||
| +        tioc);
 | ||||
|   | ||||
| -    trace_qio_channel_tls_new_server(ioc, master, creds, aclname);
 | ||||
| -    return ioc;
 | ||||
| +    trace_qio_channel_tls_new_server(tioc, master, creds, aclname);
 | ||||
| +    return tioc;
 | ||||
|   | ||||
|   error: | ||||
| -    object_unref(OBJECT(ioc));
 | ||||
| +    object_unref(OBJECT(tioc));
 | ||||
|      return NULL; | ||||
|  } | ||||
|   | ||||
| @@ -116,6 +119,7 @@ qio_channel_tls_new_client(QIOChannel *master,
 | ||||
|      ioc = QIO_CHANNEL(tioc); | ||||
|   | ||||
|      tioc->master = master; | ||||
| +    ioc->follow_coroutine_ctx = master->follow_coroutine_ctx;
 | ||||
|      if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) { | ||||
|          qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN); | ||||
|      } | ||||
| diff --git a/io/channel-websock.c b/io/channel-websock.c
 | ||||
| index a12acc27cf..de39f0d182 100644
 | ||||
| --- a/io/channel-websock.c
 | ||||
| +++ b/io/channel-websock.c
 | ||||
| @@ -883,6 +883,7 @@ qio_channel_websock_new_server(QIOChannel *master)
 | ||||
|      ioc = QIO_CHANNEL(wioc); | ||||
|   | ||||
|      wioc->master = master; | ||||
| +    ioc->follow_coroutine_ctx = master->follow_coroutine_ctx;
 | ||||
|      if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) { | ||||
|          qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN); | ||||
|      } | ||||
| -- 
 | ||||
| 2.39.3 | ||||
| 
 | ||||
| @ -1,4 +1,4 @@ | ||||
| From 2ce6cff94df2650c460f809e5ad263f1d22507c0 Mon Sep 17 00:00:00 2001 | ||||
| From ccd8ffa5cd7f9bcfddeda7a9fa1ad86d4bad870e Mon Sep 17 00:00:00 2001 | ||||
| From: Cindy Lu <lulu@redhat.com> | ||||
| Date: Fri, 12 Apr 2024 14:26:55 +0800 | ||||
| Subject: [PATCH] virtio-pci: fix use of a released vector | ||||
| @ -6,6 +6,13 @@ MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
| 
 | ||||
| RH-Author: Cindy Lu <lulu@redhat.com> | ||||
| RH-MergeRequest: 366: virtio-pci: fix use of a released vector | ||||
| RH-Jira: RHEL-32837 | ||||
| RH-Acked-by: Laurent Vivier <lvivier@redhat.com> | ||||
| RH-Acked-by: Jason Wang <jasowang@redhat.com> | ||||
| RH-Commit: [1/1] edd26ffb8727635310aed42e42925afe87df2287 | ||||
| 
 | ||||
| During the booting process of the non-standard image, the behavior of the | ||||
| called function in qemu is as follows: | ||||
| 
 | ||||
| @ -82,12 +89,14 @@ Cc: Lei Yang <leiyang@redhat.com> | ||||
| Cc: Jason Wang <jasowang@redhat.com> | ||||
| Signed-off-by: Michael S. Tsirkin <mst@redhat.com> | ||||
| Tested-by: Cindy Lu <lulu@redhat.com> | ||||
| (cherry picked from commit 2ce6cff94df2650c460f809e5ad263f1d22507c0) | ||||
| Signed-off-by: Cindy Lu <lulu@redhat.com> | ||||
| ---
 | ||||
|  hw/virtio/virtio-pci.c | 37 +++++++++++++++++++++++++++++++++++-- | ||||
|  1 file changed, 35 insertions(+), 2 deletions(-) | ||||
| 
 | ||||
| diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
 | ||||
| index cb6940fc0e92..cb159fd0785c 100644
 | ||||
| index e433879542..08faefe29a 100644
 | ||||
| --- a/hw/virtio/virtio-pci.c
 | ||||
| +++ b/hw/virtio/virtio-pci.c
 | ||||
| @@ -1424,6 +1424,38 @@ static int virtio_pci_add_mem_cap(VirtIOPCIProxy *proxy,
 | ||||
| @ -148,3 +157,6 @@ index cb6940fc0e92..cb159fd0785c 100644 | ||||
|          break; | ||||
|      case VIRTIO_PCI_COMMON_Q_ENABLE: | ||||
|          if (val == 1) { | ||||
| -- 
 | ||||
| 2.39.3 | ||||
| 
 | ||||
| @ -149,7 +149,7 @@ Obsoletes: %{name}-block-ssh <= %{epoch}:%{version}                    \ | ||||
| Summary: QEMU is a machine emulator and virtualizer | ||||
| Name: qemu-kvm | ||||
| Version: 8.2.0 | ||||
| Release: 11%{?rcrel}%{?dist}%{?cc_suffix}.2.alma.1 | ||||
| Release: 11%{?rcrel}%{?dist}%{?cc_suffix}.4 | ||||
| # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped | ||||
| # Epoch 15 used for RHEL 8 | ||||
| # Epoch 17 used for RHEL 9 (due to release versioning offset in RHEL 8.5) | ||||
| @ -610,12 +610,26 @@ Patch175: kvm-Revert-chardev-use-a-child-source-for-qio-input-sour.patch | ||||
| Patch176: kvm-coroutine-cap-per-thread-local-pool-size.patch | ||||
| # For RHEL-28947 - Qemu crashing with "failed to set up stack guard page: Cannot allocate memory" | ||||
| Patch177: kvm-coroutine-reserve-5-000-mappings.patch | ||||
| 
 | ||||
| # Patches were taken from: | ||||
| # https://github.com/qemu/qemu/commit/e34f4d87e8d47b0a65cb663aaf7bef60c2112d36 | ||||
| Patch178: kvm-error-out-of-kvm_irqchip_add_msi_route-in-case.patch | ||||
| # https://github.com/qemu/qemu/commit/2ce6cff94df2650c460f809e5ad263f1d22507c0 | ||||
| Patch179: virtio-pci-fix-use-of-a-released-vector.patch | ||||
| # For RHEL-32837 - qemu-kvm running Vyatta hits assert when doing KVM_SET_GSI_ROUTING [rhel-9.4.z] | ||||
| Patch178: kvm-virtio-pci-fix-use-of-a-released-vector.patch | ||||
| # For RHEL-32990 - qemu crash with kvm_irqchip_commit_routes: Assertion `ret == 0' failed if booting with many virtio disks and vcpus [rhel-9.4.z] | ||||
| Patch179: kvm-kvm-error-out-of-kvm_irqchip_add_msi_route-in-case-o.patch | ||||
| # For RHEL-33754 - Qemu hang when quit dst vm after storage migration(nbd+tls) [rhel-9.4.z] | ||||
| Patch180: kvm-nbd-server-do-not-poll-within-a-coroutine-context.patch | ||||
| # For RHEL-33754 - Qemu hang when quit dst vm after storage migration(nbd+tls) [rhel-9.4.z] | ||||
| Patch181: kvm-nbd-server-Mark-negotiation-functions-as-coroutine_f.patch | ||||
| # For RHEL-33754 - Qemu hang when quit dst vm after storage migration(nbd+tls) [rhel-9.4.z] | ||||
| Patch182: kvm-qio-Inherit-follow_coroutine_ctx-across-TLS.patch | ||||
| # For RHEL-33754 - Qemu hang when quit dst vm after storage migration(nbd+tls) [rhel-9.4.z] | ||||
| Patch183: kvm-iotests-test-NBD-TLS-iothread.patch | ||||
| # For RHEL-35610 | ||||
| Patch184: kvm-qcow2-Don-t-open-data_file-with-BDRV_O_NO_IO.patch | ||||
| # For RHEL-35610 | ||||
| Patch185: kvm-iotests-244-Don-t-store-data-file-with-protocol-in-i.patch | ||||
| # For RHEL-35610 | ||||
| Patch186: kvm-iotests-270-Don-t-store-data-file-with-json-prefix-i.patch | ||||
| # For RHEL-35610 | ||||
| Patch187: kvm-block-Parse-filenames-only-when-explicitly-requested.patch | ||||
| 
 | ||||
| %if %{have_clang} | ||||
| BuildRequires: clang | ||||
| @ -1677,10 +1691,27 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ | ||||
| %endif | ||||
| 
 | ||||
| %changelog | ||||
| * Thu Jun 13 2024 Eduard Abdullin <eabdullin@almalinux.org> - 8.2.0-11.2.alma.1 | ||||
| - kvm: error out of kvm_irqchip_add_msi_route() in case of full | ||||
|  route table | ||||
| - virtio-pci: fix use of a released vector | ||||
| * Wed Jun 19 2024 Miroslav Rezanina <mrezanin@redhat.com> - 8.2.0-11.el9_4.4 | ||||
| - Fixing CVE-2024-4467 | ||||
| - Resolves: RHEL-35610 | ||||
| 
 | ||||
| * Fri Jun 07 2024 Miroslav Rezanina <mrezanin@redhat.com> - 8.2.0-11.el9_4.3 | ||||
| - kvm-nbd-server-do-not-poll-within-a-coroutine-context.patch [RHEL-33754] | ||||
| - kvm-nbd-server-Mark-negotiation-functions-as-coroutine_f.patch [RHEL-33754] | ||||
| - kvm-qio-Inherit-follow_coroutine_ctx-across-TLS.patch [RHEL-33754] | ||||
| - kvm-iotests-test-NBD-TLS-iothread.patch [RHEL-33754] | ||||
| - Resolves: RHEL-33754 | ||||
|   (Qemu hang when quit dst vm after storage migration(nbd+tls) [rhel-9.4.z]) | ||||
| 
 | ||||
| * Mon May 20 2024 Miroslav Rezanina <mrezanin@redhat.com> - 8.2.0-11.el9_4.2 | ||||
| - kvm-kvm-error-out-of-kvm_irqchip_add_msi_route-in-case-o.patch [RHEL-32990] | ||||
| - Resolves: RHEL-32990 | ||||
|   (qemu crash with kvm_irqchip_commit_routes: Assertion `ret == 0' failed if booting with many virtio disks and vcpus [rhel-9.4.z]) | ||||
| 
 | ||||
| * Thu Apr 18 2024 Miroslav Rezanina <mrezanin@redhat.com> - 8.2.0-11.el9_4.1 | ||||
| - kvm-virtio-pci-fix-use-of-a-released-vector.patch [RHEL-32837] | ||||
| - Resolves: RHEL-32837 | ||||
|   (qemu-kvm running Vyatta hits assert when doing KVM_SET_GSI_ROUTING [rhel-9.4.z]) | ||||
| 
 | ||||
| * Tue Mar 26 2024 Miroslav Rezanina <mrezanin@redhat.com> - 8.2.0-11 | ||||
| - kvm-coroutine-cap-per-thread-local-pool-size.patch [RHEL-28947] | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user