crypto: qat - add limit to linked list parsing
authorAdam Guerin <adam.guerin@intel.com>
Wed, 21 Sep 2022 09:38:30 +0000 (10:38 +0100)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 30 Sep 2022 05:57:50 +0000 (13:57 +0800)
adf_copy_key_value_data() copies data from userland to kernel, based on
a linked link provided by userland. If userland provides a circular
list (or just a very long one) then it would drive a long loop where
allocation occurs in every loop. This could lead to low memory conditions.
Adding a limit to stop endless loop.

Signed-off-by: Adam Guerin <adam.guerin@intel.com>
Co-developed-by: Ciunas Bennett <ciunas.bennett@intel.com>
Signed-off-by: Ciunas Bennett <ciunas.bennett@intel.com>
Reviewed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/qat/qat_common/adf_ctl_drv.c

index 508c18edd692f293f0633dd8912996167ee701f1..82b69e1f725ba278d76fdd414cb7b67e7d450073 100644 (file)
@@ -16,6 +16,9 @@
 #include "adf_cfg_common.h"
 #include "adf_cfg_user.h"
 
+#define ADF_CFG_MAX_SECTION 512
+#define ADF_CFG_MAX_KEY_VAL 256
+
 #define DEVICE_NAME "qat_adf_ctl"
 
 static DEFINE_MUTEX(adf_ctl_lock);
@@ -137,10 +140,11 @@ static int adf_copy_key_value_data(struct adf_accel_dev *accel_dev,
        struct adf_user_cfg_key_val key_val;
        struct adf_user_cfg_key_val *params_head;
        struct adf_user_cfg_section section, *section_head;
+       int i, j;
 
        section_head = ctl_data->config_section;
 
-       while (section_head) {
+       for (i = 0; section_head && i < ADF_CFG_MAX_SECTION; i++) {
                if (copy_from_user(&section, (void __user *)section_head,
                                   sizeof(*section_head))) {
                        dev_err(&GET_DEV(accel_dev),
@@ -156,7 +160,7 @@ static int adf_copy_key_value_data(struct adf_accel_dev *accel_dev,
 
                params_head = section.params;
 
-               while (params_head) {
+               for (j = 0; params_head && j < ADF_CFG_MAX_KEY_VAL; j++) {
                        if (copy_from_user(&key_val, (void __user *)params_head,
                                           sizeof(key_val))) {
                                dev_err(&GET_DEV(accel_dev),