It turns out I had misunderstood how the x86_match_cpu() function works.
It evaluates a logical OR of the matching conditions, not logical AND.
This caused the CPU feature checks to pass even if only SSE2 (but not
AES-NI) was supported (ir vice versa), leading to potential crashes if
something tried to use the registered algs.

This patch fixes the checks to ensure that both required CPU features
are supported. The MODULE_DEVICE_TABLE declaration is specified only for
the AES-NI feature array, because I'm not sure what having multiple such
declarations would cause and I believe it should suffice to match on the
more important feature at the alias level and let the init routine do
the full check.

Signed-off-by: Ondrej Mosnacek <omosn...@redhat.com>
---
Hi Herbert,

this patch fixes the CPU checks of the AEGIS AES-NI/SSE2 implementations
that have been introduced in 4.18. Once reviewed, it should go to Linus'
tree since it may cause crashes on some systems if the corresponding
configs are enabled.

@x86 folks, please take a look if I use the MODULE_DEVICE_TABLE macro
correctly here (I'm not sure how to properly declare that the module
needs two CPU features to be both supported; all other modules I saw had
either only single match rule or required just one of the rules to
match).

Thanks,

Ondrej Mosnacek

 arch/x86/crypto/aegis128-aesni-glue.c  | 8 ++++++--
 arch/x86/crypto/aegis128l-aesni-glue.c | 8 ++++++--
 arch/x86/crypto/aegis256-aesni-glue.c  | 8 ++++++--
 3 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/arch/x86/crypto/aegis128-aesni-glue.c 
b/arch/x86/crypto/aegis128-aesni-glue.c
index 5de7c0d46edf..6a5abed59593 100644
--- a/arch/x86/crypto/aegis128-aesni-glue.c
+++ b/arch/x86/crypto/aegis128-aesni-glue.c
@@ -377,14 +377,18 @@ static struct aead_alg crypto_aegis128_aesni_alg[] = {
 
 static const struct x86_cpu_id aesni_cpu_id[] = {
        X86_FEATURE_MATCH(X86_FEATURE_AES),
-       X86_FEATURE_MATCH(X86_FEATURE_XMM2),
        {}
 };
 MODULE_DEVICE_TABLE(x86cpu, aesni_cpu_id);
 
+static const struct x86_cpu_id sse2_cpu_id[] = {
+       X86_FEATURE_MATCH(X86_FEATURE_XMM2),
+       {}
+};
+
 static int __init crypto_aegis128_aesni_module_init(void)
 {
-       if (!x86_match_cpu(aesni_cpu_id))
+       if (!x86_match_cpu(aesni_cpu_id) || !x86_match_cpu(sse2_cpu_id))
                return -ENODEV;
 
        return crypto_register_aeads(crypto_aegis128_aesni_alg,
diff --git a/arch/x86/crypto/aegis128l-aesni-glue.c 
b/arch/x86/crypto/aegis128l-aesni-glue.c
index 876e4866e633..691c52701c2d 100644
--- a/arch/x86/crypto/aegis128l-aesni-glue.c
+++ b/arch/x86/crypto/aegis128l-aesni-glue.c
@@ -377,14 +377,18 @@ static struct aead_alg crypto_aegis128l_aesni_alg[] = {
 
 static const struct x86_cpu_id aesni_cpu_id[] = {
        X86_FEATURE_MATCH(X86_FEATURE_AES),
-       X86_FEATURE_MATCH(X86_FEATURE_XMM2),
        {}
 };
 MODULE_DEVICE_TABLE(x86cpu, aesni_cpu_id);
 
+static const struct x86_cpu_id sse2_cpu_id[] = {
+       X86_FEATURE_MATCH(X86_FEATURE_XMM2),
+       {}
+};
+
 static int __init crypto_aegis128l_aesni_module_init(void)
 {
-       if (!x86_match_cpu(aesni_cpu_id))
+       if (!x86_match_cpu(aesni_cpu_id) || !x86_match_cpu(sse2_cpu_id))
                return -ENODEV;
 
        return crypto_register_aeads(crypto_aegis128l_aesni_alg,
diff --git a/arch/x86/crypto/aegis256-aesni-glue.c 
b/arch/x86/crypto/aegis256-aesni-glue.c
index 2b5dd3af8f4d..481b5e4f4fd0 100644
--- a/arch/x86/crypto/aegis256-aesni-glue.c
+++ b/arch/x86/crypto/aegis256-aesni-glue.c
@@ -377,14 +377,18 @@ static struct aead_alg crypto_aegis256_aesni_alg[] = {
 
 static const struct x86_cpu_id aesni_cpu_id[] = {
        X86_FEATURE_MATCH(X86_FEATURE_AES),
-       X86_FEATURE_MATCH(X86_FEATURE_XMM2),
        {}
 };
 MODULE_DEVICE_TABLE(x86cpu, aesni_cpu_id);
 
+static const struct x86_cpu_id sse2_cpu_id[] = {
+       X86_FEATURE_MATCH(X86_FEATURE_XMM2),
+       {}
+};
+
 static int __init crypto_aegis256_aesni_module_init(void)
 {
-       if (!x86_match_cpu(aesni_cpu_id))
+       if (!x86_match_cpu(aesni_cpu_id) || !x86_match_cpu(sse2_cpu_id))
                return -ENODEV;
 
        return crypto_register_aeads(crypto_aegis256_aesni_alg,
-- 
2.17.1

Reply via email to