Skip to content

Commit 32cf95d

Browse files
committed
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
2 parents 630aac5 + d1306eb commit 32cf95d

File tree

3 files changed

+27
-8
lines changed

3 files changed

+27
-8
lines changed

drivers/hv/ring_buffer.c

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,15 +103,29 @@ static bool hv_need_to_signal(u32 old_write, struct hv_ring_buffer_info *rbi)
103103
* there is room for the producer to send the pending packet.
104104
*/
105105

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)
108107
{
109108
u32 cur_write_sz;
110109
u32 r_size;
111-
u32 write_loc = rbi->ring_buffer->write_index;
110+
u32 write_loc;
112111
u32 read_loc = rbi->ring_buffer->read_index;
113-
u32 pending_sz = rbi->ring_buffer->pending_send_sz;
112+
u32 pending_sz;
114113

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;
115129
/* If the other end is not blocked on write don't bother. */
116130
if (pending_sz == 0)
117131
return false;
@@ -120,7 +134,7 @@ static bool hv_need_to_signal_on_read(u32 prev_write_sz,
120134
cur_write_sz = write_loc >= read_loc ? r_size - (write_loc - read_loc) :
121135
read_loc - write_loc;
122136

123-
if ((prev_write_sz < pending_sz) && (cur_write_sz >= pending_sz))
137+
if (cur_write_sz >= pending_sz)
124138
return true;
125139

126140
return false;
@@ -455,7 +469,7 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info,
455469
/* Update the read index */
456470
hv_set_next_read_location(inring_info, next_read_location);
457471

458-
*signal = hv_need_to_signal_on_read(bytes_avail_towrite, inring_info);
472+
*signal = hv_need_to_signal_on_read(inring_info);
459473

460474
return ret;
461475
}

drivers/misc/mic/vop/vop_vringh.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,11 @@ static long vop_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
945945
ret = -EFAULT;
946946
goto free_ret;
947947
}
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+
}
948953
mutex_lock(&vdev->vdev_mutex);
949954
mutex_lock(&vi->vop_mutex);
950955
ret = vop_virtio_add_device(vdev, dd_config);

drivers/nvmem/mxs-ocotp.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ static int mxs_ocotp_read(void *context, const void *reg, size_t reg_size,
9494
if (ret)
9595
goto close_banks;
9696

97-
while (val_size) {
97+
while (val_size >= reg_size) {
9898
if ((offset < OCOTP_DATA_OFFSET) || (offset % 16)) {
9999
/* fill up non-data register */
100100
*buf = 0;
@@ -103,7 +103,7 @@ static int mxs_ocotp_read(void *context, const void *reg, size_t reg_size,
103103
}
104104

105105
buf++;
106-
val_size--;
106+
val_size -= reg_size;
107107
offset += reg_size;
108108
}
109109

0 commit comments

Comments
 (0)