Loading drivers/char/diag/diag_masks.c +129 −40 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #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 +62,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 @@ -888,8 +892,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 @@ -910,8 +912,16 @@ 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); diag_save_user_msg_mask(info); 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 @@ -987,8 +997,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 @@ -1003,8 +1011,16 @@ 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); diag_save_user_msg_mask(info); 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 @@ -1444,8 +1460,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 @@ -1473,8 +1487,16 @@ 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); diag_save_user_log_mask(info); 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 @@ -1532,8 +1554,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 @@ -1548,8 +1568,16 @@ 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); diag_save_user_log_mask(info); 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 @@ -1791,6 +1819,15 @@ 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->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 Loading @@ -1878,6 +1915,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 @@ -1895,6 +1933,11 @@ 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); diag_save_user_msg_mask(session_info); mutex_unlock(&driver->md_session_lock); return 0; } Loading Loading @@ -1992,6 +2035,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 @@ -2033,7 +2078,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); if (err) Loading @@ -2045,7 +2090,11 @@ 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); diag_save_user_log_mask(session_info); mutex_unlock(&driver->md_session_lock); return 0; } Loading Loading @@ -2120,6 +2169,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: %pK\n", __func__, mask_info->ptr, mask_info->update_buf); 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_len) { pr_err("diag: In %s, invalid input mask_info->ptr: %pK, mask_info->update_buf: %pK\n", __func__, mask_info->ptr, mask_info->update_buf); 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 @@ -2129,9 +2231,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 @@ -2177,27 +2276,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 @@ -2206,9 +2301,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 @@ -2248,20 +2340,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 + 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 @@ -546,6 +546,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 +16 −3 Original line number Diff line number Diff line Loading @@ -3703,9 +3703,12 @@ 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); if (!session_info) mutex_unlock(&driver->md_session_lock); COPY_USER_SPACE_OR_ERR(buf, data_type, sizeof(int)); if (ret == -EFAULT) { mutex_unlock(&driver->md_session_lock); Loading @@ -3713,9 +3716,11 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, } 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 @@ -3724,6 +3729,7 @@ 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); Loading Loading @@ -3751,6 +3757,7 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, } } 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 @@ -3759,20 +3766,26 @@ 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); if (!session_info) mutex_unlock(&driver->md_session_lock); COPY_USER_SPACE_OR_ERR(buf, data_type, sizeof(int)); if (ret == -EFAULT) { if ((session_info)) mutex_unlock(&driver->md_session_lock); goto exit; } 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 +129 −40 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #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 +62,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 @@ -888,8 +892,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 @@ -910,8 +912,16 @@ 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); diag_save_user_msg_mask(info); 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 @@ -987,8 +997,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 @@ -1003,8 +1011,16 @@ 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); diag_save_user_msg_mask(info); 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 @@ -1444,8 +1460,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 @@ -1473,8 +1487,16 @@ 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); diag_save_user_log_mask(info); 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 @@ -1532,8 +1554,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 @@ -1548,8 +1568,16 @@ 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); diag_save_user_log_mask(info); 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 @@ -1791,6 +1819,15 @@ 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->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 Loading @@ -1878,6 +1915,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 @@ -1895,6 +1933,11 @@ 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); diag_save_user_msg_mask(session_info); mutex_unlock(&driver->md_session_lock); return 0; } Loading Loading @@ -1992,6 +2035,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 @@ -2033,7 +2078,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); if (err) Loading @@ -2045,7 +2090,11 @@ 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); diag_save_user_log_mask(session_info); mutex_unlock(&driver->md_session_lock); return 0; } Loading Loading @@ -2120,6 +2169,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: %pK\n", __func__, mask_info->ptr, mask_info->update_buf); 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_len) { pr_err("diag: In %s, invalid input mask_info->ptr: %pK, mask_info->update_buf: %pK\n", __func__, mask_info->ptr, mask_info->update_buf); 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 @@ -2129,9 +2231,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 @@ -2177,27 +2276,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 @@ -2206,9 +2301,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 @@ -2248,20 +2340,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 + 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 @@ -546,6 +546,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 +16 −3 Original line number Diff line number Diff line Loading @@ -3703,9 +3703,12 @@ 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); if (!session_info) mutex_unlock(&driver->md_session_lock); COPY_USER_SPACE_OR_ERR(buf, data_type, sizeof(int)); if (ret == -EFAULT) { mutex_unlock(&driver->md_session_lock); Loading @@ -3713,9 +3716,11 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, } 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 @@ -3724,6 +3729,7 @@ 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); Loading Loading @@ -3751,6 +3757,7 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, } } 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 @@ -3759,20 +3766,26 @@ 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); if (!session_info) mutex_unlock(&driver->md_session_lock); COPY_USER_SPACE_OR_ERR(buf, data_type, sizeof(int)); if (ret == -EFAULT) { if ((session_info)) mutex_unlock(&driver->md_session_lock); goto exit; } 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