Merge tag 'char-misc-4.6-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc

Pull misc driver fixes from Gfreg KH:
"Here are three small fixes for some driver problems that were
reported. Full details in the shortlog below.

All of these have been in linux-next with no reported issues"

* tag 'char-misc-4.6-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc:
nvmem: mxs-ocotp: fix buffer overflow in read
Drivers: hv: vmbus: Fix signaling logic in hv_need_to_signal_on_read()
misc: mic: Fix for double fetch security bug in VOP driver

+27 -8
+20 -6
drivers/hv/ring_buffer.c
··· 103 103 * there is room for the producer to send the pending packet. 104 104 */ 105 105 106 - static bool hv_need_to_signal_on_read(u32 prev_write_sz, 107 - struct hv_ring_buffer_info *rbi) 106 + static bool hv_need_to_signal_on_read(struct hv_ring_buffer_info *rbi) 108 107 { 109 108 u32 cur_write_sz; 110 109 u32 r_size; 111 - u32 write_loc = rbi->ring_buffer->write_index; 110 + u32 write_loc; 112 111 u32 read_loc = rbi->ring_buffer->read_index; 113 - u32 pending_sz = rbi->ring_buffer->pending_send_sz; 112 + u32 pending_sz; 114 113 114 + /* 115 + * Issue a full memory barrier before making the signaling decision. 116 + * Here is the reason for having this barrier: 117 + * If the reading of the pend_sz (in this function) 118 + * were to be reordered and read before we commit the new read 119 + * index (in the calling function) we could 120 + * have a problem. If the host were to set the pending_sz after we 121 + * have sampled pending_sz and go to sleep before we commit the 122 + * read index, we could miss sending the interrupt. Issue a full 123 + * memory barrier to address this. 124 + */ 125 + mb(); 126 + 127 + pending_sz = rbi->ring_buffer->pending_send_sz; 128 + write_loc = rbi->ring_buffer->write_index; 115 129 /* If the other end is not blocked on write don't bother. */ 116 130 if (pending_sz == 0) 117 131 return false; ··· 134 120 cur_write_sz = write_loc >= read_loc ? r_size - (write_loc - read_loc) : 135 121 read_loc - write_loc; 136 122 137 - if ((prev_write_sz < pending_sz) && (cur_write_sz >= pending_sz)) 123 + if (cur_write_sz >= pending_sz) 138 124 return true; 139 125 140 126 return false; ··· 469 455 /* Update the read index */ 470 456 hv_set_next_read_location(inring_info, next_read_location); 471 457 472 - *signal = hv_need_to_signal_on_read(bytes_avail_towrite, inring_info); 458 + *signal = hv_need_to_signal_on_read(inring_info); 473 459 474 460 return ret; 475 461 }
+5
drivers/misc/mic/vop/vop_vringh.c
··· 945 945 ret = -EFAULT; 946 946 goto free_ret; 947 947 } 948 + /* Ensure desc has not changed between the two reads */ 949 + if (memcmp(&dd, dd_config, sizeof(dd))) { 950 + ret = -EINVAL; 951 + goto free_ret; 952 + } 948 953 mutex_lock(&vdev->vdev_mutex); 949 954 mutex_lock(&vi->vop_mutex); 950 955 ret = vop_virtio_add_device(vdev, dd_config);
+2 -2
drivers/nvmem/mxs-ocotp.c
··· 94 94 if (ret) 95 95 goto close_banks; 96 96 97 - while (val_size) { 97 + while (val_size >= reg_size) { 98 98 if ((offset < OCOTP_DATA_OFFSET) || (offset % 16)) { 99 99 /* fill up non-data register */ 100 100 *buf = 0; ··· 103 103 } 104 104 105 105 buf++; 106 - val_size--; 106 + val_size -= reg_size; 107 107 offset += reg_size; 108 108 } 109 109