In the function bcm_vk_read(), the pointer entry is checked, indicating that it can be NULL. If entry is NULL and rc is set to -EMSGSIZE, the following code may cause null-pointer dereferences: struct vk_msg_blk tmp_msg = entry->to_h_msg[0]; set_msg_id(&tmp_msg, entry->usr_msg_id); tmp_msg.size = entry->to_h_blks - 1; To prevent these possible null-pointer dereferences, copy to_h_msg, usr_msg_id, and to_h_blks from iter into temporary variables, and return these temporary variables to the application instead of accessing them through a potentially NULL entry.
Unified · Split
| @@ -1010,6 +1010,9 @@ ssize_t bcm_vk_read(struct file *p_file, · 1009 unmodified lines | ||
| 1010 | 1010 | struct device *dev = &vk->pdev->dev; |
| 1011 | 1011 | struct bcm_vk_msg_chan *chan = &vk->to_h_msg_chan; |
| 1012 | 1012 | struct bcm_vk_wkent *entry = NULL, *iter; |
| 1013 | + struct vk_msg_blk tmp_msg; | |
| 1014 | + u32 tmp_usr_msg_id; | |
| 1015 | + u32 tmp_blks; | |
| 1013 | 1016 | u32 q_num; |
| 1014 | 1017 | u32 rsp_length; |
| 1015 | 1018 | |
| @@ -1034,6 +1037,9 @@ ssize_t bcm_vk_read(struct file *p_file, · 18 unmodified lines | ||
| 1034 | 1037 | entry = iter; |
| 1035 | 1038 | } else { |
| 1036 | 1039 | /* buffer not big enough */ |
| 1040 | + tmp_msg = iter->to_h_msg[0]; | |
| 1041 | + tmp_usr_msg_id = iter->usr_msg_id; | |
| 1042 | + tmp_blks = iter->to_h_blks; | |
| 1037 | 1043 | rc = -EMSGSIZE; |
| 1038 | 1044 | } |
| 1039 | 1045 | goto read_loop_exit; |
| @@ -1052,14 +1058,12 @@ read_loop_exit: · 12 unmodified lines | ||
| 1052 | 1058 | |
| 1053 | 1059 | bcm_vk_free_wkent(dev, entry); |
| 1054 | 1060 | } else if (rc == -EMSGSIZE) { |
| 1055 | − struct vk_msg_blk tmp_msg = entry->to_h_msg[0]; | |
| 1056 | − | |
| 1057 | 1061 | /* |
| 1058 | 1062 | * in this case, return just the first block, so |
| 1059 | 1063 | * that app knows what size it is looking for. |
| 1060 | 1064 | */ |
| 1061 | − set_msg_id(&tmp_msg, entry->usr_msg_id); | |
| 1062 | − tmp_msg.size = entry->to_h_blks - 1; | |
| 1065 | + set_msg_id(&tmp_msg, tmp_usr_msg_id); | |
| 1066 | + tmp_msg.size = tmp_blks - 1; | |
| 1063 | 1067 | if (copy_to_user(buf, &tmp_msg, VK_MSGQ_BLK_SIZE) != 0) { |
| 1064 | 1068 | dev_err(dev, "Error return 1st block in -EMSGSIZE\n"); |
| 1065 | 1069 | rc = -EFAULT; |