Loading drivers/char/diag/diag_masks.c +158 −43 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ #define DIAG_SET_FEATURE_MASK(x) (feature_bytes[(x)/8] |= (1 << (x & 0x7))) #define MAX_USERSPACE_BUF_SIZ 100000 struct diag_mask_info msg_mask; struct diag_mask_info msg_bt_mask; struct diag_mask_info log_mask; Loading Loading @@ -61,6 +63,9 @@ static const struct diag_ssid_range_t msg_mask_tbl[] = { { .ssid_first = MSG_SSID_25, .ssid_last = MSG_SSID_25_LAST } }; static int diag_save_user_msg_mask(struct diag_md_session_t *info); static int diag_save_user_log_mask(struct diag_md_session_t *info); static int diag_check_update(int md_peripheral, int pid) { int ret; Loading Loading @@ -779,7 +784,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, { uint32_t mask_size = 0, offset = 0; uint32_t *temp = NULL; int write_len = 0, i = 0, found = 0, peripheral; int write_len = 0, i = 0, found = 0, peripheral, ret_val = 0; int header_len = sizeof(struct diag_msg_build_mask_t); struct diag_msg_mask_t *mask = NULL; struct diag_msg_build_mask_t *req = NULL; Loading Loading @@ -888,8 +893,6 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, mutex_unlock(&driver->msg_mask_lock); mutex_unlock(&mask_info->lock); mutex_unlock(&driver->md_session_lock); if (diag_check_update(APPS_DATA, pid)) diag_update_userspace_clients(MSG_MASKS_TYPE); /* * Apps processor must send the response to this command. Frame the Loading @@ -911,8 +914,19 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, memcpy(dest_buf + write_len, src_buf + header_len, mask_size); write_len += mask_size; for (i = 0; i < NUM_MD_SESSIONS; i++) { if (i == APPS_DATA) if (i == APPS_DATA) { mutex_lock(&driver->md_session_lock); info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC, APPS_DATA); ret_val = diag_save_user_msg_mask(info); if (ret_val < 0) pr_err("diag: unable to save msg mask to update userspace clients err:%d\n", ret_val); mutex_unlock(&driver->md_session_lock); if (diag_check_update(APPS_DATA, pid)) diag_update_userspace_clients(MSG_MASKS_TYPE); continue; } if (!diag_check_update(i, pid)) continue; if (i > NUM_PERIPHERALS) Loading @@ -931,7 +945,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len, unsigned char *dest_buf, int dest_len, int pid) { int i, write_len = 0, peripheral; int i, write_len = 0, peripheral, ret_val = 0; int header_len = sizeof(struct diag_msg_config_rsp_t); struct diag_msg_config_rsp_t rsp; struct diag_msg_config_rsp_t *req = NULL; Loading Loading @@ -988,8 +1002,6 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len, mutex_unlock(&driver->msg_mask_lock); mutex_unlock(&mask_info->lock); mutex_unlock(&driver->md_session_lock); if (diag_check_update(APPS_DATA, pid)) diag_update_userspace_clients(MSG_MASKS_TYPE); /* * Apps processor must send the response to this command. Frame the Loading @@ -1004,8 +1016,19 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len, write_len += header_len; for (i = 0; i < NUM_MD_SESSIONS; i++) { if (i == APPS_DATA) if (i == APPS_DATA) { mutex_lock(&driver->md_session_lock); info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC, APPS_DATA); ret_val = diag_save_user_msg_mask(info); if (ret_val) pr_err("diag: unable to save msg mask to update userspace clients err:%d\n", ret_val); mutex_unlock(&driver->md_session_lock); if (diag_check_update(APPS_DATA, pid)) diag_update_userspace_clients(MSG_MASKS_TYPE); continue; } if (!diag_check_update(i, pid)) continue; if (i > NUM_PERIPHERALS) Loading Loading @@ -1343,7 +1366,7 @@ static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len, { int i, peripheral, write_len = 0; int status = LOG_STATUS_SUCCESS; int read_len = 0, payload_len = 0; int read_len = 0, payload_len = 0, ret_val = 0; int req_header_len = sizeof(struct diag_log_config_req_t); int rsp_header_len = sizeof(struct diag_log_config_set_rsp_t); uint32_t mask_size = 0; Loading Loading @@ -1445,8 +1468,6 @@ static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len, } mutex_unlock(&mask_info->lock); mutex_unlock(&driver->md_session_lock); if (diag_check_update(APPS_DATA, pid)) diag_update_userspace_clients(LOG_MASKS_TYPE); /* * Apps processor must send the response to this command. Frame the Loading Loading @@ -1474,8 +1495,19 @@ static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len, write_len += payload_len; for (i = 0; i < NUM_MD_SESSIONS; i++) { if (i == APPS_DATA) if (i == APPS_DATA) { mutex_lock(&driver->md_session_lock); info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC, APPS_DATA); ret_val = diag_save_user_log_mask(info); if (ret_val < 0) pr_err("diag: unable to save log mask to update userspace clients err:%d\n", ret_val); mutex_unlock(&driver->md_session_lock); if (diag_check_update(APPS_DATA, pid)) diag_update_userspace_clients(LOG_MASKS_TYPE); continue; } if (!diag_check_update(i, pid)) continue; if (i > NUM_PERIPHERALS) Loading @@ -1496,7 +1528,7 @@ static int diag_cmd_disable_log_mask(unsigned char *src_buf, int src_len, struct diag_mask_info *mask_info = NULL; struct diag_log_mask_t *mask = NULL; struct diag_log_config_rsp_t header; int write_len = 0, i, peripheral; int write_len = 0, i, peripheral, ret_val = 0; struct diag_md_session_t *info = NULL; mutex_lock(&driver->md_session_lock); Loading Loading @@ -1533,8 +1565,6 @@ static int diag_cmd_disable_log_mask(unsigned char *src_buf, int src_len, } mask_info->status = DIAG_CTRL_MASK_ALL_DISABLED; mutex_unlock(&driver->md_session_lock); if (diag_check_update(APPS_DATA, pid)) diag_update_userspace_clients(LOG_MASKS_TYPE); /* * Apps processor must send the response to this command. Frame the Loading @@ -1549,8 +1579,19 @@ static int diag_cmd_disable_log_mask(unsigned char *src_buf, int src_len, memcpy(dest_buf, &header, sizeof(struct diag_log_config_rsp_t)); write_len += sizeof(struct diag_log_config_rsp_t); for (i = 0; i < NUM_MD_SESSIONS; i++) { if (i == APPS_DATA) if (i == APPS_DATA) { mutex_lock(&driver->md_session_lock); info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC, APPS_DATA); ret_val = diag_save_user_log_mask(info); if (ret_val < 0) pr_err("diag: unable to save log mask to update userspace clients err:%d\n", ret_val); mutex_unlock(&driver->md_session_lock); if (diag_check_update(APPS_DATA, pid)) diag_update_userspace_clients(LOG_MASKS_TYPE); continue; } if (!diag_check_update(i, pid)) continue; if (i > NUM_PERIPHERALS) Loading Loading @@ -1792,6 +1833,17 @@ static int __diag_mask_init(struct diag_mask_info *mask_info, int mask_len, return -ENOMEM; } kmemleak_not_leak(mask_info->update_buf); mask_info->update_buf_client = kzalloc(MAX_USERSPACE_BUF_SIZ, GFP_KERNEL); if (!mask_info->update_buf_client) { kfree(mask_info->update_buf); mask_info->update_buf = NULL; kfree(mask_info->ptr); mask_info->ptr = NULL; return -ENOMEM; } kmemleak_not_leak(mask_info->update_buf_client); mask_info->update_buf_client_len = 0; } return 0; } Loading @@ -1806,6 +1858,8 @@ static void __diag_mask_exit(struct diag_mask_info *mask_info) mask_info->ptr = NULL; kfree(mask_info->update_buf); mask_info->update_buf = NULL; kfree(mask_info->update_buf_client); mask_info->update_buf_client = NULL; mutex_unlock(&mask_info->lock); } Loading Loading @@ -1879,6 +1933,7 @@ void diag_log_mask_free(struct diag_mask_info *mask_info) static int diag_msg_mask_init(void) { int err = 0, i; struct diag_md_session_t *session_info = NULL; mutex_init(&msg_mask.lock); err = __diag_mask_init(&msg_mask, MSG_MASK_SIZE, APPS_BUF_SIZE); Loading @@ -1896,6 +1951,14 @@ static int diag_msg_mask_init(void) driver->max_ssid_count[i] = 0; mutex_unlock(&driver->msg_mask_lock); mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC, APPS_DATA); err = diag_save_user_msg_mask(session_info); if (err < 0) pr_err("diag: unable to save msg mask to update userspace clients err:%d\n", err); mutex_unlock(&driver->md_session_lock); return 0; } Loading Loading @@ -1993,6 +2056,8 @@ static void diag_msg_mask_exit(void) } kfree(msg_mask.update_buf); msg_mask.update_buf = NULL; kfree(msg_mask.update_buf_client); msg_mask.update_buf_client = NULL; mutex_unlock(&driver->msg_mask_lock); } Loading Loading @@ -2034,6 +2099,7 @@ static void diag_build_time_mask_exit(void) static int diag_log_mask_init(void) { int err = 0, i; struct diag_md_session_t *session_info = NULL; mutex_init(&log_mask.lock); err = __diag_mask_init(&log_mask, LOG_MASK_SIZE, APPS_BUF_SIZE); Loading @@ -2046,7 +2112,14 @@ static int diag_log_mask_init(void) for (i = 0; i < NUM_PERIPHERALS; i++) driver->num_equip_id[i] = 0; mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC, APPS_DATA); err = diag_save_user_log_mask(session_info); if (err < 0) pr_err("diag: unable to save log mask to update userspace clients err:%d\n", err); mutex_unlock(&driver->md_session_lock); return 0; } Loading @@ -2063,6 +2136,8 @@ static void diag_log_mask_exit(void) } kfree(log_mask.update_buf); kfree(log_mask.update_buf_client); log_mask.update_buf_client = NULL; } static int diag_event_mask_init(void) Loading Loading @@ -2121,6 +2196,59 @@ static void diag_event_mask_exit(void) int diag_copy_to_user_msg_mask(char __user *buf, size_t count, struct diag_md_session_t *info) { struct diag_mask_info *mask_info = NULL; int err = 0; if (!buf || count == 0) return -EINVAL; mask_info = (!info) ? &msg_mask : info->msg_mask; if (!mask_info) return -EIO; if (!mask_info->ptr || !mask_info->update_buf_client) { pr_err("diag: In %s, invalid input mask_info->ptr: %pK, mask_info->update_buf_client: %pK\n", __func__, mask_info->ptr, mask_info->update_buf_client); return -EINVAL; } err = copy_to_user(buf, mask_info->update_buf_client, mask_info->update_buf_client_len); if (err) { pr_err("diag: In %s Unable to send msg masks to user space clients, err: %d\n", __func__, err); } return err ? err : mask_info->update_buf_client_len; } int diag_copy_to_user_log_mask(char __user *buf, size_t count, struct diag_md_session_t *info) { struct diag_mask_info *mask_info = NULL; int err = 0; if (!buf || count == 0) return -EINVAL; mask_info = (!info) ? &log_mask : info->log_mask; if (!mask_info) return -EIO; if (!mask_info->ptr || !mask_info->update_buf_client) { pr_err("diag: In %s, invalid input mask_info->ptr: %pK, mask_info->update_buf_client: %pK\n", __func__, mask_info->ptr, mask_info->update_buf_client); return -EINVAL; } err = copy_to_user(buf, mask_info->update_buf_client, mask_info->update_buf_client_len); if (err) { pr_err("diag: In %s Unable to send msg masks to user space clients, err: %d\n", __func__, err); } return err ? err : mask_info->update_buf_client_len; } static int diag_save_user_msg_mask(struct diag_md_session_t *info) { int i, err = 0, len = 0; int copy_len = 0, total_len = 0; Loading @@ -2130,9 +2258,6 @@ int diag_copy_to_user_msg_mask(char __user *buf, size_t count, unsigned char *ptr = NULL; uint8_t msg_mask_tbl_count = 0; if (!buf || count == 0) return -EINVAL; mask_info = (!info) ? &msg_mask : info->msg_mask; if (!mask_info) return -EIO; Loading Loading @@ -2178,27 +2303,23 @@ int diag_copy_to_user_msg_mask(char __user *buf, size_t count, len += copy_len; mutex_unlock(&mask->lock); /* + sizeof(int) to account for data_type already in buf */ if (total_len + sizeof(int) + len > count) { pr_err("diag: In %s, unable to send msg masks to user space, total_len: %d, count: %zu\n", __func__, total_len, count); if (total_len + sizeof(int) + len > MAX_USERSPACE_BUF_SIZ) { pr_err("diag: In %s, unable to send msg masks to user space, total_len: %d,\n", __func__, total_len); err = -ENOMEM; break; } err = copy_to_user(buf + total_len, (void *)ptr, len); if (err) { pr_err("diag: In %s Unable to send msg masks to user space clients, err: %d\n", __func__, err); break; } memcpy(mask_info->update_buf_client + total_len, (void *)ptr, len); total_len += len; } mask_info->update_buf_client_len = total_len; mutex_unlock(&driver->msg_mask_lock); mutex_unlock(&mask_info->lock); return err ? err : total_len; } int diag_copy_to_user_log_mask(char __user *buf, size_t count, struct diag_md_session_t *info) static int diag_save_user_log_mask(struct diag_md_session_t *info) { int i, err = 0, len = 0; int copy_len = 0, total_len = 0; Loading @@ -2207,9 +2328,6 @@ int diag_copy_to_user_log_mask(char __user *buf, size_t count, struct diag_mask_info *mask_info = NULL; unsigned char *ptr = NULL; if (!buf || count == 0) return -EINVAL; mask_info = (!info) ? &log_mask : info->log_mask; if (!mask_info) return -EIO; Loading Loading @@ -2249,20 +2367,17 @@ int diag_copy_to_user_log_mask(char __user *buf, size_t count, len += copy_len; mutex_unlock(&mask->lock); /* + sizeof(int) to account for data_type already in buf */ if (total_len + sizeof(int) + len > count) { pr_err("diag: In %s, unable to send log masks to user space, total_len: %d, count: %zu\n", __func__, total_len, count); if (total_len + sizeof(int) + len > MAX_USERSPACE_BUF_SIZ) { pr_err("diag: In %s, unable to send log masks to user space, total_len: %d\n", __func__, total_len); err = -ENOMEM; break; } err = copy_to_user(buf + total_len, (void *)ptr, len); if (err) { pr_err("diag: In %s Unable to send log masks to user space clients, err: %d\n", __func__, err); break; } memcpy(mask_info->update_buf_client + total_len, (void *)ptr, len); total_len += len; } mask_info->update_buf_client_len = total_len; mutex_unlock(&mask_info->lock); return err ? err : total_len; Loading drivers/char/diag/diagchar.h +2 −0 Original line number Diff line number Diff line Loading @@ -550,6 +550,8 @@ struct diag_mask_info { int mask_len; uint8_t *update_buf; int update_buf_len; uint8_t *update_buf_client; int update_buf_client_len; uint8_t status; struct mutex lock; }; Loading drivers/char/diag/diagchar_core.c +19 −8 Original line number Diff line number Diff line Loading @@ -3701,19 +3701,24 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, if (driver->data_ready[index] & MSG_MASKS_TYPE) { /*Copy the type of data being passed*/ data_type = driver->data_ready[index] & MSG_MASKS_TYPE; mutex_unlock(&driver->diagchar_mutex); mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC, APPS_DATA); COPY_USER_SPACE_OR_ERR(buf, data_type, sizeof(int)); if (ret == -EFAULT) { mutex_unlock(&driver->md_session_lock); goto exit; goto end; } if (!session_info) mutex_unlock(&driver->md_session_lock); write_len = diag_copy_to_user_msg_mask(buf + ret, count, session_info); if (session_info) mutex_unlock(&driver->md_session_lock); if (write_len > 0) ret += write_len; mutex_lock(&driver->diagchar_mutex); driver->data_ready[index] ^= MSG_MASKS_TYPE; atomic_dec(&driver->data_ready_notif[index]); goto exit; Loading @@ -3722,13 +3727,14 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, if (driver->data_ready[index] & EVENT_MASKS_TYPE) { /*Copy the type of data being passed*/ data_type = driver->data_ready[index] & EVENT_MASKS_TYPE; mutex_unlock(&driver->diagchar_mutex); mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC, APPS_DATA); COPY_USER_SPACE_OR_ERR(buf, data_type, 4); if (ret == -EFAULT) { mutex_unlock(&driver->md_session_lock); goto exit; goto end; } if (session_info && session_info->event_mask && session_info->event_mask->ptr) { Loading @@ -3737,7 +3743,7 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, session_info->event_mask->mask_len); if (ret == -EFAULT) { mutex_unlock(&driver->md_session_lock); goto exit; goto end; } } else { COPY_USER_SPACE_OR_ERR(buf + sizeof(int), Loading @@ -3745,10 +3751,11 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, event_mask.mask_len); if (ret == -EFAULT) { mutex_unlock(&driver->md_session_lock); goto exit; goto end; } } mutex_unlock(&driver->md_session_lock); mutex_lock(&driver->diagchar_mutex); driver->data_ready[index] ^= EVENT_MASKS_TYPE; atomic_dec(&driver->data_ready_notif[index]); goto exit; Loading @@ -3757,20 +3764,24 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, if (driver->data_ready[index] & LOG_MASKS_TYPE) { /*Copy the type of data being passed*/ data_type = driver->data_ready[index] & LOG_MASKS_TYPE; mutex_unlock(&driver->diagchar_mutex); mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC, APPS_DATA); COPY_USER_SPACE_OR_ERR(buf, data_type, sizeof(int)); if (ret == -EFAULT) { mutex_unlock(&driver->md_session_lock); goto exit; goto end; } if (!session_info) mutex_unlock(&driver->md_session_lock); write_len = diag_copy_to_user_log_mask(buf + ret, count, session_info); if (session_info) mutex_unlock(&driver->md_session_lock); if (write_len > 0) ret += write_len; mutex_lock(&driver->diagchar_mutex); driver->data_ready[index] ^= LOG_MASKS_TYPE; atomic_dec(&driver->data_ready_notif[index]); goto exit; Loading Loading
drivers/char/diag/diag_masks.c +158 −43 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ #define DIAG_SET_FEATURE_MASK(x) (feature_bytes[(x)/8] |= (1 << (x & 0x7))) #define MAX_USERSPACE_BUF_SIZ 100000 struct diag_mask_info msg_mask; struct diag_mask_info msg_bt_mask; struct diag_mask_info log_mask; Loading Loading @@ -61,6 +63,9 @@ static const struct diag_ssid_range_t msg_mask_tbl[] = { { .ssid_first = MSG_SSID_25, .ssid_last = MSG_SSID_25_LAST } }; static int diag_save_user_msg_mask(struct diag_md_session_t *info); static int diag_save_user_log_mask(struct diag_md_session_t *info); static int diag_check_update(int md_peripheral, int pid) { int ret; Loading Loading @@ -779,7 +784,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, { uint32_t mask_size = 0, offset = 0; uint32_t *temp = NULL; int write_len = 0, i = 0, found = 0, peripheral; int write_len = 0, i = 0, found = 0, peripheral, ret_val = 0; int header_len = sizeof(struct diag_msg_build_mask_t); struct diag_msg_mask_t *mask = NULL; struct diag_msg_build_mask_t *req = NULL; Loading Loading @@ -888,8 +893,6 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, mutex_unlock(&driver->msg_mask_lock); mutex_unlock(&mask_info->lock); mutex_unlock(&driver->md_session_lock); if (diag_check_update(APPS_DATA, pid)) diag_update_userspace_clients(MSG_MASKS_TYPE); /* * Apps processor must send the response to this command. Frame the Loading @@ -911,8 +914,19 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, memcpy(dest_buf + write_len, src_buf + header_len, mask_size); write_len += mask_size; for (i = 0; i < NUM_MD_SESSIONS; i++) { if (i == APPS_DATA) if (i == APPS_DATA) { mutex_lock(&driver->md_session_lock); info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC, APPS_DATA); ret_val = diag_save_user_msg_mask(info); if (ret_val < 0) pr_err("diag: unable to save msg mask to update userspace clients err:%d\n", ret_val); mutex_unlock(&driver->md_session_lock); if (diag_check_update(APPS_DATA, pid)) diag_update_userspace_clients(MSG_MASKS_TYPE); continue; } if (!diag_check_update(i, pid)) continue; if (i > NUM_PERIPHERALS) Loading @@ -931,7 +945,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len, unsigned char *dest_buf, int dest_len, int pid) { int i, write_len = 0, peripheral; int i, write_len = 0, peripheral, ret_val = 0; int header_len = sizeof(struct diag_msg_config_rsp_t); struct diag_msg_config_rsp_t rsp; struct diag_msg_config_rsp_t *req = NULL; Loading Loading @@ -988,8 +1002,6 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len, mutex_unlock(&driver->msg_mask_lock); mutex_unlock(&mask_info->lock); mutex_unlock(&driver->md_session_lock); if (diag_check_update(APPS_DATA, pid)) diag_update_userspace_clients(MSG_MASKS_TYPE); /* * Apps processor must send the response to this command. Frame the Loading @@ -1004,8 +1016,19 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len, write_len += header_len; for (i = 0; i < NUM_MD_SESSIONS; i++) { if (i == APPS_DATA) if (i == APPS_DATA) { mutex_lock(&driver->md_session_lock); info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC, APPS_DATA); ret_val = diag_save_user_msg_mask(info); if (ret_val) pr_err("diag: unable to save msg mask to update userspace clients err:%d\n", ret_val); mutex_unlock(&driver->md_session_lock); if (diag_check_update(APPS_DATA, pid)) diag_update_userspace_clients(MSG_MASKS_TYPE); continue; } if (!diag_check_update(i, pid)) continue; if (i > NUM_PERIPHERALS) Loading Loading @@ -1343,7 +1366,7 @@ static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len, { int i, peripheral, write_len = 0; int status = LOG_STATUS_SUCCESS; int read_len = 0, payload_len = 0; int read_len = 0, payload_len = 0, ret_val = 0; int req_header_len = sizeof(struct diag_log_config_req_t); int rsp_header_len = sizeof(struct diag_log_config_set_rsp_t); uint32_t mask_size = 0; Loading Loading @@ -1445,8 +1468,6 @@ static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len, } mutex_unlock(&mask_info->lock); mutex_unlock(&driver->md_session_lock); if (diag_check_update(APPS_DATA, pid)) diag_update_userspace_clients(LOG_MASKS_TYPE); /* * Apps processor must send the response to this command. Frame the Loading Loading @@ -1474,8 +1495,19 @@ static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len, write_len += payload_len; for (i = 0; i < NUM_MD_SESSIONS; i++) { if (i == APPS_DATA) if (i == APPS_DATA) { mutex_lock(&driver->md_session_lock); info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC, APPS_DATA); ret_val = diag_save_user_log_mask(info); if (ret_val < 0) pr_err("diag: unable to save log mask to update userspace clients err:%d\n", ret_val); mutex_unlock(&driver->md_session_lock); if (diag_check_update(APPS_DATA, pid)) diag_update_userspace_clients(LOG_MASKS_TYPE); continue; } if (!diag_check_update(i, pid)) continue; if (i > NUM_PERIPHERALS) Loading @@ -1496,7 +1528,7 @@ static int diag_cmd_disable_log_mask(unsigned char *src_buf, int src_len, struct diag_mask_info *mask_info = NULL; struct diag_log_mask_t *mask = NULL; struct diag_log_config_rsp_t header; int write_len = 0, i, peripheral; int write_len = 0, i, peripheral, ret_val = 0; struct diag_md_session_t *info = NULL; mutex_lock(&driver->md_session_lock); Loading Loading @@ -1533,8 +1565,6 @@ static int diag_cmd_disable_log_mask(unsigned char *src_buf, int src_len, } mask_info->status = DIAG_CTRL_MASK_ALL_DISABLED; mutex_unlock(&driver->md_session_lock); if (diag_check_update(APPS_DATA, pid)) diag_update_userspace_clients(LOG_MASKS_TYPE); /* * Apps processor must send the response to this command. Frame the Loading @@ -1549,8 +1579,19 @@ static int diag_cmd_disable_log_mask(unsigned char *src_buf, int src_len, memcpy(dest_buf, &header, sizeof(struct diag_log_config_rsp_t)); write_len += sizeof(struct diag_log_config_rsp_t); for (i = 0; i < NUM_MD_SESSIONS; i++) { if (i == APPS_DATA) if (i == APPS_DATA) { mutex_lock(&driver->md_session_lock); info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC, APPS_DATA); ret_val = diag_save_user_log_mask(info); if (ret_val < 0) pr_err("diag: unable to save log mask to update userspace clients err:%d\n", ret_val); mutex_unlock(&driver->md_session_lock); if (diag_check_update(APPS_DATA, pid)) diag_update_userspace_clients(LOG_MASKS_TYPE); continue; } if (!diag_check_update(i, pid)) continue; if (i > NUM_PERIPHERALS) Loading Loading @@ -1792,6 +1833,17 @@ static int __diag_mask_init(struct diag_mask_info *mask_info, int mask_len, return -ENOMEM; } kmemleak_not_leak(mask_info->update_buf); mask_info->update_buf_client = kzalloc(MAX_USERSPACE_BUF_SIZ, GFP_KERNEL); if (!mask_info->update_buf_client) { kfree(mask_info->update_buf); mask_info->update_buf = NULL; kfree(mask_info->ptr); mask_info->ptr = NULL; return -ENOMEM; } kmemleak_not_leak(mask_info->update_buf_client); mask_info->update_buf_client_len = 0; } return 0; } Loading @@ -1806,6 +1858,8 @@ static void __diag_mask_exit(struct diag_mask_info *mask_info) mask_info->ptr = NULL; kfree(mask_info->update_buf); mask_info->update_buf = NULL; kfree(mask_info->update_buf_client); mask_info->update_buf_client = NULL; mutex_unlock(&mask_info->lock); } Loading Loading @@ -1879,6 +1933,7 @@ void diag_log_mask_free(struct diag_mask_info *mask_info) static int diag_msg_mask_init(void) { int err = 0, i; struct diag_md_session_t *session_info = NULL; mutex_init(&msg_mask.lock); err = __diag_mask_init(&msg_mask, MSG_MASK_SIZE, APPS_BUF_SIZE); Loading @@ -1896,6 +1951,14 @@ static int diag_msg_mask_init(void) driver->max_ssid_count[i] = 0; mutex_unlock(&driver->msg_mask_lock); mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC, APPS_DATA); err = diag_save_user_msg_mask(session_info); if (err < 0) pr_err("diag: unable to save msg mask to update userspace clients err:%d\n", err); mutex_unlock(&driver->md_session_lock); return 0; } Loading Loading @@ -1993,6 +2056,8 @@ static void diag_msg_mask_exit(void) } kfree(msg_mask.update_buf); msg_mask.update_buf = NULL; kfree(msg_mask.update_buf_client); msg_mask.update_buf_client = NULL; mutex_unlock(&driver->msg_mask_lock); } Loading Loading @@ -2034,6 +2099,7 @@ static void diag_build_time_mask_exit(void) static int diag_log_mask_init(void) { int err = 0, i; struct diag_md_session_t *session_info = NULL; mutex_init(&log_mask.lock); err = __diag_mask_init(&log_mask, LOG_MASK_SIZE, APPS_BUF_SIZE); Loading @@ -2046,7 +2112,14 @@ static int diag_log_mask_init(void) for (i = 0; i < NUM_PERIPHERALS; i++) driver->num_equip_id[i] = 0; mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC, APPS_DATA); err = diag_save_user_log_mask(session_info); if (err < 0) pr_err("diag: unable to save log mask to update userspace clients err:%d\n", err); mutex_unlock(&driver->md_session_lock); return 0; } Loading @@ -2063,6 +2136,8 @@ static void diag_log_mask_exit(void) } kfree(log_mask.update_buf); kfree(log_mask.update_buf_client); log_mask.update_buf_client = NULL; } static int diag_event_mask_init(void) Loading Loading @@ -2121,6 +2196,59 @@ static void diag_event_mask_exit(void) int diag_copy_to_user_msg_mask(char __user *buf, size_t count, struct diag_md_session_t *info) { struct diag_mask_info *mask_info = NULL; int err = 0; if (!buf || count == 0) return -EINVAL; mask_info = (!info) ? &msg_mask : info->msg_mask; if (!mask_info) return -EIO; if (!mask_info->ptr || !mask_info->update_buf_client) { pr_err("diag: In %s, invalid input mask_info->ptr: %pK, mask_info->update_buf_client: %pK\n", __func__, mask_info->ptr, mask_info->update_buf_client); return -EINVAL; } err = copy_to_user(buf, mask_info->update_buf_client, mask_info->update_buf_client_len); if (err) { pr_err("diag: In %s Unable to send msg masks to user space clients, err: %d\n", __func__, err); } return err ? err : mask_info->update_buf_client_len; } int diag_copy_to_user_log_mask(char __user *buf, size_t count, struct diag_md_session_t *info) { struct diag_mask_info *mask_info = NULL; int err = 0; if (!buf || count == 0) return -EINVAL; mask_info = (!info) ? &log_mask : info->log_mask; if (!mask_info) return -EIO; if (!mask_info->ptr || !mask_info->update_buf_client) { pr_err("diag: In %s, invalid input mask_info->ptr: %pK, mask_info->update_buf_client: %pK\n", __func__, mask_info->ptr, mask_info->update_buf_client); return -EINVAL; } err = copy_to_user(buf, mask_info->update_buf_client, mask_info->update_buf_client_len); if (err) { pr_err("diag: In %s Unable to send msg masks to user space clients, err: %d\n", __func__, err); } return err ? err : mask_info->update_buf_client_len; } static int diag_save_user_msg_mask(struct diag_md_session_t *info) { int i, err = 0, len = 0; int copy_len = 0, total_len = 0; Loading @@ -2130,9 +2258,6 @@ int diag_copy_to_user_msg_mask(char __user *buf, size_t count, unsigned char *ptr = NULL; uint8_t msg_mask_tbl_count = 0; if (!buf || count == 0) return -EINVAL; mask_info = (!info) ? &msg_mask : info->msg_mask; if (!mask_info) return -EIO; Loading Loading @@ -2178,27 +2303,23 @@ int diag_copy_to_user_msg_mask(char __user *buf, size_t count, len += copy_len; mutex_unlock(&mask->lock); /* + sizeof(int) to account for data_type already in buf */ if (total_len + sizeof(int) + len > count) { pr_err("diag: In %s, unable to send msg masks to user space, total_len: %d, count: %zu\n", __func__, total_len, count); if (total_len + sizeof(int) + len > MAX_USERSPACE_BUF_SIZ) { pr_err("diag: In %s, unable to send msg masks to user space, total_len: %d,\n", __func__, total_len); err = -ENOMEM; break; } err = copy_to_user(buf + total_len, (void *)ptr, len); if (err) { pr_err("diag: In %s Unable to send msg masks to user space clients, err: %d\n", __func__, err); break; } memcpy(mask_info->update_buf_client + total_len, (void *)ptr, len); total_len += len; } mask_info->update_buf_client_len = total_len; mutex_unlock(&driver->msg_mask_lock); mutex_unlock(&mask_info->lock); return err ? err : total_len; } int diag_copy_to_user_log_mask(char __user *buf, size_t count, struct diag_md_session_t *info) static int diag_save_user_log_mask(struct diag_md_session_t *info) { int i, err = 0, len = 0; int copy_len = 0, total_len = 0; Loading @@ -2207,9 +2328,6 @@ int diag_copy_to_user_log_mask(char __user *buf, size_t count, struct diag_mask_info *mask_info = NULL; unsigned char *ptr = NULL; if (!buf || count == 0) return -EINVAL; mask_info = (!info) ? &log_mask : info->log_mask; if (!mask_info) return -EIO; Loading Loading @@ -2249,20 +2367,17 @@ int diag_copy_to_user_log_mask(char __user *buf, size_t count, len += copy_len; mutex_unlock(&mask->lock); /* + sizeof(int) to account for data_type already in buf */ if (total_len + sizeof(int) + len > count) { pr_err("diag: In %s, unable to send log masks to user space, total_len: %d, count: %zu\n", __func__, total_len, count); if (total_len + sizeof(int) + len > MAX_USERSPACE_BUF_SIZ) { pr_err("diag: In %s, unable to send log masks to user space, total_len: %d\n", __func__, total_len); err = -ENOMEM; break; } err = copy_to_user(buf + total_len, (void *)ptr, len); if (err) { pr_err("diag: In %s Unable to send log masks to user space clients, err: %d\n", __func__, err); break; } memcpy(mask_info->update_buf_client + total_len, (void *)ptr, len); total_len += len; } mask_info->update_buf_client_len = total_len; mutex_unlock(&mask_info->lock); return err ? err : total_len; Loading
drivers/char/diag/diagchar.h +2 −0 Original line number Diff line number Diff line Loading @@ -550,6 +550,8 @@ struct diag_mask_info { int mask_len; uint8_t *update_buf; int update_buf_len; uint8_t *update_buf_client; int update_buf_client_len; uint8_t status; struct mutex lock; }; Loading
drivers/char/diag/diagchar_core.c +19 −8 Original line number Diff line number Diff line Loading @@ -3701,19 +3701,24 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, if (driver->data_ready[index] & MSG_MASKS_TYPE) { /*Copy the type of data being passed*/ data_type = driver->data_ready[index] & MSG_MASKS_TYPE; mutex_unlock(&driver->diagchar_mutex); mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC, APPS_DATA); COPY_USER_SPACE_OR_ERR(buf, data_type, sizeof(int)); if (ret == -EFAULT) { mutex_unlock(&driver->md_session_lock); goto exit; goto end; } if (!session_info) mutex_unlock(&driver->md_session_lock); write_len = diag_copy_to_user_msg_mask(buf + ret, count, session_info); if (session_info) mutex_unlock(&driver->md_session_lock); if (write_len > 0) ret += write_len; mutex_lock(&driver->diagchar_mutex); driver->data_ready[index] ^= MSG_MASKS_TYPE; atomic_dec(&driver->data_ready_notif[index]); goto exit; Loading @@ -3722,13 +3727,14 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, if (driver->data_ready[index] & EVENT_MASKS_TYPE) { /*Copy the type of data being passed*/ data_type = driver->data_ready[index] & EVENT_MASKS_TYPE; mutex_unlock(&driver->diagchar_mutex); mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC, APPS_DATA); COPY_USER_SPACE_OR_ERR(buf, data_type, 4); if (ret == -EFAULT) { mutex_unlock(&driver->md_session_lock); goto exit; goto end; } if (session_info && session_info->event_mask && session_info->event_mask->ptr) { Loading @@ -3737,7 +3743,7 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, session_info->event_mask->mask_len); if (ret == -EFAULT) { mutex_unlock(&driver->md_session_lock); goto exit; goto end; } } else { COPY_USER_SPACE_OR_ERR(buf + sizeof(int), Loading @@ -3745,10 +3751,11 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, event_mask.mask_len); if (ret == -EFAULT) { mutex_unlock(&driver->md_session_lock); goto exit; goto end; } } mutex_unlock(&driver->md_session_lock); mutex_lock(&driver->diagchar_mutex); driver->data_ready[index] ^= EVENT_MASKS_TYPE; atomic_dec(&driver->data_ready_notif[index]); goto exit; Loading @@ -3757,20 +3764,24 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, if (driver->data_ready[index] & LOG_MASKS_TYPE) { /*Copy the type of data being passed*/ data_type = driver->data_ready[index] & LOG_MASKS_TYPE; mutex_unlock(&driver->diagchar_mutex); mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC, APPS_DATA); COPY_USER_SPACE_OR_ERR(buf, data_type, sizeof(int)); if (ret == -EFAULT) { mutex_unlock(&driver->md_session_lock); goto exit; goto end; } if (!session_info) mutex_unlock(&driver->md_session_lock); write_len = diag_copy_to_user_log_mask(buf + ret, count, session_info); if (session_info) mutex_unlock(&driver->md_session_lock); if (write_len > 0) ret += write_len; mutex_lock(&driver->diagchar_mutex); driver->data_ready[index] ^= LOG_MASKS_TYPE; atomic_dec(&driver->data_ready_notif[index]); goto exit; Loading