* [PULL 01/17] meson: sort C warning flags alphabetically
2024-02-09 14:04 [PULL 00/17] Misc fixes patches Daniel P. Berrangé
@ 2024-02-09 14:04 ` Daniel P. Berrangé
2024-02-09 14:04 ` [PULL 02/17] crypto: Introduce SM4 symmetric cipher algorithm Daniel P. Berrangé
` (16 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Daniel P. Berrangé @ 2024-02-09 14:04 UTC (permalink / raw)
To: qemu-devel
Cc: Hanna Reitz, Gerd Hoffmann, Marc-André Lureau,
Markus Armbruster, Cleber Rosa, Paolo Bonzini, Eric Blake,
Philippe Mathieu-Daudé, Eduardo Habkost, Stefan Weil,
Kevin Wolf, Thomas Huth, Hyman Huang, Richard Henderson,
John Snow, qemu-block, Daniel P. Berrangé
When scanning the list of warning flags to see if one is present, it is
helpful if they are in alphabetical order. It is further helpful to
separate out the 'no-' prefixed warnings.
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
meson.build | 40 +++++++++++++++++++++-------------------
1 file changed, 21 insertions(+), 19 deletions(-)
diff --git a/meson.build b/meson.build
index e5d6f2d057..74d3aa0b12 100644
--- a/meson.build
+++ b/meson.build
@@ -571,36 +571,38 @@ qemu_common_flags += cc.get_supported_arguments(hardening_flags)
add_global_arguments(qemu_common_flags, native: false, language: all_languages)
add_global_link_arguments(qemu_ldflags, native: false, language: all_languages)
-# Collect warnings that we want to enable
-
+# Collect warning flags we want to set, sorted alphabetically
warn_flags = [
- '-Wundef',
- '-Wwrite-strings',
- '-Wmissing-prototypes',
- '-Wstrict-prototypes',
- '-Wredundant-decls',
- '-Wold-style-declaration',
- '-Wold-style-definition',
- '-Wtype-limits',
- '-Wformat-security',
- '-Wformat-y2k',
- '-Winit-self',
- '-Wignored-qualifiers',
+ # First enable interesting warnings
'-Wempty-body',
- '-Wnested-externs',
'-Wendif-labels',
'-Wexpansion-to-defined',
+ '-Wformat-security',
+ '-Wformat-y2k',
+ '-Wignored-qualifiers',
'-Wimplicit-fallthrough=2',
+ '-Winit-self',
'-Wmissing-format-attribute',
+ '-Wmissing-prototypes',
+ '-Wnested-externs',
+ '-Wold-style-declaration',
+ '-Wold-style-definition',
+ '-Wredundant-decls',
+ '-Wshadow=local',
+ '-Wstrict-prototypes',
+ '-Wtype-limits',
+ '-Wundef',
+ '-Wwrite-strings',
+
+ # Then disable some undesirable warnings
+ '-Wno-gnu-variable-sized-type-not-at-end',
'-Wno-initializer-overrides',
'-Wno-missing-include-dirs',
+ '-Wno-psabi',
'-Wno-shift-negative-value',
'-Wno-string-plus-int',
- '-Wno-typedef-redefinition',
'-Wno-tautological-type-limit-compare',
- '-Wno-psabi',
- '-Wno-gnu-variable-sized-type-not-at-end',
- '-Wshadow=local',
+ '-Wno-typedef-redefinition',
]
if host_os != 'darwin'
--
2.43.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PULL 02/17] crypto: Introduce SM4 symmetric cipher algorithm
2024-02-09 14:04 [PULL 00/17] Misc fixes patches Daniel P. Berrangé
2024-02-09 14:04 ` [PULL 01/17] meson: sort C warning flags alphabetically Daniel P. Berrangé
@ 2024-02-09 14:04 ` Daniel P. Berrangé
2024-06-07 14:27 ` Peter Maydell
2024-02-09 14:04 ` [PULL 03/17] qemu_init: increase NOFILE soft limit on POSIX Daniel P. Berrangé
` (15 subsequent siblings)
17 siblings, 1 reply; 20+ messages in thread
From: Daniel P. Berrangé @ 2024-02-09 14:04 UTC (permalink / raw)
To: qemu-devel
Cc: Hanna Reitz, Gerd Hoffmann, Marc-André Lureau,
Markus Armbruster, Cleber Rosa, Paolo Bonzini, Eric Blake,
Philippe Mathieu-Daudé, Eduardo Habkost, Stefan Weil,
Kevin Wolf, Thomas Huth, Hyman Huang, Richard Henderson,
John Snow, qemu-block, Daniel P. Berrangé
From: Hyman Huang <yong.huang@smartx.com>
Introduce the SM4 cipher algorithms (OSCCA GB/T 32907-2016).
SM4 (GBT.32907-2016) is a cryptographic standard issued by the
Organization of State Commercial Administration of China (OSCCA)
as an authorized cryptographic algorithms for the use within China.
Detect the SM4 cipher algorithms and enable the feature silently
if it is available.
Signed-off-by: Hyman Huang <yong.huang@smartx.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
crypto/block-luks.c | 11 ++++++++
crypto/cipher-gcrypt.c.inc | 8 ++++++
crypto/cipher-nettle.c.inc | 49 +++++++++++++++++++++++++++++++++
crypto/cipher.c | 6 ++++
meson.build | 26 +++++++++++++++++
qapi/crypto.json | 5 +++-
tests/unit/test-crypto-cipher.c | 13 +++++++++
7 files changed, 117 insertions(+), 1 deletion(-)
diff --git a/crypto/block-luks.c b/crypto/block-luks.c
index fb01ec38bb..f0813d69b4 100644
--- a/crypto/block-luks.c
+++ b/crypto/block-luks.c
@@ -95,12 +95,23 @@ qcrypto_block_luks_cipher_size_map_twofish[] = {
{ 0, 0 },
};
+#ifdef CONFIG_CRYPTO_SM4
+static const QCryptoBlockLUKSCipherSizeMap
+qcrypto_block_luks_cipher_size_map_sm4[] = {
+ { 16, QCRYPTO_CIPHER_ALG_SM4},
+ { 0, 0 },
+};
+#endif
+
static const QCryptoBlockLUKSCipherNameMap
qcrypto_block_luks_cipher_name_map[] = {
{ "aes", qcrypto_block_luks_cipher_size_map_aes },
{ "cast5", qcrypto_block_luks_cipher_size_map_cast5 },
{ "serpent", qcrypto_block_luks_cipher_size_map_serpent },
{ "twofish", qcrypto_block_luks_cipher_size_map_twofish },
+#ifdef CONFIG_CRYPTO_SM4
+ { "sm4", qcrypto_block_luks_cipher_size_map_sm4},
+#endif
};
QEMU_BUILD_BUG_ON(sizeof(struct QCryptoBlockLUKSKeySlot) != 48);
diff --git a/crypto/cipher-gcrypt.c.inc b/crypto/cipher-gcrypt.c.inc
index a6a0117717..1377cbaf14 100644
--- a/crypto/cipher-gcrypt.c.inc
+++ b/crypto/cipher-gcrypt.c.inc
@@ -35,6 +35,9 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
case QCRYPTO_CIPHER_ALG_SERPENT_256:
case QCRYPTO_CIPHER_ALG_TWOFISH_128:
case QCRYPTO_CIPHER_ALG_TWOFISH_256:
+#ifdef CONFIG_CRYPTO_SM4
+ case QCRYPTO_CIPHER_ALG_SM4:
+#endif
break;
default:
return false;
@@ -219,6 +222,11 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
case QCRYPTO_CIPHER_ALG_TWOFISH_256:
gcryalg = GCRY_CIPHER_TWOFISH;
break;
+#ifdef CONFIG_CRYPTO_SM4
+ case QCRYPTO_CIPHER_ALG_SM4:
+ gcryalg = GCRY_CIPHER_SM4;
+ break;
+#endif
default:
error_setg(errp, "Unsupported cipher algorithm %s",
QCryptoCipherAlgorithm_str(alg));
diff --git a/crypto/cipher-nettle.c.inc b/crypto/cipher-nettle.c.inc
index 24cc61f87b..42b39e18a2 100644
--- a/crypto/cipher-nettle.c.inc
+++ b/crypto/cipher-nettle.c.inc
@@ -33,6 +33,9 @@
#ifndef CONFIG_QEMU_PRIVATE_XTS
#include <nettle/xts.h>
#endif
+#ifdef CONFIG_CRYPTO_SM4
+#include <nettle/sm4.h>
+#endif
static inline bool qcrypto_length_check(size_t len, size_t blocksize,
Error **errp)
@@ -426,6 +429,30 @@ DEFINE_ECB_CBC_CTR_XTS(qcrypto_nettle_twofish,
QCryptoNettleTwofish, TWOFISH_BLOCK_SIZE,
twofish_encrypt_native, twofish_decrypt_native)
+#ifdef CONFIG_CRYPTO_SM4
+typedef struct QCryptoNettleSm4 {
+ QCryptoCipher base;
+ struct sm4_ctx key[2];
+} QCryptoNettleSm4;
+
+static void sm4_encrypt_native(void *ctx, size_t length,
+ uint8_t *dst, const uint8_t *src)
+{
+ struct sm4_ctx *keys = ctx;
+ sm4_crypt(&keys[0], length, dst, src);
+}
+
+static void sm4_decrypt_native(void *ctx, size_t length,
+ uint8_t *dst, const uint8_t *src)
+{
+ struct sm4_ctx *keys = ctx;
+ sm4_crypt(&keys[1], length, dst, src);
+}
+
+DEFINE_ECB(qcrypto_nettle_sm4,
+ QCryptoNettleSm4, SM4_BLOCK_SIZE,
+ sm4_encrypt_native, sm4_decrypt_native)
+#endif
bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
QCryptoCipherMode mode)
@@ -443,6 +470,9 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
case QCRYPTO_CIPHER_ALG_TWOFISH_128:
case QCRYPTO_CIPHER_ALG_TWOFISH_192:
case QCRYPTO_CIPHER_ALG_TWOFISH_256:
+#ifdef CONFIG_CRYPTO_SM4
+ case QCRYPTO_CIPHER_ALG_SM4:
+#endif
break;
default:
return false;
@@ -701,6 +731,25 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
return &ctx->base;
}
+#ifdef CONFIG_CRYPTO_SM4
+ case QCRYPTO_CIPHER_ALG_SM4:
+ {
+ QCryptoNettleSm4 *ctx = g_new0(QCryptoNettleSm4, 1);
+
+ switch (mode) {
+ case QCRYPTO_CIPHER_MODE_ECB:
+ ctx->base.driver = &qcrypto_nettle_sm4_driver_ecb;
+ break;
+ default:
+ goto bad_cipher_mode;
+ }
+
+ sm4_set_encrypt_key(&ctx->key[0], key);
+ sm4_set_decrypt_key(&ctx->key[1], key);
+
+ return &ctx->base;
+ }
+#endif
default:
error_setg(errp, "Unsupported cipher algorithm %s",
diff --git a/crypto/cipher.c b/crypto/cipher.c
index 74b09a5b26..5f512768ea 100644
--- a/crypto/cipher.c
+++ b/crypto/cipher.c
@@ -38,6 +38,9 @@ static const size_t alg_key_len[QCRYPTO_CIPHER_ALG__MAX] = {
[QCRYPTO_CIPHER_ALG_TWOFISH_128] = 16,
[QCRYPTO_CIPHER_ALG_TWOFISH_192] = 24,
[QCRYPTO_CIPHER_ALG_TWOFISH_256] = 32,
+#ifdef CONFIG_CRYPTO_SM4
+ [QCRYPTO_CIPHER_ALG_SM4] = 16,
+#endif
};
static const size_t alg_block_len[QCRYPTO_CIPHER_ALG__MAX] = {
@@ -53,6 +56,9 @@ static const size_t alg_block_len[QCRYPTO_CIPHER_ALG__MAX] = {
[QCRYPTO_CIPHER_ALG_TWOFISH_128] = 16,
[QCRYPTO_CIPHER_ALG_TWOFISH_192] = 16,
[QCRYPTO_CIPHER_ALG_TWOFISH_256] = 16,
+#ifdef CONFIG_CRYPTO_SM4
+ [QCRYPTO_CIPHER_ALG_SM4] = 16,
+#endif
};
static const bool mode_need_iv[QCRYPTO_CIPHER_MODE__MAX] = {
diff --git a/meson.build b/meson.build
index 74d3aa0b12..c1dc83e4c0 100644
--- a/meson.build
+++ b/meson.build
@@ -1633,6 +1633,7 @@ endif
gcrypt = not_found
nettle = not_found
hogweed = not_found
+crypto_sm4 = not_found
xts = 'none'
if get_option('nettle').enabled() and get_option('gcrypt').enabled()
@@ -1658,6 +1659,17 @@ if not gnutls_crypto.found()
cc.find_library('gpg-error', required: true)],
version: gcrypt.version())
endif
+ crypto_sm4 = gcrypt
+ # SM4 ALG is available in libgcrypt >= 1.9
+ if gcrypt.found() and not cc.links('''
+ #include <gcrypt.h>
+ int main(void) {
+ gcry_cipher_hd_t handler;
+ gcry_cipher_open(&handler, GCRY_CIPHER_SM4, GCRY_CIPHER_MODE_ECB, 0);
+ return 0;
+ }''', dependencies: gcrypt)
+ crypto_sm4 = not_found
+ endif
endif
if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
nettle = dependency('nettle', version: '>=3.4',
@@ -1666,6 +1678,18 @@ if not gnutls_crypto.found()
if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
xts = 'private'
endif
+ crypto_sm4 = nettle
+ # SM4 ALG is available in nettle >= 3.9
+ if nettle.found() and not cc.links('''
+ #include <nettle/sm4.h>
+ int main(void) {
+ struct sm4_ctx ctx;
+ unsigned char key[16] = {0};
+ sm4_set_encrypt_key(&ctx, key);
+ return 0;
+ }''', dependencies: nettle)
+ crypto_sm4 = not_found
+ endif
endif
endif
@@ -2267,6 +2291,7 @@ config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
config_host_data.set('CONFIG_TASN1', tasn1.found())
config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
config_host_data.set('CONFIG_NETTLE', nettle.found())
+config_host_data.set('CONFIG_CRYPTO_SM4', crypto_sm4.found())
config_host_data.set('CONFIG_HOGWEED', hogweed.found())
config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
@@ -4306,6 +4331,7 @@ summary_info += {'nettle': nettle}
if nettle.found()
summary_info += {' XTS': xts != 'private'}
endif
+summary_info += {'SM4 ALG support': crypto_sm4}
summary_info += {'AF_ALG support': have_afalg}
summary_info += {'rng-none': get_option('rng_none')}
summary_info += {'Linux keyring': have_keyring}
diff --git a/qapi/crypto.json b/qapi/crypto.json
index fd3d46ebd1..2f2aeff5fd 100644
--- a/qapi/crypto.json
+++ b/qapi/crypto.json
@@ -94,6 +94,8 @@
#
# @twofish-256: Twofish with 256 bit / 32 byte keys
#
+# @sm4: SM4 with 128 bit / 16 byte keys (since 9.0)
+#
# Since: 2.6
##
{ 'enum': 'QCryptoCipherAlgorithm',
@@ -102,7 +104,8 @@
'des', '3des',
'cast5-128',
'serpent-128', 'serpent-192', 'serpent-256',
- 'twofish-128', 'twofish-192', 'twofish-256']}
+ 'twofish-128', 'twofish-192', 'twofish-256',
+ 'sm4']}
##
# @QCryptoCipherMode:
diff --git a/tests/unit/test-crypto-cipher.c b/tests/unit/test-crypto-cipher.c
index d9d9d078ff..11ab1a54fc 100644
--- a/tests/unit/test-crypto-cipher.c
+++ b/tests/unit/test-crypto-cipher.c
@@ -382,6 +382,19 @@ static QCryptoCipherTestData test_data[] = {
.plaintext = "90afe91bb288544f2c32dc239b2635e6",
.ciphertext = "6cb4561c40bf0a9705931cb6d408e7fa",
},
+#ifdef CONFIG_CRYPTO_SM4
+ {
+ /* SM4, GB/T 32907-2016, Appendix A.1 */
+ .path = "/crypto/cipher/sm4",
+ .alg = QCRYPTO_CIPHER_ALG_SM4,
+ .mode = QCRYPTO_CIPHER_MODE_ECB,
+ .key = "0123456789abcdeffedcba9876543210",
+ .plaintext =
+ "0123456789abcdeffedcba9876543210",
+ .ciphertext =
+ "681edf34d206965e86b3e94f536e4246",
+ },
+#endif
{
/* #1 32 byte key, 32 byte PTX */
.path = "/crypto/cipher/aes-xts-128-1",
--
2.43.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* Re: [PULL 02/17] crypto: Introduce SM4 symmetric cipher algorithm
2024-02-09 14:04 ` [PULL 02/17] crypto: Introduce SM4 symmetric cipher algorithm Daniel P. Berrangé
@ 2024-06-07 14:27 ` Peter Maydell
0 siblings, 0 replies; 20+ messages in thread
From: Peter Maydell @ 2024-06-07 14:27 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: qemu-devel, Hanna Reitz, Gerd Hoffmann, Marc-André Lureau,
Markus Armbruster, Cleber Rosa, Paolo Bonzini, Eric Blake,
Philippe Mathieu-Daudé, Eduardo Habkost, Stefan Weil,
Kevin Wolf, Thomas Huth, Hyman Huang, Richard Henderson,
John Snow, qemu-block
On Fri, 9 Feb 2024 at 14:07, Daniel P. Berrangé <berrange@redhat.com> wrote:
>
> From: Hyman Huang <yong.huang@smartx.com>
>
> Introduce the SM4 cipher algorithms (OSCCA GB/T 32907-2016).
>
> SM4 (GBT.32907-2016) is a cryptographic standard issued by the
> Organization of State Commercial Administration of China (OSCCA)
> as an authorized cryptographic algorithms for the use within China.
>
> Detect the SM4 cipher algorithms and enable the feature silently
> if it is available.
>
> Signed-off-by: Hyman Huang <yong.huang@smartx.com>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Hi; Coverity points out an issue in this code (CID 1546884):
> @@ -701,6 +731,25 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
>
> return &ctx->base;
> }
> +#ifdef CONFIG_CRYPTO_SM4
> + case QCRYPTO_CIPHER_ALG_SM4:
> + {
> + QCryptoNettleSm4 *ctx = g_new0(QCryptoNettleSm4, 1);
Here we allocate memory...
> +
> + switch (mode) {
> + case QCRYPTO_CIPHER_MODE_ECB:
> + ctx->base.driver = &qcrypto_nettle_sm4_driver_ecb;
> + break;
> + default:
> + goto bad_cipher_mode;
...but here we may jump to bad_cipher_mode, resulting in
the memory being leaked, because we never free it.
> + }
> +
This could be fixed by not doing the g_new0() until this
point when we know we aren't going to fail. This is what we
do for the other cipher cases in this file that have a switch
where the default for mode is a jump to bad_cipher_mode.
(PS: is it intentional that for some of these ciphers
an unknown mode value is an error returned to the caller
via bad_cipher_mode, and for others it is a g_assert_not_reached()?)
> + sm4_set_encrypt_key(&ctx->key[0], key);
> + sm4_set_decrypt_key(&ctx->key[1], key);
> +
> + return &ctx->base;
> + }
> +#endif
thanks
-- PMM
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PULL 03/17] qemu_init: increase NOFILE soft limit on POSIX
2024-02-09 14:04 [PULL 00/17] Misc fixes patches Daniel P. Berrangé
2024-02-09 14:04 ` [PULL 01/17] meson: sort C warning flags alphabetically Daniel P. Berrangé
2024-02-09 14:04 ` [PULL 02/17] crypto: Introduce SM4 symmetric cipher algorithm Daniel P. Berrangé
@ 2024-02-09 14:04 ` Daniel P. Berrangé
2024-02-09 14:04 ` [PULL 04/17] ui: drop VNC feature _MASK constants Daniel P. Berrangé
` (14 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Daniel P. Berrangé @ 2024-02-09 14:04 UTC (permalink / raw)
To: qemu-devel
Cc: Hanna Reitz, Gerd Hoffmann, Marc-André Lureau,
Markus Armbruster, Cleber Rosa, Paolo Bonzini, Eric Blake,
Philippe Mathieu-Daudé, Eduardo Habkost, Stefan Weil,
Kevin Wolf, Thomas Huth, Hyman Huang, Richard Henderson,
John Snow, qemu-block, Daniel P. Berrangé, Fiona Ebner
From: Fiona Ebner <f.ebner@proxmox.com>
In many configurations, e.g. multiple vNICs with multiple queues or
with many Ceph OSDs, the default soft limit of 1024 is not enough.
QEMU is supposed to work fine with file descriptors >= 1024 and does
not use select() on POSIX. Bump the soft limit to the allowed hard
limit to avoid issues with the aforementioned configurations.
Of course the limit could be raised from the outside, but the man page
of systemd.exec states about 'LimitNOFILE=':
> Don't use.
> [...]
> Typically applications should increase their soft limit to the hard
> limit on their own, if they are OK with working with file
> descriptors above 1023,
If the soft limit is already the same as the hard limit, avoid the
superfluous setrlimit call. This can avoid a warning with a strict
seccomp filter blocking setrlimit if NOFILE was already raised before
executing QEMU.
Buglink: https://bugzilla.proxmox.com/show_bug.cgi?id=4507
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
include/sysemu/os-posix.h | 1 +
include/sysemu/os-win32.h | 5 +++++
os-posix.c | 22 ++++++++++++++++++++++
system/vl.c | 2 ++
4 files changed, 30 insertions(+)
diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h
index dff32ae185..b881ac6c6f 100644
--- a/include/sysemu/os-posix.h
+++ b/include/sysemu/os-posix.h
@@ -51,6 +51,7 @@ bool is_daemonized(void);
void os_daemonize(void);
bool os_set_runas(const char *user_id);
void os_set_chroot(const char *path);
+void os_setup_limits(void);
void os_setup_post(void);
int os_mlock(void);
diff --git a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h
index 1047d260cb..b82a5d3ad9 100644
--- a/include/sysemu/os-win32.h
+++ b/include/sysemu/os-win32.h
@@ -128,6 +128,11 @@ static inline int os_mlock(void)
return -ENOSYS;
}
+static inline void os_setup_limits(void)
+{
+ return;
+}
+
#define fsync _commit
#if !defined(lseek)
diff --git a/os-posix.c b/os-posix.c
index 52ef6990ff..a4284e2c07 100644
--- a/os-posix.c
+++ b/os-posix.c
@@ -24,6 +24,7 @@
*/
#include "qemu/osdep.h"
+#include <sys/resource.h>
#include <sys/wait.h>
#include <pwd.h>
#include <grp.h>
@@ -256,6 +257,27 @@ void os_daemonize(void)
}
}
+void os_setup_limits(void)
+{
+ struct rlimit nofile;
+
+ if (getrlimit(RLIMIT_NOFILE, &nofile) < 0) {
+ warn_report("unable to query NOFILE limit: %s", strerror(errno));
+ return;
+ }
+
+ if (nofile.rlim_cur == nofile.rlim_max) {
+ return;
+ }
+
+ nofile.rlim_cur = nofile.rlim_max;
+
+ if (setrlimit(RLIMIT_NOFILE, &nofile) < 0) {
+ warn_report("unable to set NOFILE limit: %s", strerror(errno));
+ return;
+ }
+}
+
void os_setup_post(void)
{
int fd = 0;
diff --git a/system/vl.c b/system/vl.c
index 2a0bd08ff1..95cd2d91c4 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -2778,6 +2778,8 @@ void qemu_init(int argc, char **argv)
error_init(argv[0]);
qemu_init_exec_dir(argv[0]);
+ os_setup_limits();
+
qemu_init_arch_modules();
qemu_init_subsystems();
--
2.43.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PULL 04/17] ui: drop VNC feature _MASK constants
2024-02-09 14:04 [PULL 00/17] Misc fixes patches Daniel P. Berrangé
` (2 preceding siblings ...)
2024-02-09 14:04 ` [PULL 03/17] qemu_init: increase NOFILE soft limit on POSIX Daniel P. Berrangé
@ 2024-02-09 14:04 ` Daniel P. Berrangé
2024-02-09 14:04 ` [PULL 05/17] softmmu: remove obsolete comment about libvirt timeouts Daniel P. Berrangé
` (13 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Daniel P. Berrangé @ 2024-02-09 14:04 UTC (permalink / raw)
To: qemu-devel
Cc: Hanna Reitz, Gerd Hoffmann, Marc-André Lureau,
Markus Armbruster, Cleber Rosa, Paolo Bonzini, Eric Blake,
Philippe Mathieu-Daudé, Eduardo Habkost, Stefan Weil,
Kevin Wolf, Thomas Huth, Hyman Huang, Richard Henderson,
John Snow, qemu-block, Daniel P. Berrangé
Each VNC feature enum entry has a corresponding _MASK constant
which is the bit-shifted value. It is very easy for contributors
to accidentally use the _MASK constant, instead of the non-_MASK
constant, or the reverse. No compiler warning is possible and
it'll just silently do the wrong thing at runtime.
By introducing the vnc_set_feature helper method, we can drop
all the _MASK constants and thus prevent any future accidents.
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
ui/vnc.c | 34 +++++++++++++++++-----------------
ui/vnc.h | 22 +++++-----------------
2 files changed, 22 insertions(+), 34 deletions(-)
diff --git a/ui/vnc.c b/ui/vnc.c
index 4f23a0fa79..3db87fd89c 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -2144,16 +2144,16 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
vs->vnc_encoding = enc;
break;
case VNC_ENCODING_HEXTILE:
- vs->features |= VNC_FEATURE_HEXTILE_MASK;
+ vnc_set_feature(vs, VNC_FEATURE_HEXTILE);
vs->vnc_encoding = enc;
break;
case VNC_ENCODING_TIGHT:
- vs->features |= VNC_FEATURE_TIGHT_MASK;
+ vnc_set_feature(vs, VNC_FEATURE_TIGHT);
vs->vnc_encoding = enc;
break;
#ifdef CONFIG_PNG
case VNC_ENCODING_TIGHT_PNG:
- vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
+ vnc_set_feature(vs, VNC_FEATURE_TIGHT_PNG);
vs->vnc_encoding = enc;
break;
#endif
@@ -2163,57 +2163,57 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
* So prioritize ZRLE, even if the client hints that it prefers
* ZLIB.
*/
- if ((vs->features & VNC_FEATURE_ZRLE_MASK) == 0) {
- vs->features |= VNC_FEATURE_ZLIB_MASK;
+ if (!vnc_has_feature(vs, VNC_FEATURE_ZRLE)) {
+ vnc_set_feature(vs, VNC_FEATURE_ZLIB);
vs->vnc_encoding = enc;
}
break;
case VNC_ENCODING_ZRLE:
- vs->features |= VNC_FEATURE_ZRLE_MASK;
+ vnc_set_feature(vs, VNC_FEATURE_ZRLE);
vs->vnc_encoding = enc;
break;
case VNC_ENCODING_ZYWRLE:
- vs->features |= VNC_FEATURE_ZYWRLE_MASK;
+ vnc_set_feature(vs, VNC_FEATURE_ZYWRLE);
vs->vnc_encoding = enc;
break;
case VNC_ENCODING_DESKTOPRESIZE:
- vs->features |= VNC_FEATURE_RESIZE_MASK;
+ vnc_set_feature(vs, VNC_FEATURE_RESIZE);
break;
case VNC_ENCODING_DESKTOP_RESIZE_EXT:
- vs->features |= VNC_FEATURE_RESIZE_EXT_MASK;
+ vnc_set_feature(vs, VNC_FEATURE_RESIZE_EXT);
break;
case VNC_ENCODING_POINTER_TYPE_CHANGE:
- vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
+ vnc_set_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE);
break;
case VNC_ENCODING_RICH_CURSOR:
- vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
+ vnc_set_feature(vs, VNC_FEATURE_RICH_CURSOR);
break;
case VNC_ENCODING_ALPHA_CURSOR:
- vs->features |= VNC_FEATURE_ALPHA_CURSOR_MASK;
+ vnc_set_feature(vs, VNC_FEATURE_ALPHA_CURSOR);
break;
case VNC_ENCODING_EXT_KEY_EVENT:
send_ext_key_event_ack(vs);
break;
case VNC_ENCODING_AUDIO:
if (vs->vd->audio_state) {
- vs->features |= VNC_FEATURE_AUDIO_MASK;
+ vnc_set_feature(vs, VNC_FEATURE_AUDIO);
send_ext_audio_ack(vs);
}
break;
case VNC_ENCODING_WMVi:
- vs->features |= VNC_FEATURE_WMVI_MASK;
+ vnc_set_feature(vs, VNC_FEATURE_WMVI);
break;
case VNC_ENCODING_LED_STATE:
- vs->features |= VNC_FEATURE_LED_STATE_MASK;
+ vnc_set_feature(vs, VNC_FEATURE_LED_STATE);
break;
case VNC_ENCODING_XVP:
if (vs->vd->power_control) {
- vs->features |= VNC_FEATURE_XVP_MASK;
+ vnc_set_feature(vs, VNC_FEATURE_XVP);
send_xvp_message(vs, VNC_XVP_CODE_INIT);
}
break;
case VNC_ENCODING_CLIPBOARD_EXT:
- vs->features |= VNC_FEATURE_CLIPBOARD_EXT_MASK;
+ vnc_set_feature(vs, VNC_FEATURE_CLIPBOARD_EXT);
vnc_server_cut_text_caps(vs);
break;
case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
diff --git a/ui/vnc.h b/ui/vnc.h
index 96d19dce19..4521dc88f7 100644
--- a/ui/vnc.h
+++ b/ui/vnc.h
@@ -467,23 +467,6 @@ enum VncFeatures {
VNC_FEATURE_AUDIO,
};
-#define VNC_FEATURE_RESIZE_MASK (1 << VNC_FEATURE_RESIZE)
-#define VNC_FEATURE_RESIZE_EXT_MASK (1 << VNC_FEATURE_RESIZE_EXT)
-#define VNC_FEATURE_HEXTILE_MASK (1 << VNC_FEATURE_HEXTILE)
-#define VNC_FEATURE_POINTER_TYPE_CHANGE_MASK (1 << VNC_FEATURE_POINTER_TYPE_CHANGE)
-#define VNC_FEATURE_WMVI_MASK (1 << VNC_FEATURE_WMVI)
-#define VNC_FEATURE_TIGHT_MASK (1 << VNC_FEATURE_TIGHT)
-#define VNC_FEATURE_ZLIB_MASK (1 << VNC_FEATURE_ZLIB)
-#define VNC_FEATURE_RICH_CURSOR_MASK (1 << VNC_FEATURE_RICH_CURSOR)
-#define VNC_FEATURE_ALPHA_CURSOR_MASK (1 << VNC_FEATURE_ALPHA_CURSOR)
-#define VNC_FEATURE_TIGHT_PNG_MASK (1 << VNC_FEATURE_TIGHT_PNG)
-#define VNC_FEATURE_ZRLE_MASK (1 << VNC_FEATURE_ZRLE)
-#define VNC_FEATURE_ZYWRLE_MASK (1 << VNC_FEATURE_ZYWRLE)
-#define VNC_FEATURE_LED_STATE_MASK (1 << VNC_FEATURE_LED_STATE)
-#define VNC_FEATURE_XVP_MASK (1 << VNC_FEATURE_XVP)
-#define VNC_FEATURE_CLIPBOARD_EXT_MASK (1 << VNC_FEATURE_CLIPBOARD_EXT)
-#define VNC_FEATURE_AUDIO_MASK (1 << VNC_FEATURE_AUDIO)
-
/* Client -> Server message IDs */
#define VNC_MSG_CLIENT_SET_PIXEL_FORMAT 0
@@ -599,6 +582,11 @@ static inline uint32_t vnc_has_feature(VncState *vs, int feature) {
return (vs->features & (1 << feature));
}
+static inline void vnc_set_feature(VncState *vs, enum VncFeatures feature)
+{
+ vs->features |= (1 << feature);
+}
+
/* Framebuffer */
void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
int32_t encoding);
--
2.43.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PULL 05/17] softmmu: remove obsolete comment about libvirt timeouts
2024-02-09 14:04 [PULL 00/17] Misc fixes patches Daniel P. Berrangé
` (3 preceding siblings ...)
2024-02-09 14:04 ` [PULL 04/17] ui: drop VNC feature _MASK constants Daniel P. Berrangé
@ 2024-02-09 14:04 ` Daniel P. Berrangé
2024-02-09 14:04 ` [PULL 06/17] scripts: drop comment about autogenerated CPU API file Daniel P. Berrangé
` (12 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Daniel P. Berrangé @ 2024-02-09 14:04 UTC (permalink / raw)
To: qemu-devel
Cc: Hanna Reitz, Gerd Hoffmann, Marc-André Lureau,
Markus Armbruster, Cleber Rosa, Paolo Bonzini, Eric Blake,
Philippe Mathieu-Daudé, Eduardo Habkost, Stefan Weil,
Kevin Wolf, Thomas Huth, Hyman Huang, Richard Henderson,
John Snow, qemu-block, Daniel P. Berrangé, Zhao Liu
For a long time now, libvirt has pre-created the monitor connection
socket and passed the pre-opened FD into QEMU during startup. Thus
libvirt does not have any timeouts waiting for the monitor socket
to appear, it is immediately connected.
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
system/vl.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/system/vl.c b/system/vl.c
index 95cd2d91c4..a82555ae15 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -1914,7 +1914,6 @@ static bool object_create_early(const char *type)
* Allocation of large amounts of memory may delay
* chardev initialization for too long, and trigger timeouts
* on software that waits for a monitor socket to be created
- * (e.g. libvirt).
*/
if (g_str_has_prefix(type, "memory-backend-")) {
return false;
--
2.43.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PULL 06/17] scripts: drop comment about autogenerated CPU API file
2024-02-09 14:04 [PULL 00/17] Misc fixes patches Daniel P. Berrangé
` (4 preceding siblings ...)
2024-02-09 14:04 ` [PULL 05/17] softmmu: remove obsolete comment about libvirt timeouts Daniel P. Berrangé
@ 2024-02-09 14:04 ` Daniel P. Berrangé
2024-02-09 14:04 ` [PULL 07/17] docs: fix highlighting of CPU ABI header rows Daniel P. Berrangé
` (11 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Daniel P. Berrangé @ 2024-02-09 14:04 UTC (permalink / raw)
To: qemu-devel
Cc: Hanna Reitz, Gerd Hoffmann, Marc-André Lureau,
Markus Armbruster, Cleber Rosa, Paolo Bonzini, Eric Blake,
Philippe Mathieu-Daudé, Eduardo Habkost, Stefan Weil,
Kevin Wolf, Thomas Huth, Hyman Huang, Richard Henderson,
John Snow, qemu-block, Daniel P. Berrangé
The RST doc include can't be made to skip the comment indicating the CPU
CSV file is auto-generated when importing it. This comment line was
previously manually removed from the generated output that was committed.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
scripts/cpu-x86-uarch-abi.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/scripts/cpu-x86-uarch-abi.py b/scripts/cpu-x86-uarch-abi.py
index 052ddd7514..7360e55c6e 100644
--- a/scripts/cpu-x86-uarch-abi.py
+++ b/scripts/cpu-x86-uarch-abi.py
@@ -179,7 +179,6 @@
models[name]["delta"][level] = delta
def print_uarch_abi_csv():
- print("# Automatically generated from '%s'" % __file__)
print("Model,baseline,v2,v3,v4")
for name in models.keys():
print(name, end="")
--
2.43.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PULL 07/17] docs: fix highlighting of CPU ABI header rows
2024-02-09 14:04 [PULL 00/17] Misc fixes patches Daniel P. Berrangé
` (5 preceding siblings ...)
2024-02-09 14:04 ` [PULL 06/17] scripts: drop comment about autogenerated CPU API file Daniel P. Berrangé
@ 2024-02-09 14:04 ` Daniel P. Berrangé
2024-02-09 14:04 ` [PULL 08/17] docs: re-generate x86_64 ABI compatibility CSV Daniel P. Berrangé
` (10 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Daniel P. Berrangé @ 2024-02-09 14:04 UTC (permalink / raw)
To: qemu-devel
Cc: Hanna Reitz, Gerd Hoffmann, Marc-André Lureau,
Markus Armbruster, Cleber Rosa, Paolo Bonzini, Eric Blake,
Philippe Mathieu-Daudé, Eduardo Habkost, Stefan Weil,
Kevin Wolf, Thomas Huth, Hyman Huang, Richard Henderson,
John Snow, qemu-block, Daniel P. Berrangé
The 'header-rows' directive indicates how many rows in the generated
table are to be highlighted as headers. We only have one such row in
the CSV file included. This removes the accident bold highlighting
of the 'i486' CPU model.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
docs/system/cpu-models-x86.rst.inc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/system/cpu-models-x86.rst.inc b/docs/system/cpu-models-x86.rst.inc
index 7f6368f999..ba27b5683f 100644
--- a/docs/system/cpu-models-x86.rst.inc
+++ b/docs/system/cpu-models-x86.rst.inc
@@ -58,7 +58,7 @@ depending on the machine type is in use.
.. csv-table:: x86-64 ABI compatibility levels
:file: cpu-models-x86-abi.csv
:widths: 40,15,15,15,15
- :header-rows: 2
+ :header-rows: 1
Preferred CPU models for Intel x86 hosts
--
2.43.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PULL 08/17] docs: re-generate x86_64 ABI compatibility CSV
2024-02-09 14:04 [PULL 00/17] Misc fixes patches Daniel P. Berrangé
` (6 preceding siblings ...)
2024-02-09 14:04 ` [PULL 07/17] docs: fix highlighting of CPU ABI header rows Daniel P. Berrangé
@ 2024-02-09 14:04 ` Daniel P. Berrangé
2024-02-09 14:04 ` [PULL 09/17] chardev: close QIOChannel before unref'ing Daniel P. Berrangé
` (9 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Daniel P. Berrangé @ 2024-02-09 14:04 UTC (permalink / raw)
To: qemu-devel
Cc: Hanna Reitz, Gerd Hoffmann, Marc-André Lureau,
Markus Armbruster, Cleber Rosa, Paolo Bonzini, Eric Blake,
Philippe Mathieu-Daudé, Eduardo Habkost, Stefan Weil,
Kevin Wolf, Thomas Huth, Hyman Huang, Richard Henderson,
John Snow, qemu-block, Daniel P. Berrangé
This picks up the new EPYC-Genoa, SapphireRapids & GraniteRapids CPUs,
removes the now deleted Icelake-Client CPU, and adds the newer versions
of many existing CPUs.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
docs/system/cpu-models-x86-abi.csv | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/docs/system/cpu-models-x86-abi.csv b/docs/system/cpu-models-x86-abi.csv
index f3f3b60be1..38b9bae310 100644
--- a/docs/system/cpu-models-x86-abi.csv
+++ b/docs/system/cpu-models-x86-abi.csv
@@ -8,27 +8,37 @@ Cascadelake-Server-v1,✅,✅,✅,✅
Cascadelake-Server-v2,✅,✅,✅,✅
Cascadelake-Server-v3,✅,✅,✅,✅
Cascadelake-Server-v4,✅,✅,✅,✅
+Cascadelake-Server-v5,✅,✅,✅,✅
Conroe-v1,✅,,,
Cooperlake-v1,✅,✅,✅,✅
+Cooperlake-v2,✅,✅,✅,✅
Denverton-v1,✅,✅,,
Denverton-v2,✅,✅,,
+Denverton-v3,✅,✅,,
Dhyana-v1,✅,✅,✅,
+Dhyana-v2,✅,✅,✅,
+EPYC-Genoa-v1,✅,✅,✅,✅
EPYC-Milan-v1,✅,✅,✅,
+EPYC-Milan-v2,✅,✅,✅,
EPYC-Rome-v1,✅,✅,✅,
EPYC-Rome-v2,✅,✅,✅,
+EPYC-Rome-v3,✅,✅,✅,
+EPYC-Rome-v4,✅,✅,✅,
EPYC-v1,✅,✅,✅,
EPYC-v2,✅,✅,✅,
EPYC-v3,✅,✅,✅,
+EPYC-v4,✅,✅,✅,
+GraniteRapids-v1,✅,✅,✅,✅
Haswell-v1,✅,✅,✅,
Haswell-v2,✅,✅,✅,
Haswell-v3,✅,✅,✅,
Haswell-v4,✅,✅,✅,
-Icelake-Client-v1,✅,✅,✅,
-Icelake-Client-v2,✅,✅,✅,
Icelake-Server-v1,✅,✅,✅,✅
Icelake-Server-v2,✅,✅,✅,✅
Icelake-Server-v3,✅,✅,✅,✅
Icelake-Server-v4,✅,✅,✅,✅
+Icelake-Server-v5,✅,✅,✅,✅
+Icelake-Server-v6,✅,✅,✅,✅
IvyBridge-v1,✅,✅,,
IvyBridge-v2,✅,✅,,
KnightsMill-v1,✅,✅,✅,
@@ -42,15 +52,21 @@ Opteron_G5-v1,✅,✅,,
Penryn-v1,✅,,,
SandyBridge-v1,✅,✅,,
SandyBridge-v2,✅,✅,,
+SapphireRapids-v1,✅,✅,✅,✅
+SapphireRapids-v2,✅,✅,✅,✅
Skylake-Client-v1,✅,✅,✅,
Skylake-Client-v2,✅,✅,✅,
Skylake-Client-v3,✅,✅,✅,
+Skylake-Client-v4,✅,✅,✅,
Skylake-Server-v1,✅,✅,✅,✅
Skylake-Server-v2,✅,✅,✅,✅
Skylake-Server-v3,✅,✅,✅,✅
Skylake-Server-v4,✅,✅,✅,✅
+Skylake-Server-v5,✅,✅,✅,✅
Snowridge-v1,✅,✅,,
Snowridge-v2,✅,✅,,
+Snowridge-v3,✅,✅,,
+Snowridge-v4,✅,✅,,
Westmere-v1,✅,✅,,
Westmere-v2,✅,✅,,
athlon-v1,,,,
--
2.43.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PULL 09/17] chardev: close QIOChannel before unref'ing
2024-02-09 14:04 [PULL 00/17] Misc fixes patches Daniel P. Berrangé
` (7 preceding siblings ...)
2024-02-09 14:04 ` [PULL 08/17] docs: re-generate x86_64 ABI compatibility CSV Daniel P. Berrangé
@ 2024-02-09 14:04 ` Daniel P. Berrangé
2024-02-09 14:04 ` [PULL 10/17] io: add trace event when cancelling TLS handshake Daniel P. Berrangé
` (8 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Daniel P. Berrangé @ 2024-02-09 14:04 UTC (permalink / raw)
To: qemu-devel
Cc: Hanna Reitz, Gerd Hoffmann, Marc-André Lureau,
Markus Armbruster, Cleber Rosa, Paolo Bonzini, Eric Blake,
Philippe Mathieu-Daudé, Eduardo Habkost, Stefan Weil,
Kevin Wolf, Thomas Huth, Hyman Huang, Richard Henderson,
John Snow, qemu-block, Daniel P. Berrangé, jiangyegen
The chardev socket backend will unref the QIOChannel object while
it is still potentially open. When using TLS there could be a
pending TLS handshake taking place. If the channel is left open
then when the TLS handshake callback runs, it can end up accessing
free'd memory in the tcp_chr_tls_handshake method.
Closing the QIOChannel will unregister any pending handshake
source.
Reported-by: jiangyegen <jiangyegen@huawei.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
chardev/char-socket.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 73947da188..7105753815 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -378,6 +378,10 @@ static void tcp_chr_free_connection(Chardev *chr)
char_socket_yank_iochannel,
QIO_CHANNEL(s->sioc));
}
+
+ if (s->ioc) {
+ qio_channel_close(s->ioc, NULL);
+ }
object_unref(OBJECT(s->sioc));
s->sioc = NULL;
object_unref(OBJECT(s->ioc));
--
2.43.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PULL 10/17] io: add trace event when cancelling TLS handshake
2024-02-09 14:04 [PULL 00/17] Misc fixes patches Daniel P. Berrangé
` (8 preceding siblings ...)
2024-02-09 14:04 ` [PULL 09/17] chardev: close QIOChannel before unref'ing Daniel P. Berrangé
@ 2024-02-09 14:04 ` Daniel P. Berrangé
2024-02-09 14:04 ` [PULL 11/17] crypto: Support LUKS volume with detached header Daniel P. Berrangé
` (7 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Daniel P. Berrangé @ 2024-02-09 14:04 UTC (permalink / raw)
To: qemu-devel
Cc: Hanna Reitz, Gerd Hoffmann, Marc-André Lureau,
Markus Armbruster, Cleber Rosa, Paolo Bonzini, Eric Blake,
Philippe Mathieu-Daudé, Eduardo Habkost, Stefan Weil,
Kevin Wolf, Thomas Huth, Hyman Huang, Richard Henderson,
John Snow, qemu-block, Daniel P. Berrangé
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
io/channel-tls.c | 1 +
io/trace-events | 1 +
2 files changed, 2 insertions(+)
diff --git a/io/channel-tls.c b/io/channel-tls.c
index 58fe1aceee..1d9c9c72bf 100644
--- a/io/channel-tls.c
+++ b/io/channel-tls.c
@@ -381,6 +381,7 @@ static int qio_channel_tls_close(QIOChannel *ioc,
QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc);
if (tioc->hs_ioc_tag) {
+ trace_qio_channel_tls_handshake_cancel(ioc);
g_clear_handle_id(&tioc->hs_ioc_tag, g_source_remove);
}
diff --git a/io/trace-events b/io/trace-events
index 3cc5cf1efd..d4c0f84a9a 100644
--- a/io/trace-events
+++ b/io/trace-events
@@ -43,6 +43,7 @@ qio_channel_tls_handshake_start(void *ioc) "TLS handshake start ioc=%p"
qio_channel_tls_handshake_pending(void *ioc, int status) "TLS handshake pending ioc=%p status=%d"
qio_channel_tls_handshake_fail(void *ioc) "TLS handshake fail ioc=%p"
qio_channel_tls_handshake_complete(void *ioc) "TLS handshake complete ioc=%p"
+qio_channel_tls_handshake_cancel(void *ioc) "TLS handshake cancel ioc=%p"
qio_channel_tls_credentials_allow(void *ioc) "TLS credentials allow ioc=%p"
qio_channel_tls_credentials_deny(void *ioc) "TLS credentials deny ioc=%p"
--
2.43.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PULL 11/17] crypto: Support LUKS volume with detached header
2024-02-09 14:04 [PULL 00/17] Misc fixes patches Daniel P. Berrangé
` (9 preceding siblings ...)
2024-02-09 14:04 ` [PULL 10/17] io: add trace event when cancelling TLS handshake Daniel P. Berrangé
@ 2024-02-09 14:04 ` Daniel P. Berrangé
2024-02-09 14:05 ` [PULL 12/17] qapi: Make parameter 'file' optional for BlockdevCreateOptionsLUKS Daniel P. Berrangé
` (6 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Daniel P. Berrangé @ 2024-02-09 14:04 UTC (permalink / raw)
To: qemu-devel
Cc: Hanna Reitz, Gerd Hoffmann, Marc-André Lureau,
Markus Armbruster, Cleber Rosa, Paolo Bonzini, Eric Blake,
Philippe Mathieu-Daudé, Eduardo Habkost, Stefan Weil,
Kevin Wolf, Thomas Huth, Hyman Huang, Richard Henderson,
John Snow, qemu-block, Daniel P. Berrangé
From: Hyman Huang <yong.huang@smartx.com>
By enhancing the LUKS driver, it is possible to implement
the LUKS volume with a detached header.
Normally a LUKS volume has a layout:
disk: | header | key material | disk payload data |
With a detached LUKS header, you need 2 disks so getting:
disk1: | header | key material |
disk2: | disk payload data |
There are a variety of benefits to doing this:
* Secrecy - the disk2 cannot be identified as containing LUKS
volume since there's no header
* Control - if access to the disk1 is restricted, then even
if someone has access to disk2 they can't unlock
it. Might be useful if you have disks on NFS but
want to restrict which host can launch a VM
instance from it, by dynamically providing access
to the header to a designated host
* Flexibility - your application data volume may be a given
size and it is inconvenient to resize it to
add encryption.You can store the LUKS header
separately and use the existing storage
volume for payload
* Recovery - corruption of a bit in the header may make the
entire payload inaccessible. It might be
convenient to take backups of the header. If
your primary disk header becomes corrupt, you
can unlock the data still by pointing to the
backup detached header
Take the raw-format image as an example to introduce the usage
of the LUKS volume with a detached header:
1. prepare detached LUKS header images
$ dd if=/dev/zero of=test-header.img bs=1M count=32
$ dd if=/dev/zero of=test-payload.img bs=1M count=1000
$ cryptsetup luksFormat --header test-header.img test-payload.img
> --force-password --type luks1
2. block-add a protocol blockdev node of payload image
$ virsh qemu-monitor-command vm '{"execute":"blockdev-add",
> "arguments":{"node-name":"libvirt-1-storage", "driver":"file",
> "filename":"test-payload.img"}}'
3. block-add a protocol blockdev node of LUKS header as above.
$ virsh qemu-monitor-command vm '{"execute":"blockdev-add",
> "arguments":{"node-name":"libvirt-2-storage", "driver":"file",
> "filename": "test-header.img" }}'
4. object-add the secret for decrypting the cipher stored in
LUKS header above
$ virsh qemu-monitor-command vm '{"execute":"object-add",
> "arguments":{"qom-type":"secret", "id":
> "libvirt-2-storage-secret0", "data":"abc123"}}'
5. block-add the raw-drived blockdev format node
$ virsh qemu-monitor-command vm '{"execute":"blockdev-add",
> "arguments":{"node-name":"libvirt-1-format", "driver":"raw",
> "file":"libvirt-1-storage"}}'
6. block-add the luks-drived blockdev to link the raw disk
with the LUKS header by specifying the field "header"
$ virsh qemu-monitor-command vm '{"execute":"blockdev-add",
> "arguments":{"node-name":"libvirt-2-format", "driver":"luks",
> "file":"libvirt-1-format", "header":"libvirt-2-storage",
> "key-secret":"libvirt-2-format-secret0"}}'
7. hot-plug the virtio-blk device finally
$ virsh qemu-monitor-command vm '{"execute":"device_add",
> "arguments": {"num-queues":"1", "driver":"virtio-blk-pci",
> "drive": "libvirt-2-format", "id":"virtio-disk2"}}'
Starting a VM with a LUKS volume with detached header is
somewhat similar to hot-plug in that both maintaining the
same json command while the starting VM changes the
"blockdev-add/device_add" parameters to "blockdev/device".
Signed-off-by: Hyman Huang <yong.huang@smartx.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
block/crypto.c | 21 +++++++++++++++++++--
crypto/block-luks.c | 11 +++++++----
include/crypto/block.h | 5 +++++
qapi/block-core.json | 5 ++++-
4 files changed, 35 insertions(+), 7 deletions(-)
diff --git a/block/crypto.c b/block/crypto.c
index 921933a5e5..68656158e9 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -39,6 +39,7 @@ typedef struct BlockCrypto BlockCrypto;
struct BlockCrypto {
QCryptoBlock *block;
bool updating_keys;
+ BdrvChild *header; /* Reference to the detached LUKS header */
};
@@ -63,12 +64,14 @@ static int block_crypto_read_func(QCryptoBlock *block,
Error **errp)
{
BlockDriverState *bs = opaque;
+ BlockCrypto *crypto = bs->opaque;
ssize_t ret;
GLOBAL_STATE_CODE();
GRAPH_RDLOCK_GUARD_MAINLOOP();
- ret = bdrv_pread(bs->file, offset, buflen, buf, 0);
+ ret = bdrv_pread(crypto->header ? crypto->header : bs->file,
+ offset, buflen, buf, 0);
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not read encryption header");
return ret;
@@ -84,12 +87,14 @@ static int block_crypto_write_func(QCryptoBlock *block,
Error **errp)
{
BlockDriverState *bs = opaque;
+ BlockCrypto *crypto = bs->opaque;
ssize_t ret;
GLOBAL_STATE_CODE();
GRAPH_RDLOCK_GUARD_MAINLOOP();
- ret = bdrv_pwrite(bs->file, offset, buflen, buf, 0);
+ ret = bdrv_pwrite(crypto->header ? crypto->header : bs->file,
+ offset, buflen, buf, 0);
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not write encryption header");
return ret;
@@ -262,6 +267,8 @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
int flags,
Error **errp)
{
+ ERRP_GUARD();
+
BlockCrypto *crypto = bs->opaque;
QemuOpts *opts = NULL;
int ret;
@@ -276,6 +283,13 @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
return ret;
}
+ crypto->header = bdrv_open_child(NULL, options, "header", bs,
+ &child_of_bds, BDRV_CHILD_METADATA,
+ true, errp);
+ if (*errp != NULL) {
+ return -EINVAL;
+ }
+
GRAPH_RDLOCK_GUARD_MAINLOOP();
bs->supported_write_flags = BDRV_REQ_FUA &
@@ -299,6 +313,9 @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
if (flags & BDRV_O_NO_IO) {
cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
}
+ if (crypto->header != NULL) {
+ cflags |= QCRYPTO_BLOCK_OPEN_DETACHED;
+ }
crypto->block = qcrypto_block_open(open_opts, NULL,
block_crypto_read_func,
bs,
diff --git a/crypto/block-luks.c b/crypto/block-luks.c
index f0813d69b4..7e1235c213 100644
--- a/crypto/block-luks.c
+++ b/crypto/block-luks.c
@@ -468,12 +468,15 @@ qcrypto_block_luks_load_header(QCryptoBlock *block,
* Does basic sanity checks on the LUKS header
*/
static int
-qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, Error **errp)
+qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks,
+ unsigned int flags,
+ Error **errp)
{
size_t i, j;
unsigned int header_sectors = QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET /
QCRYPTO_BLOCK_LUKS_SECTOR_SIZE;
+ bool detached = flags & QCRYPTO_BLOCK_OPEN_DETACHED;
if (memcmp(luks->header.magic, qcrypto_block_luks_magic,
QCRYPTO_BLOCK_LUKS_MAGIC_LEN) != 0) {
@@ -505,7 +508,7 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, Error **errp)
return -1;
}
- if (luks->header.payload_offset_sector <
+ if (!detached && luks->header.payload_offset_sector <
DIV_ROUND_UP(QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET,
QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)) {
error_setg(errp, "LUKS payload is overlapping with the header");
@@ -554,7 +557,7 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, Error **errp)
return -1;
}
- if (start1 + len1 > luks->header.payload_offset_sector) {
+ if (!detached && start1 + len1 > luks->header.payload_offset_sector) {
error_setg(errp,
"Keyslot %zu is overlapping with the encrypted payload",
i);
@@ -1214,7 +1217,7 @@ qcrypto_block_luks_open(QCryptoBlock *block,
goto fail;
}
- if (qcrypto_block_luks_check_header(luks, errp) < 0) {
+ if (qcrypto_block_luks_check_header(luks, flags, errp) < 0) {
goto fail;
}
diff --git a/include/crypto/block.h b/include/crypto/block.h
index 4f63a37872..d0d97f5d12 100644
--- a/include/crypto/block.h
+++ b/include/crypto/block.h
@@ -66,6 +66,7 @@ bool qcrypto_block_has_format(QCryptoBlockFormat format,
typedef enum {
QCRYPTO_BLOCK_OPEN_NO_IO = (1 << 0),
+ QCRYPTO_BLOCK_OPEN_DETACHED = (1 << 1),
} QCryptoBlockOpenFlags;
/**
@@ -95,6 +96,10 @@ typedef enum {
* metadata such as the payload offset. There will be
* no cipher or ivgen objects available.
*
+ * If @flags contains QCRYPTO_BLOCK_OPEN_DETACHED then
+ * the open process will be optimized to skip the LUKS
+ * payload overlap check.
+ *
* If any part of initializing the encryption context
* fails an error will be returned. This could be due
* to the volume being in the wrong format, a cipher
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 781c9bd03e..e7d4fb539b 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -3365,11 +3365,14 @@
# decryption key (since 2.6). Mandatory except when doing a
# metadata-only probe of the image.
#
+# @header: block device holding a detached LUKS header. (since 9.0)
+#
# Since: 2.9
##
{ 'struct': 'BlockdevOptionsLUKS',
'base': 'BlockdevOptionsGenericFormat',
- 'data': { '*key-secret': 'str' } }
+ 'data': { '*key-secret': 'str',
+ '*header': 'BlockdevRef'} }
##
# @BlockdevOptionsGenericCOWFormat:
--
2.43.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PULL 12/17] qapi: Make parameter 'file' optional for BlockdevCreateOptionsLUKS
2024-02-09 14:04 [PULL 00/17] Misc fixes patches Daniel P. Berrangé
` (10 preceding siblings ...)
2024-02-09 14:04 ` [PULL 11/17] crypto: Support LUKS volume with detached header Daniel P. Berrangé
@ 2024-02-09 14:05 ` Daniel P. Berrangé
2024-02-09 14:05 ` [PULL 13/17] crypto: Modify the qcrypto_block_create to support creation flags Daniel P. Berrangé
` (5 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Daniel P. Berrangé @ 2024-02-09 14:05 UTC (permalink / raw)
To: qemu-devel
Cc: Hanna Reitz, Gerd Hoffmann, Marc-André Lureau,
Markus Armbruster, Cleber Rosa, Paolo Bonzini, Eric Blake,
Philippe Mathieu-Daudé, Eduardo Habkost, Stefan Weil,
Kevin Wolf, Thomas Huth, Hyman Huang, Richard Henderson,
John Snow, qemu-block, Daniel P. Berrangé
From: Hyman Huang <yong.huang@smartx.com>
To support detached LUKS header creation, make the existing 'file'
field in BlockdevCreateOptionsLUKS optional.
Signed-off-by: Hyman Huang <yong.huang@smartx.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
block/crypto.c | 21 ++++++++++++++-------
qapi/block-core.json | 5 +++--
2 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/block/crypto.c b/block/crypto.c
index 68656158e9..e87dc84111 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -663,9 +663,9 @@ block_crypto_co_create_luks(BlockdevCreateOptions *create_options, Error **errp)
assert(create_options->driver == BLOCKDEV_DRIVER_LUKS);
luks_opts = &create_options->u.luks;
- bs = bdrv_co_open_blockdev_ref(luks_opts->file, errp);
- if (bs == NULL) {
- return -EIO;
+ if (luks_opts->file == NULL) {
+ error_setg(errp, "Formatting LUKS disk requires parameter 'file'");
+ return -EINVAL;
}
create_opts = (QCryptoBlockCreateOptions) {
@@ -677,10 +677,17 @@ block_crypto_co_create_luks(BlockdevCreateOptions *create_options, Error **errp)
preallocation = luks_opts->preallocation;
}
- ret = block_crypto_co_create_generic(bs, luks_opts->size, &create_opts,
- preallocation, errp);
- if (ret < 0) {
- goto fail;
+ if (luks_opts->file) {
+ bs = bdrv_co_open_blockdev_ref(luks_opts->file, errp);
+ if (bs == NULL) {
+ return -EIO;
+ }
+
+ ret = block_crypto_co_create_generic(bs, luks_opts->size, &create_opts,
+ preallocation, errp);
+ if (ret < 0) {
+ goto fail;
+ }
}
ret = 0;
diff --git a/qapi/block-core.json b/qapi/block-core.json
index e7d4fb539b..77d1f50d55 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -4955,7 +4955,8 @@
#
# Driver specific image creation options for LUKS.
#
-# @file: Node to create the image format on
+# @file: Node to create the image format on, mandatory except when
+# 'preallocation' is not requested
#
# @size: Size of the virtual disk in bytes
#
@@ -4966,7 +4967,7 @@
##
{ 'struct': 'BlockdevCreateOptionsLUKS',
'base': 'QCryptoBlockCreateOptionsLUKS',
- 'data': { 'file': 'BlockdevRef',
+ 'data': { '*file': 'BlockdevRef',
'size': 'size',
'*preallocation': 'PreallocMode' } }
--
2.43.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PULL 13/17] crypto: Modify the qcrypto_block_create to support creation flags
2024-02-09 14:04 [PULL 00/17] Misc fixes patches Daniel P. Berrangé
` (11 preceding siblings ...)
2024-02-09 14:05 ` [PULL 12/17] qapi: Make parameter 'file' optional for BlockdevCreateOptionsLUKS Daniel P. Berrangé
@ 2024-02-09 14:05 ` Daniel P. Berrangé
2024-02-09 14:05 ` [PULL 14/17] block: Support detached LUKS header creation using blockdev-create Daniel P. Berrangé
` (4 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Daniel P. Berrangé @ 2024-02-09 14:05 UTC (permalink / raw)
To: qemu-devel
Cc: Hanna Reitz, Gerd Hoffmann, Marc-André Lureau,
Markus Armbruster, Cleber Rosa, Paolo Bonzini, Eric Blake,
Philippe Mathieu-Daudé, Eduardo Habkost, Stefan Weil,
Kevin Wolf, Thomas Huth, Hyman Huang, Richard Henderson,
John Snow, qemu-block, Daniel P. Berrangé
From: Hyman Huang <yong.huang@smartx.com>
Expand the signature of qcrypto_block_create to enable the
formation of LUKS volumes with detachable headers. To accomplish
that, introduce QCryptoBlockCreateFlags to instruct the creation
process to set the payload_offset_sector to 0.
Signed-off-by: Hyman Huang <yong.huang@smartx.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
block/crypto.c | 1 +
block/qcow.c | 2 +-
block/qcow2.c | 2 +-
crypto/block-luks.c | 28 +++++++++++++++++++++-------
crypto/block.c | 4 +++-
crypto/blockpriv.h | 2 ++
include/crypto/block.h | 11 +++++++++++
tests/unit/test-crypto-block.c | 2 ++
8 files changed, 42 insertions(+), 10 deletions(-)
diff --git a/block/crypto.c b/block/crypto.c
index e87dc84111..1b3f87922a 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -369,6 +369,7 @@ block_crypto_co_create_generic(BlockDriverState *bs, int64_t size,
block_crypto_create_init_func,
block_crypto_create_write_func,
&data,
+ 0,
errp);
if (!crypto) {
diff --git a/block/qcow.c b/block/qcow.c
index c6d0e15f1e..ca8e1d5ec8 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -885,7 +885,7 @@ qcow_co_create(BlockdevCreateOptions *opts, Error **errp)
header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
crypto = qcrypto_block_create(qcow_opts->encrypt, "encrypt.",
- NULL, NULL, NULL, errp);
+ NULL, NULL, NULL, 0, errp);
if (!crypto) {
ret = -EINVAL;
goto exit;
diff --git a/block/qcow2.c b/block/qcow2.c
index 9bee66fff5..204f5854cf 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -3216,7 +3216,7 @@ qcow2_set_up_encryption(BlockDriverState *bs,
crypto = qcrypto_block_create(cryptoopts, "encrypt.",
qcow2_crypto_hdr_init_func,
qcow2_crypto_hdr_write_func,
- bs, errp);
+ bs, 0, errp);
if (!crypto) {
return -EINVAL;
}
diff --git a/crypto/block-luks.c b/crypto/block-luks.c
index 7e1235c213..ab52c9dce1 100644
--- a/crypto/block-luks.c
+++ b/crypto/block-luks.c
@@ -1315,6 +1315,7 @@ qcrypto_block_luks_create(QCryptoBlock *block,
const char *hash_alg;
g_autofree char *cipher_mode_spec = NULL;
uint64_t iters;
+ uint64_t detached_header_size;
memcpy(&luks_opts, &options->u.luks, sizeof(luks_opts));
if (!luks_opts.has_iter_time) {
@@ -1543,19 +1544,32 @@ qcrypto_block_luks_create(QCryptoBlock *block,
slot->stripes = QCRYPTO_BLOCK_LUKS_STRIPES;
}
- /* The total size of the LUKS headers is the partition header + key
- * slot headers, rounded up to the nearest sector, combined with
- * the size of each master key material region, also rounded up
- * to the nearest sector */
- luks->header.payload_offset_sector = header_sectors +
- QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS * split_key_sectors;
+ if (block->detached_header) {
+ /*
+ * For a detached LUKS header image, set the payload_offset_sector
+ * to 0 to specify the starting point for read/write
+ */
+ luks->header.payload_offset_sector = 0;
+ } else {
+ /*
+ * The total size of the LUKS headers is the partition header + key
+ * slot headers, rounded up to the nearest sector, combined with
+ * the size of each master key material region, also rounded up
+ * to the nearest sector
+ */
+ luks->header.payload_offset_sector = header_sectors +
+ QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS * split_key_sectors;
+ }
block->sector_size = QCRYPTO_BLOCK_LUKS_SECTOR_SIZE;
block->payload_offset = luks->header.payload_offset_sector *
block->sector_size;
+ detached_header_size =
+ (header_sectors + QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS *
+ split_key_sectors) * block->sector_size;
/* Reserve header space to match payload offset */
- initfunc(block, block->payload_offset, opaque, &local_err);
+ initfunc(block, detached_header_size, opaque, &local_err);
if (local_err) {
error_propagate(errp, local_err);
goto error;
diff --git a/crypto/block.c b/crypto/block.c
index 7bb4b74a37..506ea1d1a3 100644
--- a/crypto/block.c
+++ b/crypto/block.c
@@ -87,6 +87,7 @@ QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options,
QCryptoBlockInitFunc initfunc,
QCryptoBlockWriteFunc writefunc,
void *opaque,
+ unsigned int flags,
Error **errp)
{
QCryptoBlock *block = g_new0(QCryptoBlock, 1);
@@ -102,6 +103,7 @@ QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options,
}
block->driver = qcrypto_block_drivers[options->format];
+ block->detached_header = flags & QCRYPTO_BLOCK_CREATE_DETACHED;
if (block->driver->create(block, options, optprefix, initfunc,
writefunc, opaque, errp) < 0) {
@@ -146,7 +148,7 @@ qcrypto_block_calculate_payload_offset(QCryptoBlockCreateOptions *create_opts,
qcrypto_block_create(create_opts, optprefix,
qcrypto_block_headerlen_hdr_init_func,
qcrypto_block_headerlen_hdr_write_func,
- len, errp);
+ len, 0, errp);
return crypto != NULL;
}
diff --git a/crypto/blockpriv.h b/crypto/blockpriv.h
index 3c7ccea504..836f3b4726 100644
--- a/crypto/blockpriv.h
+++ b/crypto/blockpriv.h
@@ -42,6 +42,8 @@ struct QCryptoBlock {
size_t niv;
uint64_t payload_offset; /* In bytes */
uint64_t sector_size; /* In bytes */
+
+ bool detached_header; /* True if disk has a detached LUKS header */
};
struct QCryptoBlockDriver {
diff --git a/include/crypto/block.h b/include/crypto/block.h
index d0d97f5d12..92e823c9f2 100644
--- a/include/crypto/block.h
+++ b/include/crypto/block.h
@@ -116,6 +116,10 @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options,
size_t n_threads,
Error **errp);
+typedef enum {
+ QCRYPTO_BLOCK_CREATE_DETACHED = (1 << 0),
+} QCryptoBlockCreateFlags;
+
/**
* qcrypto_block_create:
* @options: the encryption options
@@ -123,6 +127,7 @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options,
* @initfunc: callback for initializing volume header
* @writefunc: callback for writing data to the volume header
* @opaque: data to pass to @initfunc and @writefunc
+ * @flags: bitmask of QCryptoBlockCreateFlags values
* @errp: pointer to a NULL-initialized error object
*
* Create a new block encryption object for initializing
@@ -134,6 +139,11 @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options,
* generating new master keys, etc as required. Any existing
* data present on the volume will be irrevocably destroyed.
*
+ * If @flags contains QCRYPTO_BLOCK_CREATE_DETACHED then
+ * the open process will set the payload_offset_sector to 0
+ * to specify the starting point for the read/write of a
+ * detached LUKS header image.
+ *
* If any part of initializing the encryption context
* fails an error will be returned. This could be due
* to the volume being in the wrong format, a cipher
@@ -147,6 +157,7 @@ QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options,
QCryptoBlockInitFunc initfunc,
QCryptoBlockWriteFunc writefunc,
void *opaque,
+ unsigned int flags,
Error **errp);
/**
diff --git a/tests/unit/test-crypto-block.c b/tests/unit/test-crypto-block.c
index 347cd5f3d7..6cfc817a92 100644
--- a/tests/unit/test-crypto-block.c
+++ b/tests/unit/test-crypto-block.c
@@ -283,6 +283,7 @@ static void test_block(gconstpointer opaque)
test_block_init_func,
test_block_write_func,
&header,
+ 0,
&error_abort);
g_assert(blk);
@@ -362,6 +363,7 @@ test_luks_bad_header(gconstpointer data)
test_block_init_func,
test_block_write_func,
&buf,
+ 0,
&error_abort);
g_assert(blk);
--
2.43.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PULL 14/17] block: Support detached LUKS header creation using blockdev-create
2024-02-09 14:04 [PULL 00/17] Misc fixes patches Daniel P. Berrangé
` (12 preceding siblings ...)
2024-02-09 14:05 ` [PULL 13/17] crypto: Modify the qcrypto_block_create to support creation flags Daniel P. Berrangé
@ 2024-02-09 14:05 ` Daniel P. Berrangé
2024-02-09 14:05 ` [PULL 15/17] block: Support detached LUKS header creation using qemu-img Daniel P. Berrangé
` (3 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Daniel P. Berrangé @ 2024-02-09 14:05 UTC (permalink / raw)
To: qemu-devel
Cc: Hanna Reitz, Gerd Hoffmann, Marc-André Lureau,
Markus Armbruster, Cleber Rosa, Paolo Bonzini, Eric Blake,
Philippe Mathieu-Daudé, Eduardo Habkost, Stefan Weil,
Kevin Wolf, Thomas Huth, Hyman Huang, Richard Henderson,
John Snow, qemu-block, Daniel P. Berrangé
From: Hyman Huang <yong.huang@smartx.com>
Firstly, enable the ability to choose the block device containing
a detachable LUKS header by adding the 'header' parameter to
BlockdevCreateOptionsLUKS.
Secondly, when formatting the LUKS volume with a detachable header,
truncate the payload volume to length without a header size.
Using the qmp blockdev command, create the LUKS volume with a
detachable header as follows:
1. add the secret to lock/unlock the cipher stored in the
detached LUKS header
$ virsh qemu-monitor-command vm '{"execute":"object-add",
> "arguments":{"qom-type": "secret", "id": "sec0", "data": "foo"}}'
2. create a header img with 0 size
$ virsh qemu-monitor-command vm '{"execute":"blockdev-create",
> "arguments":{"job-id":"job0", "options":{"driver":"file",
> "filename":"/path/to/detached_luks_header.img", "size":0 }}}'
3. add protocol blockdev node for header
$ virsh qemu-monitor-command vm '{"execute":"blockdev-add",
> "arguments": {"driver":"file", "filename":
> "/path/to/detached_luks_header.img", "node-name":
> "detached-luks-header-storage"}}'
4. create a payload img with 0 size
$ virsh qemu-monitor-command vm '{"execute":"blockdev-create",
> "arguments":{"job-id":"job1", "options":{"driver":"file",
> "filename":"/path/to/detached_luks_payload_raw.img", "size":0}}}'
5. add protocol blockdev node for payload
$ virsh qemu-monitor-command vm '{"execute":"blockdev-add",
> "arguments": {"driver":"file", "filename":
> "/path/to/detached_luks_payload_raw.img", "node-name":
> "luks-payload-raw-storage"}}'
6. do the formatting with 128M size
$ virsh qemu-monitor-command c81_node1 '{"execute":"blockdev-create",
> "arguments":{"job-id":"job2", "options":{"driver":"luks", "header":
> "detached-luks-header-storage", "file":"luks-payload-raw-storage",
> "size":134217728, "preallocation":"full", "key-secret":"sec0" }}}'
Signed-off-by: Hyman Huang <yong.huang@smartx.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
block/crypto.c | 101 +++++++++++++++++++++++++++++++++++++++----
qapi/block-core.json | 3 ++
2 files changed, 96 insertions(+), 8 deletions(-)
diff --git a/block/crypto.c b/block/crypto.c
index 1b3f87922a..8e7ee5e9ac 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -162,6 +162,48 @@ error:
return ret;
}
+static int coroutine_fn GRAPH_UNLOCKED
+block_crypto_co_format_luks_payload(BlockdevCreateOptionsLUKS *luks_opts,
+ Error **errp)
+{
+ BlockDriverState *bs = NULL;
+ BlockBackend *blk = NULL;
+ Error *local_error = NULL;
+ int ret;
+
+ if (luks_opts->size > INT64_MAX) {
+ return -EFBIG;
+ }
+
+ bs = bdrv_co_open_blockdev_ref(luks_opts->file, errp);
+ if (bs == NULL) {
+ return -EIO;
+ }
+
+ blk = blk_co_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE,
+ BLK_PERM_ALL, errp);
+ if (!blk) {
+ ret = -EPERM;
+ goto fail;
+ }
+
+ ret = blk_truncate(blk, luks_opts->size, true,
+ luks_opts->preallocation, 0, &local_error);
+ if (ret < 0) {
+ if (ret == -EFBIG) {
+ /* Replace the error message with a better one */
+ error_free(local_error);
+ error_setg(errp, "The requested file size is too large");
+ }
+ goto fail;
+ }
+
+ ret = 0;
+
+fail:
+ bdrv_co_unref(bs);
+ return ret;
+}
static QemuOptsList block_crypto_runtime_opts_luks = {
.name = "crypto",
@@ -341,7 +383,9 @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
static int coroutine_fn GRAPH_UNLOCKED
block_crypto_co_create_generic(BlockDriverState *bs, int64_t size,
QCryptoBlockCreateOptions *opts,
- PreallocMode prealloc, Error **errp)
+ PreallocMode prealloc,
+ unsigned int flags,
+ Error **errp)
{
int ret;
BlockBackend *blk;
@@ -369,7 +413,7 @@ block_crypto_co_create_generic(BlockDriverState *bs, int64_t size,
block_crypto_create_init_func,
block_crypto_create_write_func,
&data,
- 0,
+ flags,
errp);
if (!crypto) {
@@ -656,16 +700,26 @@ static int coroutine_fn GRAPH_UNLOCKED
block_crypto_co_create_luks(BlockdevCreateOptions *create_options, Error **errp)
{
BlockdevCreateOptionsLUKS *luks_opts;
+ BlockDriverState *hdr_bs = NULL;
BlockDriverState *bs = NULL;
QCryptoBlockCreateOptions create_opts;
PreallocMode preallocation = PREALLOC_MODE_OFF;
+ unsigned int cflags = 0;
int ret;
assert(create_options->driver == BLOCKDEV_DRIVER_LUKS);
luks_opts = &create_options->u.luks;
- if (luks_opts->file == NULL) {
- error_setg(errp, "Formatting LUKS disk requires parameter 'file'");
+ if (luks_opts->header == NULL && luks_opts->file == NULL) {
+ error_setg(errp, "Either the parameter 'header' or 'file' must "
+ "be specified");
+ return -EINVAL;
+ }
+
+ if ((luks_opts->preallocation != PREALLOC_MODE_OFF) &&
+ (luks_opts->file == NULL)) {
+ error_setg(errp, "Parameter 'preallocation' requires 'file' to be "
+ "specified for formatting LUKS disk");
return -EINVAL;
}
@@ -678,14 +732,38 @@ block_crypto_co_create_luks(BlockdevCreateOptions *create_options, Error **errp)
preallocation = luks_opts->preallocation;
}
- if (luks_opts->file) {
+ if (luks_opts->header) {
+ /* LUKS volume with detached header */
+ hdr_bs = bdrv_co_open_blockdev_ref(luks_opts->header, errp);
+ if (hdr_bs == NULL) {
+ return -EIO;
+ }
+
+ cflags |= QCRYPTO_BLOCK_CREATE_DETACHED;
+
+ /* Format the LUKS header node */
+ ret = block_crypto_co_create_generic(hdr_bs, 0, &create_opts,
+ PREALLOC_MODE_OFF, cflags, errp);
+ if (ret < 0) {
+ goto fail;
+ }
+
+ /* Format the LUKS payload node */
+ if (luks_opts->file) {
+ ret = block_crypto_co_format_luks_payload(luks_opts, errp);
+ if (ret < 0) {
+ goto fail;
+ }
+ }
+ } else if (luks_opts->file) {
+ /* LUKS volume with none-detached header */
bs = bdrv_co_open_blockdev_ref(luks_opts->file, errp);
if (bs == NULL) {
return -EIO;
}
ret = block_crypto_co_create_generic(bs, luks_opts->size, &create_opts,
- preallocation, errp);
+ preallocation, cflags, errp);
if (ret < 0) {
goto fail;
}
@@ -693,7 +771,13 @@ block_crypto_co_create_luks(BlockdevCreateOptions *create_options, Error **errp)
ret = 0;
fail:
- bdrv_co_unref(bs);
+ if (hdr_bs != NULL) {
+ bdrv_co_unref(hdr_bs);
+ }
+
+ if (bs != NULL) {
+ bdrv_co_unref(bs);
+ }
return ret;
}
@@ -747,7 +831,8 @@ block_crypto_co_create_opts_luks(BlockDriver *drv, const char *filename,
}
/* Create format layer */
- ret = block_crypto_co_create_generic(bs, size, create_opts, prealloc, errp);
+ ret = block_crypto_co_create_generic(bs, size, create_opts,
+ prealloc, 0, errp);
if (ret < 0) {
goto fail;
}
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 77d1f50d55..e4ef36d2aa 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -4958,6 +4958,8 @@
# @file: Node to create the image format on, mandatory except when
# 'preallocation' is not requested
#
+# @header: Block device holding a detached LUKS header. (since 9.0)
+#
# @size: Size of the virtual disk in bytes
#
# @preallocation: Preallocation mode for the new image (since: 4.2)
@@ -4968,6 +4970,7 @@
{ 'struct': 'BlockdevCreateOptionsLUKS',
'base': 'QCryptoBlockCreateOptionsLUKS',
'data': { '*file': 'BlockdevRef',
+ '*header': 'BlockdevRef',
'size': 'size',
'*preallocation': 'PreallocMode' } }
--
2.43.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PULL 15/17] block: Support detached LUKS header creation using qemu-img
2024-02-09 14:04 [PULL 00/17] Misc fixes patches Daniel P. Berrangé
` (13 preceding siblings ...)
2024-02-09 14:05 ` [PULL 14/17] block: Support detached LUKS header creation using blockdev-create Daniel P. Berrangé
@ 2024-02-09 14:05 ` Daniel P. Berrangé
2024-02-09 14:05 ` [PULL 16/17] crypto: Introduce 'detached-header' field in QCryptoBlockInfoLUKS Daniel P. Berrangé
` (2 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Daniel P. Berrangé @ 2024-02-09 14:05 UTC (permalink / raw)
To: qemu-devel
Cc: Hanna Reitz, Gerd Hoffmann, Marc-André Lureau,
Markus Armbruster, Cleber Rosa, Paolo Bonzini, Eric Blake,
Philippe Mathieu-Daudé, Eduardo Habkost, Stefan Weil,
Kevin Wolf, Thomas Huth, Hyman Huang, Richard Henderson,
John Snow, qemu-block, Daniel P. Berrangé
From: Hyman Huang <yong.huang@smartx.com>
Even though a LUKS header might be created with cryptsetup,
qemu-img should be enhanced to accommodate it as well.
Add the 'detached-header' option to specify the creation of
a detached LUKS header. This is how it is used:
$ qemu-img create --object secret,id=sec0,data=abc123 -f luks
> -o cipher-alg=aes-256,cipher-mode=xts -o key-secret=sec0
> -o detached-header=true header.luks
Using qemu-img or cryptsetup tools to query information of
an LUKS header image as follows:
Assume a detached LUKS header image has been created by:
$ dd if=/dev/zero of=test-header.img bs=1M count=32
$ dd if=/dev/zero of=test-payload.img bs=1M count=1000
$ cryptsetup luksFormat --header test-header.img test-payload.img
> --force-password --type luks1
Header image information could be queried using cryptsetup:
$ cryptsetup luksDump test-header.img
or qemu-img:
$ qemu-img info 'json:{"driver":"luks","file":{"filename":
> "test-payload.img"},"header":{"filename":"test-header.img"}}'
When using qemu-img, keep in mind that the entire disk
information specified by the JSON-format string above must be
supplied on the commandline; if not, an overlay check will reveal
a problem with the LUKS volume check logic.
Signed-off-by: Hyman Huang <yong.huang@smartx.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
[changed to pass 'cflags' to block_crypto_co_create_generic]
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
block.c | 5 ++++-
block/crypto.c | 12 ++++++++++--
block/crypto.h | 8 ++++++++
qapi/crypto.json | 5 ++++-
4 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/block.c b/block.c
index 30afdcbba6..1ed9214f66 100644
--- a/block.c
+++ b/block.c
@@ -7357,7 +7357,10 @@ void bdrv_img_create(const char *filename, const char *fmt,
goto out;
}
- if (size == -1) {
+ /* Parameter 'size' is not needed for detached LUKS header */
+ if (size == -1 &&
+ !(!strcmp(fmt, "luks") &&
+ qemu_opt_get_bool(opts, "detached-header", false))) {
error_setg(errp, "Image creation needs a size parameter");
goto out;
}
diff --git a/block/crypto.c b/block/crypto.c
index 8e7ee5e9ac..21eed909c1 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -231,6 +231,7 @@ static QemuOptsList block_crypto_create_opts_luks = {
BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG(""),
BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG(""),
BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME(""),
+ BLOCK_CRYPTO_OPT_DEF_LUKS_DETACHED_HEADER(""),
{ /* end of list */ }
},
};
@@ -405,7 +406,7 @@ block_crypto_co_create_generic(BlockDriverState *bs, int64_t size,
data = (struct BlockCryptoCreateData) {
.blk = blk,
- .size = size,
+ .size = flags & QCRYPTO_BLOCK_CREATE_DETACHED ? 0 : size,
.prealloc = prealloc,
};
@@ -791,6 +792,9 @@ block_crypto_co_create_opts_luks(BlockDriver *drv, const char *filename,
PreallocMode prealloc;
char *buf = NULL;
int64_t size;
+ bool detached_hdr =
+ qemu_opt_get_bool(opts, "detached-header", false);
+ unsigned int cflags = 0;
int ret;
Error *local_err = NULL;
@@ -830,9 +834,13 @@ block_crypto_co_create_opts_luks(BlockDriver *drv, const char *filename,
goto fail;
}
+ if (detached_hdr) {
+ cflags |= QCRYPTO_BLOCK_CREATE_DETACHED;
+ }
+
/* Create format layer */
ret = block_crypto_co_create_generic(bs, size, create_opts,
- prealloc, 0, errp);
+ prealloc, cflags, errp);
if (ret < 0) {
goto fail;
}
diff --git a/block/crypto.h b/block/crypto.h
index 72e792c9af..dc3d2d5ed9 100644
--- a/block/crypto.h
+++ b/block/crypto.h
@@ -41,6 +41,7 @@
#define BLOCK_CRYPTO_OPT_LUKS_IVGEN_HASH_ALG "ivgen-hash-alg"
#define BLOCK_CRYPTO_OPT_LUKS_HASH_ALG "hash-alg"
#define BLOCK_CRYPTO_OPT_LUKS_ITER_TIME "iter-time"
+#define BLOCK_CRYPTO_OPT_LUKS_DETACHED_HEADER "detached-header"
#define BLOCK_CRYPTO_OPT_LUKS_KEYSLOT "keyslot"
#define BLOCK_CRYPTO_OPT_LUKS_STATE "state"
#define BLOCK_CRYPTO_OPT_LUKS_OLD_SECRET "old-secret"
@@ -100,6 +101,13 @@
.help = "Select new state of affected keyslots (active/inactive)",\
}
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_DETACHED_HEADER(prefix) \
+ { \
+ .name = prefix BLOCK_CRYPTO_OPT_LUKS_DETACHED_HEADER, \
+ .type = QEMU_OPT_BOOL, \
+ .help = "Create a detached LUKS header", \
+ }
+
#define BLOCK_CRYPTO_OPT_DEF_LUKS_KEYSLOT(prefix) \
{ \
.name = prefix BLOCK_CRYPTO_OPT_LUKS_KEYSLOT, \
diff --git a/qapi/crypto.json b/qapi/crypto.json
index 2f2aeff5fd..22c6cce3ae 100644
--- a/qapi/crypto.json
+++ b/qapi/crypto.json
@@ -226,6 +226,8 @@
# @iter-time: number of milliseconds to spend in PBKDF passphrase
# processing. Currently defaults to 2000. (since 2.8)
#
+# @detached-header: create a detached LUKS header. (since 9.0)
+#
# Since: 2.6
##
{ 'struct': 'QCryptoBlockCreateOptionsLUKS',
@@ -235,7 +237,8 @@
'*ivgen-alg': 'QCryptoIVGenAlgorithm',
'*ivgen-hash-alg': 'QCryptoHashAlgorithm',
'*hash-alg': 'QCryptoHashAlgorithm',
- '*iter-time': 'int'}}
+ '*iter-time': 'int',
+ '*detached-header': 'bool'}}
##
# @QCryptoBlockOpenOptions:
--
2.43.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PULL 16/17] crypto: Introduce 'detached-header' field in QCryptoBlockInfoLUKS
2024-02-09 14:04 [PULL 00/17] Misc fixes patches Daniel P. Berrangé
` (14 preceding siblings ...)
2024-02-09 14:05 ` [PULL 15/17] block: Support detached LUKS header creation using qemu-img Daniel P. Berrangé
@ 2024-02-09 14:05 ` Daniel P. Berrangé
2024-02-09 14:05 ` [PULL 17/17] tests: Add case for LUKS volume with detached header Daniel P. Berrangé
2024-02-12 18:31 ` [PULL 00/17] Misc fixes patches Peter Maydell
17 siblings, 0 replies; 20+ messages in thread
From: Daniel P. Berrangé @ 2024-02-09 14:05 UTC (permalink / raw)
To: qemu-devel
Cc: Hanna Reitz, Gerd Hoffmann, Marc-André Lureau,
Markus Armbruster, Cleber Rosa, Paolo Bonzini, Eric Blake,
Philippe Mathieu-Daudé, Eduardo Habkost, Stefan Weil,
Kevin Wolf, Thomas Huth, Hyman Huang, Richard Henderson,
John Snow, qemu-block, Daniel P. Berrangé
From: Hyman Huang <yong.huang@smartx.com>
When querying the LUKS disk with the qemu-img tool or other APIs,
add information about whether the LUKS header is detached.
Additionally, update the test case with the appropriate
modification.
Signed-off-by: Hyman Huang <yong.huang@smartx.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
crypto/block-luks.c | 2 ++
qapi/crypto.json | 3 +++
tests/qemu-iotests/210.out | 4 ++++
3 files changed, 9 insertions(+)
diff --git a/crypto/block-luks.c b/crypto/block-luks.c
index ab52c9dce1..3ee928fb5a 100644
--- a/crypto/block-luks.c
+++ b/crypto/block-luks.c
@@ -1271,6 +1271,7 @@ qcrypto_block_luks_open(QCryptoBlock *block,
block->sector_size = QCRYPTO_BLOCK_LUKS_SECTOR_SIZE;
block->payload_offset = luks->header.payload_offset_sector *
block->sector_size;
+ block->detached_header = (block->payload_offset == 0) ? true : false;
return 0;
@@ -1895,6 +1896,7 @@ static int qcrypto_block_luks_get_info(QCryptoBlock *block,
info->u.luks.master_key_iters = luks->header.master_key_iterations;
info->u.luks.uuid = g_strndup((const char *)luks->header.uuid,
sizeof(luks->header.uuid));
+ info->u.luks.detached_header = block->detached_header;
for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) {
slot = g_new0(QCryptoBlockInfoLUKSSlot, 1);
diff --git a/qapi/crypto.json b/qapi/crypto.json
index 22c6cce3ae..ad8dd37175 100644
--- a/qapi/crypto.json
+++ b/qapi/crypto.json
@@ -317,6 +317,8 @@
#
# @hash-alg: the master key hash algorithm
#
+# @detached-header: whether the LUKS header is detached (Since 9.0)
+#
# @payload-offset: offset to the payload data in bytes
#
# @master-key-iters: number of PBKDF2 iterations for key material
@@ -333,6 +335,7 @@
'ivgen-alg': 'QCryptoIVGenAlgorithm',
'*ivgen-hash-alg': 'QCryptoHashAlgorithm',
'hash-alg': 'QCryptoHashAlgorithm',
+ 'detached-header': 'bool',
'payload-offset': 'int',
'master-key-iters': 'int',
'uuid': 'str',
diff --git a/tests/qemu-iotests/210.out b/tests/qemu-iotests/210.out
index 96d9f749dd..94b29b2120 100644
--- a/tests/qemu-iotests/210.out
+++ b/tests/qemu-iotests/210.out
@@ -18,6 +18,7 @@ virtual size: 128 MiB (134217728 bytes)
encrypted: yes
Format specific information:
ivgen alg: plain64
+ detached header: false
hash alg: sha256
cipher alg: aes-256
uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
@@ -70,6 +71,7 @@ virtual size: 64 MiB (67108864 bytes)
encrypted: yes
Format specific information:
ivgen alg: plain64
+ detached header: false
hash alg: sha1
cipher alg: aes-128
uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
@@ -125,6 +127,7 @@ virtual size: 0 B (0 bytes)
encrypted: yes
Format specific information:
ivgen alg: plain64
+ detached header: false
hash alg: sha256
cipher alg: aes-256
uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
@@ -195,6 +198,7 @@ virtual size: 0 B (0 bytes)
encrypted: yes
Format specific information:
ivgen alg: plain64
+ detached header: false
hash alg: sha256
cipher alg: aes-256
uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
--
2.43.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PULL 17/17] tests: Add case for LUKS volume with detached header
2024-02-09 14:04 [PULL 00/17] Misc fixes patches Daniel P. Berrangé
` (15 preceding siblings ...)
2024-02-09 14:05 ` [PULL 16/17] crypto: Introduce 'detached-header' field in QCryptoBlockInfoLUKS Daniel P. Berrangé
@ 2024-02-09 14:05 ` Daniel P. Berrangé
2024-02-12 18:31 ` [PULL 00/17] Misc fixes patches Peter Maydell
17 siblings, 0 replies; 20+ messages in thread
From: Daniel P. Berrangé @ 2024-02-09 14:05 UTC (permalink / raw)
To: qemu-devel
Cc: Hanna Reitz, Gerd Hoffmann, Marc-André Lureau,
Markus Armbruster, Cleber Rosa, Paolo Bonzini, Eric Blake,
Philippe Mathieu-Daudé, Eduardo Habkost, Stefan Weil,
Kevin Wolf, Thomas Huth, Hyman Huang, Richard Henderson,
John Snow, qemu-block, Daniel P. Berrangé
From: Hyman Huang <yong.huang@smartx.com>
Also, add a section to the MAINTAINERS file for detached
LUKS header, it only has a test case in it currently.
Signed-off-by: Hyman Huang <yong.huang@smartx.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
MAINTAINERS | 5 +
| 316 ++++++++++++++++++
| 5 +
3 files changed, 326 insertions(+)
create mode 100755 tests/qemu-iotests/tests/luks-detached-header
create mode 100644 tests/qemu-iotests/tests/luks-detached-header.out
diff --git a/MAINTAINERS b/MAINTAINERS
index 2f9741b898..f80db6a96a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3402,6 +3402,11 @@ F: migration/dirtyrate.c
F: migration/dirtyrate.h
F: include/sysemu/dirtyrate.h
+Detached LUKS header
+M: Hyman Huang <yong.huang@smartx.com>
+S: Maintained
+F: tests/qemu-iotests/tests/luks-detached-header
+
D-Bus
M: Marc-André Lureau <marcandre.lureau@redhat.com>
S: Maintained
--git a/tests/qemu-iotests/tests/luks-detached-header b/tests/qemu-iotests/tests/luks-detached-header
new file mode 100755
index 0000000000..3455fd8de1
--- /dev/null
+++ b/tests/qemu-iotests/tests/luks-detached-header
@@ -0,0 +1,316 @@
+#!/usr/bin/env python3
+# group: rw auto
+#
+# Test LUKS volume with detached header
+#
+# Copyright (C) 2024 SmartX Inc.
+#
+# Authors:
+# Hyman Huang <yong.huang@smartx.com>
+#
+# 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/>.
+#
+
+import os
+import json
+import iotests
+from iotests import (
+ imgfmt,
+ qemu_img_create,
+ qemu_img_info,
+ QMPTestCase,
+)
+
+
+image_size = 128 * 1024 * 1024
+
+luks_img = os.path.join(iotests.test_dir, "luks.img")
+detached_header_img1 = os.path.join(iotests.test_dir, "detached_header.img1")
+detached_header_img2 = os.path.join(iotests.test_dir, "detached_header.img2")
+detached_payload_raw_img = os.path.join(
+ iotests.test_dir, "detached_payload_raw.img"
+)
+detached_payload_qcow2_img = os.path.join(
+ iotests.test_dir, "detached_payload_qcow2.img"
+)
+detached_header_raw_img = "json:" + json.dumps(
+ {
+ "driver": "luks",
+ "file": {"filename": detached_payload_raw_img},
+ "header": {
+ "filename": detached_header_img1,
+ },
+ }
+)
+detached_header_qcow2_img = "json:" + json.dumps(
+ {
+ "driver": "luks",
+ "file": {"filename": detached_payload_qcow2_img},
+ "header": {"filename": detached_header_img2},
+ }
+)
+
+secret_obj = "secret,id=sec0,data=foo"
+luks_opts = "key-secret=sec0"
+
+
+class TestDetachedLUKSHeader(QMPTestCase):
+ def setUp(self) -> None:
+ self.vm = iotests.VM()
+ self.vm.add_object(secret_obj)
+ self.vm.launch()
+
+ # 1. Create the normal LUKS disk with 128M size
+ self.vm.blockdev_create(
+ {"driver": "file", "filename": luks_img, "size": 0}
+ )
+ self.vm.qmp_log(
+ "blockdev-add",
+ driver="file",
+ filename=luks_img,
+ node_name="luks-1-storage",
+ )
+ result = self.vm.blockdev_create(
+ {
+ "driver": imgfmt,
+ "file": "luks-1-storage",
+ "key-secret": "sec0",
+ "size": image_size,
+ "iter-time": 10,
+ }
+ )
+ # None is expected
+ self.assertEqual(result, None)
+
+ # 2. Create the LUKS disk with detached header (raw)
+
+ # Create detached LUKS header
+ self.vm.blockdev_create(
+ {"driver": "file", "filename": detached_header_img1, "size": 0}
+ )
+ self.vm.qmp_log(
+ "blockdev-add",
+ driver="file",
+ filename=detached_header_img1,
+ node_name="luks-2-header-storage",
+ )
+
+ # Create detached LUKS raw payload
+ self.vm.blockdev_create(
+ {"driver": "file", "filename": detached_payload_raw_img, "size": 0}
+ )
+ self.vm.qmp_log(
+ "blockdev-add",
+ driver="file",
+ filename=detached_payload_raw_img,
+ node_name="luks-2-payload-storage",
+ )
+
+ # Format LUKS disk with detached header
+ result = self.vm.blockdev_create(
+ {
+ "driver": imgfmt,
+ "header": "luks-2-header-storage",
+ "file": "luks-2-payload-storage",
+ "key-secret": "sec0",
+ "preallocation": "full",
+ "size": image_size,
+ "iter-time": 10,
+ }
+ )
+ self.assertEqual(result, None)
+
+ self.vm.shutdown()
+
+ # 3. Create the LUKS disk with detached header (qcow2)
+
+ # Create detached LUKS header using qemu-img
+ res = qemu_img_create(
+ "-f",
+ "luks",
+ "--object",
+ secret_obj,
+ "-o",
+ luks_opts,
+ "-o",
+ "detached-header=true",
+ detached_header_img2,
+ )
+ assert res.returncode == 0
+
+ # Create detached LUKS qcow2 payload
+ res = qemu_img_create(
+ "-f", "qcow2", detached_payload_qcow2_img, str(image_size)
+ )
+ assert res.returncode == 0
+
+ def tearDown(self) -> None:
+ os.remove(luks_img)
+ os.remove(detached_header_img1)
+ os.remove(detached_header_img2)
+ os.remove(detached_payload_raw_img)
+ os.remove(detached_payload_qcow2_img)
+
+ # Check if there was any qemu-io run that failed
+ if "Pattern verification failed" in self.vm.get_log():
+ print("ERROR: Pattern verification failed:")
+ print(self.vm.get_log())
+ self.fail("qemu-io pattern verification failed")
+
+ def test_img_creation(self) -> None:
+ # Check if the images created above are expected
+
+ data = qemu_img_info(luks_img)["format-specific"]
+ self.assertEqual(data["type"], imgfmt)
+ self.assertEqual(data["data"]["detached-header"], False)
+
+ data = qemu_img_info(detached_header_raw_img)["format-specific"]
+ self.assertEqual(data["type"], imgfmt)
+ self.assertEqual(data["data"]["detached-header"], True)
+
+ data = qemu_img_info(detached_header_qcow2_img)["format-specific"]
+ self.assertEqual(data["type"], imgfmt)
+ self.assertEqual(data["data"]["detached-header"], True)
+
+ # Check if preallocation works
+ size = qemu_img_info(detached_payload_raw_img)["actual-size"]
+ self.assertGreaterEqual(size, image_size)
+
+ def test_detached_luks_header(self) -> None:
+ self.vm.launch()
+
+ # 1. Add the disk created above
+
+ # Add normal LUKS disk
+ self.vm.qmp_log(
+ "blockdev-add",
+ driver="file",
+ filename=luks_img,
+ node_name="luks-1-storage",
+ )
+ result = self.vm.qmp_log(
+ "blockdev-add",
+ driver="luks",
+ file="luks-1-storage",
+ key_secret="sec0",
+ node_name="luks-1-format",
+ )
+
+ # Expected result{ "return": {} }
+ self.assert_qmp(result, "return", {})
+
+ # Add detached LUKS header with raw payload
+ self.vm.qmp_log(
+ "blockdev-add",
+ driver="file",
+ filename=detached_header_img1,
+ node_name="luks-header1-storage",
+ )
+
+ self.vm.qmp_log(
+ "blockdev-add",
+ driver="file",
+ filename=detached_payload_raw_img,
+ node_name="luks-2-payload-raw-storage",
+ )
+
+ result = self.vm.qmp_log(
+ "blockdev-add",
+ driver=imgfmt,
+ header="luks-header1-storage",
+ file="luks-2-payload-raw-storage",
+ key_secret="sec0",
+ node_name="luks-2-payload-raw-format",
+ )
+ self.assert_qmp(result, "return", {})
+
+ # Add detached LUKS header with qcow2 payload
+ self.vm.qmp_log(
+ "blockdev-add",
+ driver="file",
+ filename=detached_header_img2,
+ node_name="luks-header2-storage",
+ )
+
+ self.vm.qmp_log(
+ "blockdev-add",
+ driver="file",
+ filename=detached_payload_qcow2_img,
+ node_name="luks-3-payload-qcow2-storage",
+ )
+
+ result = self.vm.qmp_log(
+ "blockdev-add",
+ driver=imgfmt,
+ header="luks-header2-storage",
+ file="luks-3-payload-qcow2-storage",
+ key_secret="sec0",
+ node_name="luks-3-payload-qcow2-format",
+ )
+ self.assert_qmp(result, "return", {})
+
+ # 2. Do I/O test
+
+ # Do some I/O to the image to see whether it still works
+ # (Pattern verification will be checked by tearDown())
+
+ # Normal LUKS disk
+ result = self.vm.qmp_log(
+ "human-monitor-command",
+ command_line='qemu-io luks-1-format "write -P 40 0 64k"',
+ )
+ self.assert_qmp(result, "return", "")
+
+ result = self.vm.qmp_log(
+ "human-monitor-command",
+ command_line='qemu-io luks-1-format "read -P 40 0 64k"',
+ )
+ self.assert_qmp(result, "return", "")
+
+ # Detached LUKS header with raw payload
+ cmd = 'qemu-io luks-2-payload-raw-format "write -P 41 0 64k"'
+ result = self.vm.qmp(
+ "human-monitor-command",
+ command_line=cmd
+ )
+ self.assert_qmp(result, "return", "")
+
+ cmd = 'qemu-io luks-2-payload-raw-format "read -P 41 0 64k"'
+ result = self.vm.qmp(
+ "human-monitor-command",
+ command_line=cmd
+ )
+ self.assert_qmp(result, "return", "")
+
+ # Detached LUKS header with qcow2 payload
+ cmd = 'qemu-io luks-3-payload-qcow2-format "write -P 42 0 64k"'
+ result = self.vm.qmp(
+ "human-monitor-command",
+ command_line=cmd
+ )
+ self.assert_qmp(result, "return", "")
+
+ cmd = 'qemu-io luks-3-payload-qcow2-format "read -P 42 0 64k"'
+ result = self.vm.qmp(
+ "human-monitor-command",
+ command_line=cmd
+ )
+ self.assert_qmp(result, "return", "")
+
+ self.vm.shutdown()
+
+
+if __name__ == "__main__":
+ # Test image creation and I/O
+ iotests.main(supported_fmts=["luks"], supported_protocols=["file"])
--git a/tests/qemu-iotests/tests/luks-detached-header.out b/tests/qemu-iotests/tests/luks-detached-header.out
new file mode 100644
index 0000000000..fbc63e62f8
--- /dev/null
+++ b/tests/qemu-iotests/tests/luks-detached-header.out
@@ -0,0 +1,5 @@
+..
+----------------------------------------------------------------------
+Ran 2 tests
+
+OK
--
2.43.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* Re: [PULL 00/17] Misc fixes patches
2024-02-09 14:04 [PULL 00/17] Misc fixes patches Daniel P. Berrangé
` (16 preceding siblings ...)
2024-02-09 14:05 ` [PULL 17/17] tests: Add case for LUKS volume with detached header Daniel P. Berrangé
@ 2024-02-12 18:31 ` Peter Maydell
17 siblings, 0 replies; 20+ messages in thread
From: Peter Maydell @ 2024-02-12 18:31 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: qemu-devel, Hanna Reitz, Gerd Hoffmann, Marc-André Lureau,
Markus Armbruster, Cleber Rosa, Paolo Bonzini, Eric Blake,
Philippe Mathieu-Daudé, Eduardo Habkost, Stefan Weil,
Kevin Wolf, Thomas Huth, Hyman Huang, Richard Henderson,
John Snow, qemu-block
On Fri, 9 Feb 2024 at 14:07, Daniel P. Berrangé <berrange@redhat.com> wrote:
>
> The following changes since commit 9e34f127f419b3941b36dfdfac79640dc81e97e2:
>
> Merge tag 'pull-request-2024-02-06' of https://gitlab.com/thuth/qemu into staging (2024-02-08 11:59:28 +0000)
>
> are available in the Git repository at:
>
> https://gitlab.com/berrange/qemu tags/misc-fixes-pull-request
>
> for you to fetch changes up to d87b258b75498d3e8563ec8ebaaf67efc27be945:
>
> tests: Add case for LUKS volume with detached header (2024-02-09 12:50:38 +0000)
>
> ----------------------------------------------------------------
> - LUKS support for detached headers
> - Update x86 CPU model docs and script
> - Add missing close of chardev QIOChannel
> - More trace events o nTKS handshake
> - Drop unsafe VNC constants
> - Increase NOFILE limit during startup
>
Applied, thanks.
Please update the changelog at https://wiki.qemu.org/ChangeLog/9.0
for any user-visible changes.
-- PMM
^ permalink raw reply [flat|nested] 20+ messages in thread