diff options
author | Anca Jeanina Floarea <anca.floarea@freescale.com> | 2014-09-17 15:07:38 (GMT) |
---|---|---|
committer | Matthew Weigel <Matthew.Weigel@freescale.com> | 2014-12-11 18:39:32 (GMT) |
commit | 8572340361bed44ac4133bc7af91bdc92489d474 (patch) | |
tree | f8f3f6e47213cd274831520c56975faa6132207b /drivers/staging/fsl_dpa_offload/wrp_dpa_stats.c | |
parent | b41fa90d6d3ab71153d271484cb7967391fecda9 (diff) | |
download | linux-fsl-qoriq-8572340361bed44ac4133bc7af91bdc92489d474.tar.xz |
dpa_offload: Fix DPA Stats issues caused by tainted values
Fix DPA Stats issues related to tainted values by adding
constraints to user-provided parameters.
Signed-off-by: Anca Jeanina Floarea <anca.floarea@freescale.com>
Change-Id: Ib59f89518d96c9102a71be4c673e2d065b0a71f8
Reviewed-on: http://git.am.freescale.net:8181/19070
Reviewed-by: Marian-Cornel Chereji <marian.chereji@freescale.com>
Tested-by: Marian-Cornel Chereji <marian.chereji@freescale.com>
Diffstat (limited to 'drivers/staging/fsl_dpa_offload/wrp_dpa_stats.c')
-rw-r--r-- | drivers/staging/fsl_dpa_offload/wrp_dpa_stats.c | 62 |
1 files changed, 61 insertions, 1 deletions
diff --git a/drivers/staging/fsl_dpa_offload/wrp_dpa_stats.c b/drivers/staging/fsl_dpa_offload/wrp_dpa_stats.c index 49545e85..57784a9 100644 --- a/drivers/staging/fsl_dpa_offload/wrp_dpa_stats.c +++ b/drivers/staging/fsl_dpa_offload/wrp_dpa_stats.c @@ -555,6 +555,15 @@ static long do_ioctl_stats_init(struct ioc_dpa_stats_params *prm) long ret = 0; uint16_t i; + /* Check user-provided storage area length */ + if (prm->storage_area_len < DPA_STATS_CNT_SEL_LEN || + prm->storage_area_len > DPA_STATS_MAX_STORAGE_AREA_SIZE) { + log_err("Parameter storage_area_len %d must be in range (%d - %d)\n", + prm->storage_area_len, + DPA_STATS_CNT_SEL_LEN, DPA_STATS_MAX_STORAGE_AREA_SIZE); + return -EINVAL; + } + /* Save user-provided parameters */ params.max_counters = prm->max_counters; params.storage_area_len = prm->storage_area_len; @@ -841,6 +850,13 @@ static int do_ioctl_stats_create_class_counter(void *args) return -EINVAL; } + if (prm.cnt_params.class_members > DPA_STATS_MAX_NUM_OF_CLASS_MEMBERS) { + log_err("Parameter class_members %d exceeds maximum number of class members: %d\n", + prm.cnt_params.class_members, + DPA_STATS_MAX_NUM_OF_CLASS_MEMBERS); + return -EINVAL; + } + cls_mbrs = prm.cnt_params.class_members; switch (prm.cnt_params.type) { @@ -1102,6 +1118,13 @@ static int do_ioctl_stats_compat_create_class_counter(void *args) return -EINVAL; } + if (uprm_cls->class_members > DPA_STATS_MAX_NUM_OF_CLASS_MEMBERS) { + log_err("Parameter class_members %d exceeds maximum number of class members: %d\n", + uprm_cls->class_members, + DPA_STATS_MAX_NUM_OF_CLASS_MEMBERS); + return -EINVAL; + } + memset(&kprm, 0, sizeof(struct ioc_dpa_stats_cls_cnt_params)); kprm.stats_id = uprm.stats_id; kprm_cls->type = uprm_cls->type; @@ -1451,6 +1474,14 @@ static int do_ioctl_stats_get_counters(void *args) return -EINVAL; } + if (prm.req_params.cnts_ids_len == 0 || + prm.req_params.cnts_ids_len > DPA_STATS_REQ_CNTS_IDS_LEN) { + log_err("Number of requested counter ids (%d) must be in range (1 - %d)\n", + prm.req_params.cnts_ids_len, + DPA_STATS_REQ_CNTS_IDS_LEN); + return -EINVAL; + } + /* Save the user-space array of counter ids */ cnts_ids = prm.req_params.cnts_ids; @@ -1520,8 +1551,15 @@ static int do_ioctl_stats_compat_get_counters(void *args) return -EINVAL; } + if (uprm.req_params.cnts_ids_len == 0 || + uprm.req_params.cnts_ids_len > DPA_STATS_REQ_CNTS_IDS_LEN) { + log_err("Number of requested counter ids (%d) must be in range (1 - %d)\n", + uprm.req_params.cnts_ids_len, + DPA_STATS_REQ_CNTS_IDS_LEN); + return -EINVAL; + } + memset(&kprm, 0, sizeof(struct ioc_dpa_stats_cnt_request_params)); - kprm.cnts_len = uprm.cnts_len; kprm.request_done = (dpa_stats_request_cb) ((compat_ptr)(uprm.request_done)); kprm.req_params.cnts_ids_len = uprm.req_params.cnts_ids_len; @@ -1608,6 +1646,13 @@ static int do_ioctl_stats_reset_counters(void *args) return -EINVAL; } + if (prm.cnts_ids_len == 0 || + prm.cnts_ids_len > DPA_STATS_REQ_CNTS_IDS_LEN) { + log_err("Number of counters to reset %d must be in range (1 - %d)\n", + prm.cnts_ids_len, DPA_STATS_REQ_CNTS_IDS_LEN); + return -EINVAL; + } + /* Allocate kernel-space memory area to copy the counters ids */ cnt_ids = kcalloc(prm.cnts_ids_len, sizeof(int), GFP_KERNEL); if (!cnt_ids) { @@ -1653,6 +1698,13 @@ static int do_ioctl_stats_compat_reset_counters(void *args) return -EINVAL; } + if (uprm.cnts_ids_len == 0 || + uprm.cnts_ids_len > DPA_STATS_REQ_CNTS_IDS_LEN) { + log_err("Number of counters to reset %d must be in range (1 - %d)\n", + uprm.cnts_ids_len, DPA_STATS_REQ_CNTS_IDS_LEN); + return -EINVAL; + } + memset(&kprm, 0, sizeof(struct ioc_dpa_stats_cnts_reset_params)); kprm.cnts_ids_len = uprm.cnts_ids_len; @@ -2005,6 +2057,14 @@ static int copy_key_descriptor_compatcpy( return -ENOMEM; } + if ((compat_ptr(key.byte) || compat_ptr(key.mask))) { + if (key.size == 0 || key.size > DPA_OFFLD_MAXENTRYKEYSIZE) { + log_err("Key size should be between %d and %d.\n", 1, + DPA_OFFLD_MAXENTRYKEYSIZE); + return -EINVAL; + } + } + if (compat_ptr(key.byte)) { /* Allocate memory to store the key byte array */ kparam->byte = kmalloc(key.size, GFP_KERNEL); |